blob: 8bc6b968cd9054476325a31cc750b714174da37a [file] [log] [blame]
Jason Samsb8c5a842009-07-31 20:40:47 -07001/*
Stephen Hines9069ee82012-02-13 18:25:54 -08002 * Copyright (C) 2008-2012 The Android Open Source Project
Jason Samsb8c5a842009-07-31 20:40:47 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.renderscript;
18
Jason Samsb8c5a842009-07-31 20:40:47 -070019import java.io.IOException;
20import java.io.InputStream;
Jason Samsb8c5a842009-07-31 20:40:47 -070021import android.content.res.Resources;
Romain Guy650a3eb2009-08-31 14:06:43 -070022import android.content.res.AssetManager;
Jason Samsb8c5a842009-07-31 20:40:47 -070023import android.graphics.Bitmap;
24import android.graphics.BitmapFactory;
Jason Samsfb9aa9f2012-03-28 15:30:07 -070025import android.view.Surface;
Jason Sams615e7ce2012-01-13 14:01:20 -080026import android.graphics.SurfaceTexture;
Jason Samsb8c5a842009-07-31 20:40:47 -070027import android.util.Log;
Romain Guy650a3eb2009-08-31 14:06:43 -070028import android.util.TypedValue;
Tim Murrayabd5db92013-02-28 11:45:22 -080029import android.graphics.Canvas;
Jason Samsb8c5a842009-07-31 20:40:47 -070030
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070031/**
Robert Ly11518ac2011-02-09 13:57:06 -080032 * <p>
33 * Memory allocation class for renderscript. An allocation combines a
34 * {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
35 * This implies that all memory in Renderscript is typed.
36 * </p>
Jason Samsa23d4e72011-01-04 18:59:12 -080037 *
Robert Ly11518ac2011-02-09 13:57:06 -080038 * <p>Allocations are the primary way data moves into and out of scripts. Memory is user
39 * synchronized and it's possible for allocations to exist in multiple memory spaces
40 * concurrently. Currently those spaces are:</p>
41 * <ul>
42 * <li>Script: accessable by RS scripts.</li>
43 * <li>Graphics Texture: accessable as a graphics texture.</li>
44 * <li>Graphics Vertex: accessable as graphical vertex data.</li>
45 * <li>Graphics Constants: Accessable as constants in user shaders</li>
46 * </ul>
47 * </p>
48 * <p>
49 * For example, when creating a allocation for a texture, the user can
50 * specify its memory spaces as both script and textures. This means that it can both
51 * be used as script binding and as a GPU texture for rendering. To maintain
52 * synchronization if a script modifies an allocation used by other targets it must
53 * call a synchronizing function to push the updates to the memory, otherwise the results
54 * are undefined.
55 * </p>
56 * <p>By default, Android system side updates are always applied to the script accessable
57 * memory. If this is not present, they are then applied to the various HW
58 * memory types. A {@link android.renderscript.Allocation#syncAll syncAll()}
59 * call is necessary after the script data is updated to
60 * keep the other memory spaces in sync.</p>
Jason Samsa23d4e72011-01-04 18:59:12 -080061 *
Robert Ly11518ac2011-02-09 13:57:06 -080062 * <p>Allocation data is uploaded in one of two primary ways. For simple
63 * arrays there are copyFrom() functions that take an array from the control code and
64 * copy it to the slave memory store. Both type checked and unchecked copies are provided.
65 * The unchecked variants exist to allow apps to copy over arrays of structures from a
66 * control language that does not support structures.</p>
Jason Samsb8c5a842009-07-31 20:40:47 -070067 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080068 * <div class="special reference">
69 * <h3>Developer Guides</h3>
70 * <p>For more information about creating an application that uses Renderscript, read the
Scott Mainb47fa162013-02-05 14:23:13 -080071 * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080072 * </div>
Jason Samsb8c5a842009-07-31 20:40:47 -070073 **/
74public class Allocation extends BaseObj {
Jason Sams43ee06852009-08-12 17:54:11 -070075 Type mType;
Jason Sams8a647432010-03-01 15:31:04 -080076 Bitmap mBitmap;
Jason Sams5476b452010-12-08 16:14:36 -080077 int mUsage;
Jason Samsba862d12011-07-07 15:24:42 -070078 Allocation mAdaptedAllocation;
79
80 boolean mConstrainedLOD;
81 boolean mConstrainedFace;
82 boolean mConstrainedY;
83 boolean mConstrainedZ;
Jason Sams615e7ce2012-01-13 14:01:20 -080084 boolean mReadAllowed = true;
85 boolean mWriteAllowed = true;
Jason Samsba862d12011-07-07 15:24:42 -070086 int mSelectedY;
87 int mSelectedZ;
88 int mSelectedLOD;
89 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
90
91 int mCurrentDimX;
92 int mCurrentDimY;
93 int mCurrentDimZ;
94 int mCurrentCount;
95
Jason Sams5476b452010-12-08 16:14:36 -080096
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -070097 /**
Jason Samsf7086092011-01-12 13:28:37 -080098 * The usage of the allocation. These signal to renderscript
99 * where to place the allocation in memory.
100 *
101 * SCRIPT The allocation will be bound to and accessed by
102 * scripts.
103 */
Jason Sams5476b452010-12-08 16:14:36 -0800104 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -0800105
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700106 /**
Jason Sams163766c2012-02-15 12:04:24 -0800107 * GRAPHICS_TEXTURE The allocation will be used as a texture
Stephen Hines836c4a52011-06-01 14:38:10 -0700108 * source by one or more graphics programs.
Jason Samsf7086092011-01-12 13:28:37 -0800109 *
110 */
Jason Sams5476b452010-12-08 16:14:36 -0800111 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -0800112
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700113 /**
Jason Samsf7086092011-01-12 13:28:37 -0800114 * GRAPHICS_VERTEX The allocation will be used as a graphics
115 * mesh.
116 *
117 */
Jason Sams5476b452010-12-08 16:14:36 -0800118 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -0800119
120
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700121 /**
Jason Samsf7086092011-01-12 13:28:37 -0800122 * GRAPHICS_CONSTANTS The allocation will be used as the source
123 * of shader constants by one or more programs.
124 *
125 */
Jason Sams5476b452010-12-08 16:14:36 -0800126 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
127
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700128 /**
Jason Sams163766c2012-02-15 12:04:24 -0800129 * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700130 * target for offscreen rendering
131 *
132 */
133 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
134
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700135 /**
Jason Sams163766c2012-02-15 12:04:24 -0800136 * USAGE_IO_INPUT The allocation will be used as SurfaceTexture
137 * consumer. This usage will cause the allocation to be created
138 * read only.
Jason Sams615e7ce2012-01-13 14:01:20 -0800139 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800140 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700141 public static final int USAGE_IO_INPUT = 0x0020;
Stephen Hines9069ee82012-02-13 18:25:54 -0800142
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700143 /**
Jason Sams163766c2012-02-15 12:04:24 -0800144 * USAGE_IO_OUTPUT The allocation will be used as a
145 * SurfaceTexture producer. The dimensions and format of the
146 * SurfaceTexture will be forced to those of the allocation.
Jason Sams615e7ce2012-01-13 14:01:20 -0800147 *
Jason Sams615e7ce2012-01-13 14:01:20 -0800148 */
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700149 public static final int USAGE_IO_OUTPUT = 0x0040;
Jason Sams43ee06852009-08-12 17:54:11 -0700150
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700151 /**
Tim Murray00bb4542012-12-17 16:35:06 -0800152 * USAGE_SHARED The allocation's backing store will be inherited
153 * from another object (usually a Bitmap); calling appropriate
154 * copy methods will be significantly faster than if the entire
155 * allocation were copied every time.
156 *
157 * This is set by default for allocations created with
158 * CreateFromBitmap(RenderScript, Bitmap) in API version 18 and
159 * higher.
160 *
161 */
162 public static final int USAGE_SHARED = 0x0080;
163
164 /**
Jason Samsf7086092011-01-12 13:28:37 -0800165 * Controls mipmap behavior when using the bitmap creation and
166 * update functions.
167 */
Jason Sams4ef66502010-12-10 16:03:15 -0800168 public enum MipmapControl {
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700169 /**
Jason Samsf7086092011-01-12 13:28:37 -0800170 * No mipmaps will be generated and the type generated from the
171 * incoming bitmap will not contain additional LODs.
172 */
Jason Sams5476b452010-12-08 16:14:36 -0800173 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800174
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700175 /**
Jason Samsf7086092011-01-12 13:28:37 -0800176 * A Full mipmap chain will be created in script memory. The
177 * type of the allocation will contain a full mipmap chain. On
178 * upload to graphics the full chain will be transfered.
179 */
Jason Sams5476b452010-12-08 16:14:36 -0800180 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800181
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700182 /**
Jason Samsf7086092011-01-12 13:28:37 -0800183 * The type of the allocation will be the same as MIPMAP_NONE.
184 * It will not contain mipmaps. On upload to graphics the
185 * graphics copy of the allocation data will contain a full
186 * mipmap chain generated from the top level in script memory.
187 */
Jason Sams5476b452010-12-08 16:14:36 -0800188 MIPMAP_ON_SYNC_TO_TEXTURE(2);
189
190 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800191 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800192 mID = id;
193 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700194 }
195
Jason Sams48fe5342011-07-08 13:52:30 -0700196
197 private int getIDSafe() {
198 if (mAdaptedAllocation != null) {
Jason Samse07694b2012-04-03 15:36:36 -0700199 return mAdaptedAllocation.getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700200 }
Jason Samse07694b2012-04-03 15:36:36 -0700201 return getID(mRS);
Jason Sams48fe5342011-07-08 13:52:30 -0700202 }
203
Jason Sams03d2d002012-03-23 13:51:56 -0700204
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700205 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700206 * Get the element of the type of the Allocation.
207 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700208 * @return Element that describes the structure of data in the
209 * allocation
Jason Sams03d2d002012-03-23 13:51:56 -0700210 *
211 */
212 public Element getElement() {
213 return mType.getElement();
214 }
215
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700216 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700217 * Get the usage flags of the Allocation.
218 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700219 * @return usage flags associated with the allocation. e.g.
220 * script, texture, etc.
Jason Sams03d2d002012-03-23 13:51:56 -0700221 *
222 */
223 public int getUsage() {
224 return mUsage;
225 }
226
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700227 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700228 * Get the size of the Allocation in bytes.
229 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700230 * @return size of the Allocation in bytes.
Jason Sams36c0f642012-03-23 15:48:37 -0700231 *
232 */
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700233 public int getBytesSize() {
234 return mType.getCount() * mType.getElement().getBytesSize();
Jason Sams36c0f642012-03-23 15:48:37 -0700235 }
236
Jason Sams452a7662011-07-07 16:05:18 -0700237 private void updateCacheInfo(Type t) {
238 mCurrentDimX = t.getX();
239 mCurrentDimY = t.getY();
240 mCurrentDimZ = t.getZ();
241 mCurrentCount = mCurrentDimX;
242 if (mCurrentDimY > 1) {
243 mCurrentCount *= mCurrentDimY;
244 }
245 if (mCurrentDimZ > 1) {
246 mCurrentCount *= mCurrentDimZ;
247 }
248 }
Jason Samsba862d12011-07-07 15:24:42 -0700249
Tim Murraya3145512012-12-04 17:59:29 -0800250 private void setBitmap(Bitmap b) {
251 mBitmap = b;
252 }
253
Jason Sams5476b452010-12-08 16:14:36 -0800254 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700255 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800256 if ((usage & ~(USAGE_SCRIPT |
257 USAGE_GRAPHICS_TEXTURE |
258 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700259 USAGE_GRAPHICS_CONSTANTS |
Jason Sams615e7ce2012-01-13 14:01:20 -0800260 USAGE_GRAPHICS_RENDER_TARGET |
Jason Sams615e7ce2012-01-13 14:01:20 -0800261 USAGE_IO_INPUT |
Tim Murray00bb4542012-12-17 16:35:06 -0800262 USAGE_IO_OUTPUT |
263 USAGE_SHARED)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800264 throw new RSIllegalArgumentException("Unknown usage specified.");
265 }
Jason Sams615e7ce2012-01-13 14:01:20 -0800266
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700267 if ((usage & USAGE_IO_INPUT) != 0) {
Jason Sams615e7ce2012-01-13 14:01:20 -0800268 mWriteAllowed = false;
269
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700270 if ((usage & ~(USAGE_IO_INPUT |
Jason Sams615e7ce2012-01-13 14:01:20 -0800271 USAGE_GRAPHICS_TEXTURE |
272 USAGE_SCRIPT)) != 0) {
273 throw new RSIllegalArgumentException("Invalid usage combination.");
274 }
275 }
276
Tim Murrayf8c033d2013-04-09 14:33:32 -0700277 // don't need to account for USAGE_SHARED Allocations
278 if ((usage & USAGE_SHARED) == 0) {
279 int numBytes = t.getCount() * t.getElement().getBytesSize();
280 rs.addAllocSizeForGC(numBytes);
281 mGCSize = numBytes;
282 }
283
Jason Sams5476b452010-12-08 16:14:36 -0800284 mType = t;
Jason Sams615e7ce2012-01-13 14:01:20 -0800285 mUsage = usage;
Jason Samsba862d12011-07-07 15:24:42 -0700286
Jason Sams452a7662011-07-07 16:05:18 -0700287 if (t != null) {
288 updateCacheInfo(t);
Jason Samsba862d12011-07-07 15:24:42 -0700289 }
Tim Murrayf8c033d2013-04-09 14:33:32 -0700290
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700291 }
292
Jason Samsb97b2512011-01-16 15:04:08 -0800293 private void validateIsInt32() {
294 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
295 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
296 return;
297 }
298 throw new RSIllegalArgumentException(
299 "32 bit integer source does not match allocation type " + mType.mElement.mType);
300 }
301
302 private void validateIsInt16() {
303 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
304 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
305 return;
306 }
307 throw new RSIllegalArgumentException(
308 "16 bit integer source does not match allocation type " + mType.mElement.mType);
309 }
310
311 private void validateIsInt8() {
312 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
313 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
314 return;
315 }
316 throw new RSIllegalArgumentException(
317 "8 bit integer source does not match allocation type " + mType.mElement.mType);
318 }
319
320 private void validateIsFloat32() {
321 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
322 return;
323 }
324 throw new RSIllegalArgumentException(
325 "32 bit float source does not match allocation type " + mType.mElement.mType);
326 }
327
328 private void validateIsObject() {
329 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
330 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
331 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
332 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
333 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
334 (mType.mElement.mType == Element.DataType.RS_MESH) ||
335 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
336 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
337 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
338 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
339 return;
340 }
341 throw new RSIllegalArgumentException(
342 "Object source does not match allocation type " + mType.mElement.mType);
343 }
344
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700345 @Override
346 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800347 super.updateFromNative();
Jason Samse07694b2012-04-03 15:36:36 -0700348 int typeID = mRS.nAllocationGetType(getID(mRS));
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700349 if(typeID != 0) {
350 mType = new Type(typeID, mRS);
351 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700352 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700353 }
354 }
355
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700356 /**
Jason Sams03d2d002012-03-23 13:51:56 -0700357 * Get the type of the Allocation.
358 *
359 * @return Type
360 *
361 */
Jason Samsea87e962010-01-12 12:12:28 -0800362 public Type getType() {
363 return mType;
364 }
365
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700366 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700367 * Propagate changes from one usage of the allocation to the
Jason Sams03d2d002012-03-23 13:51:56 -0700368 * remaining usages of the allocation.
369 *
370 */
Jason Sams5476b452010-12-08 16:14:36 -0800371 public void syncAll(int srcLocation) {
372 switch (srcLocation) {
373 case USAGE_SCRIPT:
374 case USAGE_GRAPHICS_CONSTANTS:
375 case USAGE_GRAPHICS_TEXTURE:
376 case USAGE_GRAPHICS_VERTEX:
377 break;
378 default:
379 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
380 }
381 mRS.validate();
Jason Sams48fe5342011-07-08 13:52:30 -0700382 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
Jason Sams5476b452010-12-08 16:14:36 -0800383 }
384
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700385 /**
Jason Sams163766c2012-02-15 12:04:24 -0800386 * Send a buffer to the output stream. The contents of the
387 * Allocation will be undefined after this operation.
388 *
Jason Sams163766c2012-02-15 12:04:24 -0800389 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700390 public void ioSend() {
Jason Sams163766c2012-02-15 12:04:24 -0800391 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
392 throw new RSIllegalArgumentException(
393 "Can only send buffer if IO_OUTPUT usage specified.");
394 }
395 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700396 mRS.nAllocationIoSend(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -0800397 }
398
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700399 /**
Jason Samsc5f519c2012-03-29 17:58:15 -0700400 * Delete once code is updated.
401 * @hide
402 */
403 public void ioSendOutput() {
404 ioSend();
405 }
406
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700407 /**
Jason Sams163766c2012-02-15 12:04:24 -0800408 * Receive the latest input into the Allocation.
409 *
Jason Sams163766c2012-02-15 12:04:24 -0800410 */
Jason Samsc5f519c2012-03-29 17:58:15 -0700411 public void ioReceive() {
Jason Sams163766c2012-02-15 12:04:24 -0800412 if ((mUsage & USAGE_IO_INPUT) == 0) {
413 throw new RSIllegalArgumentException(
Jason Samsfe1d5ff2012-03-23 11:47:26 -0700414 "Can only receive if IO_INPUT usage specified.");
Jason Sams163766c2012-02-15 12:04:24 -0800415 }
416 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -0700417 mRS.nAllocationIoReceive(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -0800418 }
419
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700420 /**
Jason Sams36c0f642012-03-23 15:48:37 -0700421 * Copy an array of RS objects to the allocation.
Jason Sams03d2d002012-03-23 13:51:56 -0700422 *
423 * @param d Source array.
424 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800425 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800426 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800427 validateIsObject();
Jason Samsba862d12011-07-07 15:24:42 -0700428 if (d.length != mCurrentCount) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800429 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
Jason Samsba862d12011-07-07 15:24:42 -0700430 mCurrentCount + ", array length = " + d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800431 }
432 int i[] = new int[d.length];
433 for (int ct=0; ct < d.length; ct++) {
Jason Samse07694b2012-04-03 15:36:36 -0700434 i[ct] = d[ct].getID(mRS);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800435 }
Jason Samsba862d12011-07-07 15:24:42 -0700436 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700437 }
438
Jason Samsfb9f82c2011-01-12 14:53:25 -0800439 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800440 Bitmap.Config bc = b.getConfig();
Tim Murrayabd5db92013-02-28 11:45:22 -0800441 if (bc == null) {
442 throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
443 }
Jason Sams252c0782011-01-11 17:42:52 -0800444 switch (bc) {
445 case ALPHA_8:
446 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
447 throw new RSIllegalArgumentException("Allocation kind is " +
448 mType.getElement().mKind + ", type " +
449 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700450 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800451 " bytes, passed bitmap was " + bc);
452 }
453 break;
454 case ARGB_8888:
455 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700456 (mType.getElement().getBytesSize() != 4)) {
Jason Sams252c0782011-01-11 17:42:52 -0800457 throw new RSIllegalArgumentException("Allocation kind is " +
458 mType.getElement().mKind + ", type " +
459 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700460 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800461 " bytes, passed bitmap was " + bc);
462 }
463 break;
464 case RGB_565:
465 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700466 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800467 throw new RSIllegalArgumentException("Allocation kind is " +
468 mType.getElement().mKind + ", type " +
469 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700470 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800471 " bytes, passed bitmap was " + bc);
472 }
473 break;
474 case ARGB_4444:
475 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700476 (mType.getElement().getBytesSize() != 2)) {
Jason Sams252c0782011-01-11 17:42:52 -0800477 throw new RSIllegalArgumentException("Allocation kind is " +
478 mType.getElement().mKind + ", type " +
479 mType.getElement().mType +
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700480 " of " + mType.getElement().getBytesSize() +
Jason Sams252c0782011-01-11 17:42:52 -0800481 " bytes, passed bitmap was " + bc);
482 }
483 break;
484
485 }
Jason Sams4ef66502010-12-10 16:03:15 -0800486 }
487
Jason Samsfb9f82c2011-01-12 14:53:25 -0800488 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700489 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800490 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
491 }
492 }
493
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700494 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800495 * Copy an allocation from an array. This variant is not type
496 * checked which allows an application to fill in structured
497 * data from an array.
498 *
499 * @param d the source data array
500 */
501 public void copyFromUnchecked(int[] d) {
502 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800503 if (mCurrentDimY > 0) {
504 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
505 } else {
506 copy1DRangeFromUnchecked(0, mCurrentCount, d);
507 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800508 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700509 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800510 * Copy an allocation from an array. This variant is not type
511 * checked which allows an application to fill in structured
512 * data from an array.
513 *
514 * @param d the source data array
515 */
516 public void copyFromUnchecked(short[] d) {
517 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800518 if (mCurrentDimY > 0) {
519 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
520 } else {
521 copy1DRangeFromUnchecked(0, mCurrentCount, d);
522 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800523 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700524 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800525 * Copy an allocation from an array. This variant is not type
526 * checked which allows an application to fill in structured
527 * data from an array.
528 *
529 * @param d the source data array
530 */
531 public void copyFromUnchecked(byte[] d) {
532 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800533 if (mCurrentDimY > 0) {
534 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
535 } else {
536 copy1DRangeFromUnchecked(0, mCurrentCount, d);
537 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800538 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700539 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800540 * Copy an allocation from an array. This variant is not type
541 * checked which allows an application to fill in structured
542 * data from an array.
543 *
544 * @param d the source data array
545 */
546 public void copyFromUnchecked(float[] d) {
547 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800548 if (mCurrentDimY > 0) {
549 copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
550 } else {
551 copy1DRangeFromUnchecked(0, mCurrentCount, d);
552 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800553 }
554
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700555 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800556 * Copy an allocation from an array. This variant is type
557 * checked and will generate exceptions if the Allocation type
558 * is not a 32 bit integer type.
559 *
560 * @param d the source data array
561 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800562 public void copyFrom(int[] d) {
563 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800564 if (mCurrentDimY > 0) {
565 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
566 } else {
567 copy1DRangeFrom(0, mCurrentCount, d);
568 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800569 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800570
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700571 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800572 * Copy an allocation from an array. This variant is type
573 * checked and will generate exceptions if the Allocation type
574 * is not a 16 bit integer type.
575 *
576 * @param d the source data array
577 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800578 public void copyFrom(short[] d) {
579 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800580 if (mCurrentDimY > 0) {
581 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
582 } else {
583 copy1DRangeFrom(0, mCurrentCount, d);
584 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800585 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800586
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700587 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800588 * Copy an allocation from an array. This variant is type
589 * checked and will generate exceptions if the Allocation type
590 * is not a 8 bit integer type.
591 *
592 * @param d the source data array
593 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800594 public void copyFrom(byte[] d) {
595 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800596 if (mCurrentDimY > 0) {
597 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
598 } else {
599 copy1DRangeFrom(0, mCurrentCount, d);
600 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800601 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800602
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700603 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800604 * Copy an allocation from an array. This variant is type
605 * checked and will generate exceptions if the Allocation type
606 * is not a 32 bit float type.
607 *
608 * @param d the source data array
609 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800610 public void copyFrom(float[] d) {
611 mRS.validate();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800612 if (mCurrentDimY > 0) {
613 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
614 } else {
615 copy1DRangeFrom(0, mCurrentCount, d);
616 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800617 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800618
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700619 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800620 * Copy an allocation from a bitmap. The height, width, and
621 * format of the bitmap must match the existing allocation.
622 *
623 * @param b the source bitmap
624 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800625 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800626 mRS.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -0800627 if (b.getConfig() == null) {
628 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
629 Canvas c = new Canvas(newBitmap);
630 c.drawBitmap(b, 0, 0, null);
631 copyFrom(newBitmap);
632 return;
633 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800634 validateBitmapSize(b);
635 validateBitmapFormat(b);
Jason Samse07694b2012-04-03 15:36:36 -0700636 mRS.nAllocationCopyFromBitmap(getID(mRS), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700637 }
638
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700639 /**
Tim Murrayf671fb02012-10-03 13:50:05 -0700640 * Copy an allocation from an allocation. The types of both allocations
641 * must be identical.
642 *
643 * @param a the source allocation
644 */
645 public void copyFrom(Allocation a) {
646 mRS.validate();
647 if (!mType.equals(a.getType())) {
648 throw new RSIllegalArgumentException("Types of allocations must match.");
649 }
650 copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
651 }
652
653
654 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800655 * This is only intended to be used by auto-generate code reflected from the
656 * renderscript script files.
657 *
658 * @param xoff
659 * @param fp
660 */
Jason Sams21b41032011-01-16 15:05:41 -0800661 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800662 mRS.validate();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700663 int eSize = mType.mElement.getBytesSize();
Jason Samsa70f4162010-03-26 15:33:42 -0700664 final byte[] data = fp.getData();
665
666 int count = data.length / eSize;
667 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800668 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700669 " not divisible by element size " + eSize + ".");
670 }
Jason Samsba862d12011-07-07 15:24:42 -0700671 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700672 }
673
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700674 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800675 * This is only intended to be used by auto-generate code reflected from the
676 * renderscript script files.
677 *
678 * @param xoff
679 * @param component_number
680 * @param fp
681 */
Jason Sams21b41032011-01-16 15:05:41 -0800682 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Samsf70b0fc82012-02-22 15:22:41 -0800683 mRS.validate();
Jason Sams49bdaf02010-08-31 13:50:42 -0700684 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800685 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700686 }
687 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800688 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700689 }
690
691 final byte[] data = fp.getData();
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700692 int eSize = mType.mElement.mElements[component_number].getBytesSize();
Alex Sakhartchoukbf3c3f22012-02-02 09:47:26 -0800693 eSize *= mType.mElement.mArraySizes[component_number];
Jason Sams49bdaf02010-08-31 13:50:42 -0700694
695 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800696 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700697 " does not match component size " + eSize + ".");
698 }
699
Jason Sams48fe5342011-07-08 13:52:30 -0700700 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
Jason Samsba862d12011-07-07 15:24:42 -0700701 component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700702 }
703
Jason Sams768bc022009-09-21 19:41:04 -0700704 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800705 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700706 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800707 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700708 }
709 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800710 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700711 }
Jason Samsba862d12011-07-07 15:24:42 -0700712 if((off + count) > mCurrentCount) {
713 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700714 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700715 }
Jason Samsba862d12011-07-07 15:24:42 -0700716 if(len < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800717 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700718 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700719 }
720
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700721 /**
Jason Samsf7086092011-01-12 13:28:37 -0800722 * Generate a mipmap chain. Requires the type of the allocation
723 * include mipmaps.
724 *
725 * This function will generate a complete set of mipmaps from
726 * the top level lod and place them into the script memoryspace.
727 *
728 * If the allocation is also using other memory spaces a
729 * followup sync will be required.
730 */
731 public void generateMipmaps() {
Jason Samse07694b2012-04-03 15:36:36 -0700732 mRS.nAllocationGenerateMipmaps(getID(mRS));
Jason Samsf7086092011-01-12 13:28:37 -0800733 }
734
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700735 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800736 * Copy part of an allocation from an array. This variant is
737 * not type checked which allows an application to fill in
738 * structured data from an array.
739 *
740 * @param off The offset of the first element to be copied.
741 * @param count The number of elements to be copied.
742 * @param d the source data array
743 */
744 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700745 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700746 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700747 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700748 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700749 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800750 * Copy part of an allocation from an array. This variant is
751 * not type checked which allows an application to fill in
752 * structured data from an array.
753 *
754 * @param off The offset of the first element to be copied.
755 * @param count The number of elements to be copied.
756 * @param d the source data array
757 */
758 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700759 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700760 data1DChecks(off, count, d.length * 2, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700761 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700762 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700763 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800764 * Copy part of an allocation from an array. This variant is
765 * not type checked which allows an application to fill in
766 * structured data from an array.
767 *
768 * @param off The offset of the first element to be copied.
769 * @param count The number of elements to be copied.
770 * @param d the source data array
771 */
772 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700773 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700774 data1DChecks(off, count, d.length, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700775 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700776 }
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700777 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800778 * Copy part of an allocation from an array. This variant is
779 * not type checked which allows an application to fill in
780 * structured data from an array.
781 *
782 * @param off The offset of the first element to be copied.
783 * @param count The number of elements to be copied.
784 * @param d the source data array
785 */
786 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Alex Sakhartchouk918e8402012-04-11 14:04:23 -0700787 int dataSize = mType.mElement.getBytesSize() * count;
Jason Sams768bc022009-09-21 19:41:04 -0700788 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700789 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700790 }
791
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700792 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800793 * Copy part of an allocation from an array. This variant is
794 * type checked and will generate exceptions if the Allocation
795 * type is not a 32 bit integer type.
796 *
797 * @param off The offset of the first element to be copied.
798 * @param count The number of elements to be copied.
799 * @param d the source data array
800 */
Jason Samsb97b2512011-01-16 15:04:08 -0800801 public void copy1DRangeFrom(int off, int count, int[] d) {
802 validateIsInt32();
803 copy1DRangeFromUnchecked(off, count, d);
804 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800805
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700806 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800807 * Copy part of an allocation from an array. This variant is
808 * type checked and will generate exceptions if the Allocation
809 * type is not a 16 bit integer type.
810 *
811 * @param off The offset of the first element to be copied.
812 * @param count The number of elements to be copied.
813 * @param d the source data array
814 */
Jason Samsb97b2512011-01-16 15:04:08 -0800815 public void copy1DRangeFrom(int off, int count, short[] d) {
816 validateIsInt16();
817 copy1DRangeFromUnchecked(off, count, d);
818 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800819
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700820 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800821 * Copy part of an allocation from an array. This variant is
822 * type checked and will generate exceptions if the Allocation
823 * type is not a 8 bit integer type.
824 *
825 * @param off The offset of the first element to be copied.
826 * @param count The number of elements to be copied.
827 * @param d the source data array
828 */
Jason Samsb97b2512011-01-16 15:04:08 -0800829 public void copy1DRangeFrom(int off, int count, byte[] d) {
830 validateIsInt8();
831 copy1DRangeFromUnchecked(off, count, d);
832 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800833
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700834 /**
Jason Sams4fa3eed2011-01-19 15:44:38 -0800835 * Copy part of an allocation from an array. This variant is
836 * type checked and will generate exceptions if the Allocation
837 * type is not a 32 bit float type.
838 *
839 * @param off The offset of the first element to be copied.
840 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700841 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800842 */
Jason Samsb97b2512011-01-16 15:04:08 -0800843 public void copy1DRangeFrom(int off, int count, float[] d) {
844 validateIsFloat32();
845 copy1DRangeFromUnchecked(off, count, d);
846 }
847
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700848 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700849 * Copy part of an allocation from another allocation.
850 *
851 * @param off The offset of the first element to be copied.
852 * @param count The number of elements to be copied.
853 * @param data the source data allocation.
854 * @param dataOff off The offset of the first element in data to
855 * be copied.
856 */
857 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Jason Sams48fe5342011-07-08 13:52:30 -0700858 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700859 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -0700860 count, 1, data.getID(mRS), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700861 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700862 }
863
Jason Samsfb9f82c2011-01-12 14:53:25 -0800864 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -0700865 if (mAdaptedAllocation != null) {
866
867 } else {
868
869 if (xoff < 0 || yoff < 0) {
870 throw new RSIllegalArgumentException("Offset cannot be negative.");
871 }
872 if (h < 0 || w < 0) {
873 throw new RSIllegalArgumentException("Height or width cannot be negative.");
874 }
875 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
876 throw new RSIllegalArgumentException("Updated region larger than allocation.");
877 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800878 }
879 }
Jason Sams768bc022009-09-21 19:41:04 -0700880
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800881 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, byte[] data) {
882 mRS.validate();
883 validate2DRange(xoff, yoff, w, h);
884 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
885 w, h, data, data.length);
886 }
887
888 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, short[] data) {
889 mRS.validate();
890 validate2DRange(xoff, yoff, w, h);
891 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
892 w, h, data, data.length * 2);
893 }
894
895 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, int[] data) {
896 mRS.validate();
897 validate2DRange(xoff, yoff, w, h);
898 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
899 w, h, data, data.length * 4);
900 }
901
902 void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, float[] data) {
903 mRS.validate();
904 validate2DRange(xoff, yoff, w, h);
905 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
906 w, h, data, data.length * 4);
907 }
908
909
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700910 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700911 * Copy a rectangular region from the array into the allocation.
912 * The incoming array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -0800913 *
914 * @param xoff X offset of the region to update
915 * @param yoff Y offset of the region to update
916 * @param w Width of the incoming region to update
917 * @param h Height of the incoming region to update
918 * @param data to be placed into the allocation
919 */
920 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800921 validateIsInt8();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800922 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800923 }
924
Jason Samsf7086092011-01-12 13:28:37 -0800925 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800926 validateIsInt16();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800927 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800928 }
929
Jason Samsf7086092011-01-12 13:28:37 -0800930 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800931 validateIsInt32();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800932 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsb8c5a842009-07-31 20:40:47 -0700933 }
934
Jason Samsf7086092011-01-12 13:28:37 -0800935 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Stephen Hines5f528be2013-02-08 21:03:51 -0800936 validateIsFloat32();
Stephen Hinesa9a7b372013-02-08 17:11:31 -0800937 copy2DRangeFromUnchecked(xoff, yoff, w, h, data);
Jason Samsb8c5a842009-07-31 20:40:47 -0700938 }
939
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700940 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700941 * Copy a rectangular region into the allocation from another
942 * allocation.
943 *
944 * @param xoff X offset of the region to update.
945 * @param yoff Y offset of the region to update.
946 * @param w Width of the incoming region to update.
947 * @param h Height of the incoming region to update.
948 * @param data source allocation.
949 * @param dataXoff X offset in data of the region to update.
950 * @param dataYoff Y offset in data of the region to update.
951 */
952 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
953 Allocation data, int dataXoff, int dataYoff) {
954 mRS.validate();
955 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700956 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
Jason Samsba862d12011-07-07 15:24:42 -0700957 mSelectedLOD, mSelectedFace.mID,
Jason Samse07694b2012-04-03 15:36:36 -0700958 w, h, data.getID(mRS), dataXoff, dataYoff,
Jason Samsba862d12011-07-07 15:24:42 -0700959 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700960 }
961
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700962 /**
Jason Samsf7086092011-01-12 13:28:37 -0800963 * Copy a bitmap into an allocation. The height and width of
964 * the update will use the height and width of the incoming
965 * bitmap.
966 *
967 * @param xoff X offset of the region to update
968 * @param yoff Y offset of the region to update
969 * @param data the bitmap to be copied
970 */
971 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800972 mRS.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -0800973 if (data.getConfig() == null) {
974 Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
975 Canvas c = new Canvas(newBitmap);
976 c.drawBitmap(data, 0, 0, null);
977 copy2DRangeFrom(xoff, yoff, newBitmap);
978 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800979 validateBitmapFormat(data);
980 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Sams48fe5342011-07-08 13:52:30 -0700981 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800982 }
983
984
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700985 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700986 * Copy from the Allocation into a Bitmap. The bitmap must
987 * match the dimensions of the Allocation.
988 *
989 * @param b The bitmap to be set from the Allocation.
990 */
Jason Samsfa445b92011-01-07 17:00:07 -0800991 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800992 mRS.validate();
993 validateBitmapFormat(b);
994 validateBitmapSize(b);
Jason Samse07694b2012-04-03 15:36:36 -0700995 mRS.nAllocationCopyToBitmap(getID(mRS), b);
Jason Samsfa445b92011-01-07 17:00:07 -0800996 }
997
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -0700998 /**
Jason Sams48fe5342011-07-08 13:52:30 -0700999 * Copy from the Allocation into a byte array. The array must
1000 * be at least as large as the Allocation. The allocation must
1001 * be of an 8 bit elemental type.
1002 *
1003 * @param d The array to be set from the Allocation.
1004 */
Jason Samsfa445b92011-01-07 17:00:07 -08001005 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001006 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -08001007 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001008 mRS.nAllocationRead(getID(mRS), d);
Jason Sams40a29e82009-08-10 14:55:26 -07001009 }
1010
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001011 /**
Jason Sams48fe5342011-07-08 13:52:30 -07001012 * Copy from the Allocation into a short array. The array must
1013 * be at least as large as the Allocation. The allocation must
1014 * be of an 16 bit elemental type.
1015 *
1016 * @param d The array to be set from the Allocation.
1017 */
Jason Samsfa445b92011-01-07 17:00:07 -08001018 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001019 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -08001020 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001021 mRS.nAllocationRead(getID(mRS), d);
Jason Samsfa445b92011-01-07 17:00:07 -08001022 }
1023
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001024 /**
Jason Sams48fe5342011-07-08 13:52:30 -07001025 * Copy from the Allocation into a int array. The array must be
1026 * at least as large as the Allocation. The allocation must be
1027 * of an 32 bit elemental type.
1028 *
1029 * @param d The array to be set from the Allocation.
1030 */
Jason Samsfa445b92011-01-07 17:00:07 -08001031 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001032 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -08001033 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001034 mRS.nAllocationRead(getID(mRS), d);
Jason Samsfa445b92011-01-07 17:00:07 -08001035 }
1036
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001037 /**
Jason Sams48fe5342011-07-08 13:52:30 -07001038 * Copy from the Allocation into a float array. The array must
1039 * be at least as large as the Allocation. The allocation must
1040 * be of an 32 bit float elemental type.
1041 *
1042 * @param d The array to be set from the Allocation.
1043 */
Jason Samsfa445b92011-01-07 17:00:07 -08001044 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -08001045 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -08001046 mRS.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001047 mRS.nAllocationRead(getID(mRS), d);
Jason Sams40a29e82009-08-10 14:55:26 -07001048 }
1049
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001050 /**
Jason Samsf7086092011-01-12 13:28:37 -08001051 * Resize a 1D allocation. The contents of the allocation are
1052 * preserved. If new elements are allocated objects are created
1053 * with null contents and the new region is otherwise undefined.
1054 *
1055 * If the new region is smaller the references of any objects
1056 * outside the new region will be released.
1057 *
1058 * A new type will be created with the new dimension.
1059 *
1060 * @param dimX The new size of the allocation.
1061 */
Jason Sams31a7e422010-10-26 13:09:17 -07001062 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001063 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -08001064 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001065 }
Jason Samse07694b2012-04-03 15:36:36 -07001066 mRS.nAllocationResize1D(getID(mRS), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -07001067 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -07001068
Jason Samse07694b2012-04-03 15:36:36 -07001069 int typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams31a7e422010-10-26 13:09:17 -07001070 mType = new Type(typeID, mRS);
1071 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -07001072 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001073 }
1074
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001075 /**
Jason Sams163766c2012-02-15 12:04:24 -08001076 * Resize a 2D allocation. The contents of the allocation are
1077 * preserved. If new elements are allocated objects are created
1078 * with null contents and the new region is otherwise undefined.
1079 *
1080 * If the new region is smaller the references of any objects
1081 * outside the new region will be released.
1082 *
1083 * A new type will be created with the new dimension.
1084 *
Jason Sams163766c2012-02-15 12:04:24 -08001085 * @param dimX The new size of the allocation.
1086 * @param dimY The new size of the allocation.
1087 */
Tim Murraybc254b92012-10-05 15:00:45 -07001088 public synchronized void resize(int dimX, int dimY) {
Jason Sams163766c2012-02-15 12:04:24 -08001089 if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
1090 throw new RSInvalidStateException(
1091 "Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001092 }
1093 if (mType.getY() == 0) {
Jason Sams163766c2012-02-15 12:04:24 -08001094 throw new RSInvalidStateException(
1095 "Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -07001096 }
Jason Samse07694b2012-04-03 15:36:36 -07001097 mRS.nAllocationResize2D(getID(mRS), dimX, dimY);
Jason Sams163766c2012-02-15 12:04:24 -08001098 mRS.finish(); // Necessary because resize is fifoed and update is async.
1099
Jason Samse07694b2012-04-03 15:36:36 -07001100 int typeID = mRS.nAllocationGetType(getID(mRS));
Jason Sams163766c2012-02-15 12:04:24 -08001101 mType = new Type(typeID, mRS);
1102 mType.updateFromNative();
1103 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -07001104 }
Jason Sams40a29e82009-08-10 14:55:26 -07001105
Jason Samsbd1c3ad2009-08-03 16:03:08 -07001106
Jason Samsb8c5a842009-07-31 20:40:47 -07001107
1108 // creation
1109
Jason Sams49a05d72010-12-29 14:31:29 -08001110 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -07001111 static {
1112 mBitmapOptions.inScaled = false;
1113 }
1114
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001115 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001116 *
1117 * @param type renderscript type describing data layout
1118 * @param mips specifies desired mipmap behaviour for the
1119 * allocation
1120 * @param usage bit field specifying how the allocation is
1121 * utilized
1122 */
1123 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001124 rs.validate();
Jason Samse07694b2012-04-03 15:36:36 -07001125 if (type.getID(rs) == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001126 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -07001127 }
Tim Murrayf8c033d2013-04-09 14:33:32 -07001128
Jason Samse07694b2012-04-03 15:36:36 -07001129 int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
Jason Sams857d0c72011-11-23 15:02:15 -08001130 if (id == 0) {
1131 throw new RSRuntimeException("Allocation creation failed.");
1132 }
1133 return new Allocation(id, rs, type, usage);
1134 }
1135
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001136 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001137 * Creates a renderscript allocation with the size specified by
1138 * the type and no mipmaps generated by default
1139 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001140 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001141 * @param type renderscript type describing data layout
1142 * @param usage bit field specifying how the allocation is
1143 * utilized
1144 *
1145 * @return allocation
1146 */
Jason Samse5d37122010-12-16 00:33:33 -08001147 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
1148 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
1149 }
1150
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001151 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001152 * Creates a renderscript allocation for use by the script with
1153 * the size specified by the type and no mipmaps generated by
1154 * default
1155 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001156 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001157 * @param type renderscript type describing data layout
1158 *
1159 * @return allocation
1160 */
Jason Sams5476b452010-12-08 16:14:36 -08001161 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001162 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -08001163 }
Jason Sams1bada8c2009-08-09 17:01:55 -07001164
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001165 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001166 * Creates a renderscript allocation with a specified number of
1167 * given elements
1168 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001169 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001170 * @param e describes what each element of an allocation is
1171 * @param count specifies the number of element in the allocation
1172 * @param usage bit field specifying how the allocation is
1173 * utilized
1174 *
1175 * @return allocation
1176 */
Jason Sams5476b452010-12-08 16:14:36 -08001177 static public Allocation createSized(RenderScript rs, Element e,
1178 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001179 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -07001180 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001181 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -07001182 Type t = b.create();
1183
Jason Samse07694b2012-04-03 15:36:36 -07001184 int id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
Jason Sams5476b452010-12-08 16:14:36 -08001185 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001186 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -07001187 }
Jason Sams5476b452010-12-08 16:14:36 -08001188 return new Allocation(id, rs, t, usage);
1189 }
1190
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001191 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001192 * Creates a renderscript allocation with a specified number of
1193 * given elements
1194 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001195 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001196 * @param e describes what each element of an allocation is
1197 * @param count specifies the number of element in the allocation
1198 *
1199 * @return allocation
1200 */
Jason Sams5476b452010-12-08 16:14:36 -08001201 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -08001202 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -07001203 }
1204
Jason Sams49a05d72010-12-29 14:31:29 -08001205 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -08001206 final Bitmap.Config bc = b.getConfig();
1207 if (bc == Bitmap.Config.ALPHA_8) {
1208 return Element.A_8(rs);
1209 }
1210 if (bc == Bitmap.Config.ARGB_4444) {
1211 return Element.RGBA_4444(rs);
1212 }
1213 if (bc == Bitmap.Config.ARGB_8888) {
1214 return Element.RGBA_8888(rs);
1215 }
1216 if (bc == Bitmap.Config.RGB_565) {
1217 return Element.RGB_565(rs);
1218 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -08001219 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -08001220 }
1221
Jason Sams49a05d72010-12-29 14:31:29 -08001222 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001223 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -08001224 Element e = elementFromBitmap(rs, b);
1225 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001226 tb.setX(b.getWidth());
1227 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08001228 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08001229 return tb.create();
1230 }
1231
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001232 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001233 * Creates a renderscript allocation from a bitmap
1234 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001235 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001236 * @param b bitmap source for the allocation data
1237 * @param mips specifies desired mipmap behaviour for the
1238 * allocation
1239 * @param usage bit field specifying how the allocation is
1240 * utilized
1241 *
1242 * @return renderscript allocation containing bitmap data
1243 *
1244 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001245 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001246 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001247 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001248 rs.validate();
Tim Murrayabd5db92013-02-28 11:45:22 -08001249
1250 // WAR undocumented color formats
1251 if (b.getConfig() == null) {
1252 if ((usage & USAGE_SHARED) != 0) {
1253 throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
1254 }
1255 Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
1256 Canvas c = new Canvas(newBitmap);
1257 c.drawBitmap(b, 0, 0, null);
1258 return createFromBitmap(rs, newBitmap, mips, usage);
1259 }
1260
Jason Sams5476b452010-12-08 16:14:36 -08001261 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08001262
Tim Murraya3145512012-12-04 17:59:29 -08001263 // enable optimized bitmap path only with no mipmap and script-only usage
1264 if (mips == MipmapControl.MIPMAP_NONE &&
1265 t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
Stephen Hinesd34dc852012-12-19 19:33:13 -08001266 usage == (USAGE_SHARED | USAGE_SCRIPT)) {
Tim Murraya3145512012-12-04 17:59:29 -08001267 int id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
1268 if (id == 0) {
1269 throw new RSRuntimeException("Load failed.");
1270 }
1271
1272 // keep a reference to the Bitmap around to prevent GC
1273 Allocation alloc = new Allocation(id, rs, t, usage);
1274 alloc.setBitmap(b);
1275 return alloc;
1276 }
1277
Jason Samse07694b2012-04-03 15:36:36 -07001278 int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Jason Sams5476b452010-12-08 16:14:36 -08001279 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001280 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -08001281 }
Jason Sams5476b452010-12-08 16:14:36 -08001282 return new Allocation(id, rs, t, usage);
1283 }
1284
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001285 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001286 * For allocations used with io operations, returns the handle
1287 * onto a raw buffer that is being managed by the screen
1288 * compositor.
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001289 *
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001290 * @return Surface object associated with allocation
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001291 *
1292 */
1293 public Surface getSurface() {
Jason Sams72226e02013-02-22 12:45:54 -08001294 if ((mUsage & USAGE_IO_INPUT) == 0) {
1295 throw new RSInvalidStateException("Allocation is not a surface texture.");
1296 }
1297 return mRS.nAllocationGetSurface(getID(mRS));
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001298 }
1299
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001300 /**
Jason Samsc089c2f2013-02-22 13:57:36 -08001301 * @hide
1302 */
1303 public void setSurfaceTexture(SurfaceTexture st) {
1304 setSurface(new Surface(st));
1305 }
1306
1307 /**
Alex Sakhartchouk918e8402012-04-11 14:04:23 -07001308 * Associate a surface for io output with this allocation
1309 *
1310 * @param sur Surface to associate with allocation
Jason Sams163766c2012-02-15 12:04:24 -08001311 */
Jason Samsfb9aa9f2012-03-28 15:30:07 -07001312 public void setSurface(Surface sur) {
1313 mRS.validate();
Jason Sams163766c2012-02-15 12:04:24 -08001314 if ((mUsage & USAGE_IO_OUTPUT) == 0) {
1315 throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
1316 }
1317
Jason Samse07694b2012-04-03 15:36:36 -07001318 mRS.nAllocationSetSurface(getID(mRS), sur);
Jason Sams163766c2012-02-15 12:04:24 -08001319 }
1320
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001321 /**
Tim Murray00bb4542012-12-17 16:35:06 -08001322 * Creates a RenderScript allocation from a bitmap.
1323 *
1324 * With target API version 18 or greater, this allocation will be
1325 * created with USAGE_SHARED. With target API version 17 or lower,
1326 * this allocation will be created with USAGE_GRAPHICS_TEXTURE.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001327 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001328 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001329 * @param b bitmap source for the allocation data
1330 *
1331 * @return renderscript allocation containing bitmap data
1332 *
1333 */
Jason Sams6d8eb262010-12-15 01:41:00 -08001334 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
Tim Murray00bb4542012-12-17 16:35:06 -08001335 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
1336 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1337 USAGE_SHARED | USAGE_SCRIPT);
1338 }
Jason Sams6d8eb262010-12-15 01:41:00 -08001339 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1340 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08001341 }
1342
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001343 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001344 * Creates a cubemap allocation from a bitmap containing the
1345 * horizontal list of cube faces. Each individual face must be
1346 * the same size and power of 2
1347 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001348 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001349 * @param b bitmap with cubemap faces layed out in the following
1350 * format: right, left, top, bottom, front, back
1351 * @param mips specifies desired mipmap behaviour for the cubemap
1352 * @param usage bit field specifying how the cubemap is utilized
1353 *
1354 * @return allocation containing cubemap data
1355 *
1356 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001357 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001358 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001359 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001360 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001361
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001362 int height = b.getHeight();
1363 int width = b.getWidth();
1364
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001365 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001366 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
1367 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001368 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001369 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001370 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001371 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001372 if (!isPow2) {
1373 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1374 }
1375
1376 Element e = elementFromBitmap(rs, b);
1377 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001378 tb.setX(height);
1379 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001380 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08001381 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001382 Type t = tb.create();
1383
Jason Samse07694b2012-04-03 15:36:36 -07001384 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001385 if(id == 0) {
1386 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
1387 }
Jason Sams5476b452010-12-08 16:14:36 -08001388 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001389 }
1390
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001391 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001392 * Creates a non-mipmapped cubemap allocation for use as a
1393 * graphics texture from a bitmap containing the horizontal list
1394 * of cube faces. Each individual face must be the same size and
1395 * power of 2
1396 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001397 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001398 * @param b bitmap with cubemap faces layed out in the following
1399 * format: right, left, top, bottom, front, back
1400 *
1401 * @return allocation containing cubemap data
1402 *
1403 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001404 static public Allocation createCubemapFromBitmap(RenderScript rs,
1405 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08001406 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001407 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08001408 }
1409
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001410 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001411 * Creates a cubemap allocation from 6 bitmaps containing
1412 * the cube faces. All the faces must be the same size and
1413 * power of 2
1414 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001415 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001416 * @param xpos cubemap face in the positive x direction
1417 * @param xneg cubemap face in the negative x direction
1418 * @param ypos cubemap face in the positive y direction
1419 * @param yneg cubemap face in the negative y direction
1420 * @param zpos cubemap face in the positive z direction
1421 * @param zneg cubemap face in the negative z direction
1422 * @param mips specifies desired mipmap behaviour for the cubemap
1423 * @param usage bit field specifying how the cubemap is utilized
1424 *
1425 * @return allocation containing cubemap data
1426 *
1427 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001428 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1429 Bitmap xpos,
1430 Bitmap xneg,
1431 Bitmap ypos,
1432 Bitmap yneg,
1433 Bitmap zpos,
1434 Bitmap zneg,
1435 MipmapControl mips,
1436 int usage) {
1437 int height = xpos.getHeight();
1438 if (xpos.getWidth() != height ||
1439 xneg.getWidth() != height || xneg.getHeight() != height ||
1440 ypos.getWidth() != height || ypos.getHeight() != height ||
1441 yneg.getWidth() != height || yneg.getHeight() != height ||
1442 zpos.getWidth() != height || zpos.getHeight() != height ||
1443 zneg.getWidth() != height || zneg.getHeight() != height) {
1444 throw new RSIllegalArgumentException("Only square cube map faces supported");
1445 }
1446 boolean isPow2 = (height & (height - 1)) == 0;
1447 if (!isPow2) {
1448 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1449 }
1450
1451 Element e = elementFromBitmap(rs, xpos);
1452 Type.Builder tb = new Type.Builder(rs, e);
1453 tb.setX(height);
1454 tb.setY(height);
1455 tb.setFaces(true);
1456 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1457 Type t = tb.create();
1458 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1459
1460 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07001461 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001462 adapter.copyFrom(xpos);
1463 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1464 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001465 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001466 adapter.copyFrom(ypos);
1467 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1468 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001469 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001470 adapter.copyFrom(zpos);
1471 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1472 adapter.copyFrom(zneg);
1473
1474 return cubemap;
1475 }
1476
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001477 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001478 * Creates a non-mipmapped cubemap allocation for use as a
1479 * graphics texture from 6 bitmaps containing
1480 * the cube faces. All the faces must be the same size and
1481 * power of 2
1482 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001483 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001484 * @param xpos cubemap face in the positive x direction
1485 * @param xneg cubemap face in the negative x direction
1486 * @param ypos cubemap face in the positive y direction
1487 * @param yneg cubemap face in the negative y direction
1488 * @param zpos cubemap face in the positive z direction
1489 * @param zneg cubemap face in the negative z direction
1490 *
1491 * @return allocation containing cubemap data
1492 *
1493 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001494 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1495 Bitmap xpos,
1496 Bitmap xneg,
1497 Bitmap ypos,
1498 Bitmap yneg,
1499 Bitmap zpos,
1500 Bitmap zneg) {
1501 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1502 zpos, zneg, MipmapControl.MIPMAP_NONE,
1503 USAGE_GRAPHICS_TEXTURE);
1504 }
1505
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001506 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001507 * Creates a renderscript allocation from the bitmap referenced
1508 * by resource id
1509 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001510 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001511 * @param res application resources
1512 * @param id resource id to load the data from
1513 * @param mips specifies desired mipmap behaviour for the
1514 * allocation
1515 * @param usage bit field specifying how the allocation is
1516 * utilized
1517 *
1518 * @return renderscript allocation containing resource data
1519 *
1520 */
Jason Sams5476b452010-12-08 16:14:36 -08001521 static public Allocation createFromBitmapResource(RenderScript rs,
1522 Resources res,
1523 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001524 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001525 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001526
Jason Sams771bebb2009-12-07 12:40:12 -08001527 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001528 Bitmap b = BitmapFactory.decodeResource(res, id);
1529 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1530 b.recycle();
1531 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001532 }
1533
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001534 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001535 * Creates a non-mipmapped renderscript allocation to use as a
1536 * graphics texture from the bitmap referenced by resource id
1537 *
Jason Sams455d6442013-02-05 19:20:18 -08001538 * With target API version 18 or greater, this allocation will be
1539 * created with USAGE_SHARED. With target API version 17 or lower,
1540 * this allocation will be created with USAGE_GRAPHICS_TEXTURE.
1541 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001542 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001543 * @param res application resources
1544 * @param id resource id to load the data from
1545 *
1546 * @return renderscript allocation containing resource data
1547 *
1548 */
Jason Sams5476b452010-12-08 16:14:36 -08001549 static public Allocation createFromBitmapResource(RenderScript rs,
1550 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001551 int id) {
Jason Sams455d6442013-02-05 19:20:18 -08001552 if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
1553 return createFromBitmapResource(rs, res, id,
1554 MipmapControl.MIPMAP_NONE,
1555 USAGE_SHARED | USAGE_SCRIPT);
1556 }
Jason Sams6d8eb262010-12-15 01:41:00 -08001557 return createFromBitmapResource(rs, res, id,
1558 MipmapControl.MIPMAP_NONE,
1559 USAGE_GRAPHICS_TEXTURE);
1560 }
1561
Stephen Hines9c9ad3f8c22012-05-07 15:34:29 -07001562 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001563 * Creates a renderscript allocation containing string data
1564 * encoded in UTF-8 format
1565 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001566 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001567 * @param str string to create the allocation from
1568 * @param usage bit field specifying how the allocaiton is
1569 * utilized
1570 *
1571 */
Jason Sams5476b452010-12-08 16:14:36 -08001572 static public Allocation createFromString(RenderScript rs,
1573 String str,
1574 int usage) {
1575 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001576 byte[] allocArray = null;
1577 try {
1578 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001579 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001580 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001581 return alloc;
1582 }
1583 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001584 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001585 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001586 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001587}
1588
1589