blob: 59a9e5d0ba134e425cd85e70e6f1451d13959e84 [file] [log] [blame]
Jason Samsb8c5a842009-07-31 20:40:47 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
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 Samsb8c5a842009-07-31 20:40:47 -070025import android.util.Log;
Romain Guy650a3eb2009-08-31 14:06:43 -070026import android.util.TypedValue;
Jason Samsb8c5a842009-07-31 20:40:47 -070027
28/**
Robert Ly11518ac2011-02-09 13:57:06 -080029 * <p>
30 * Memory allocation class for renderscript. An allocation combines a
31 * {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
32 * This implies that all memory in Renderscript is typed.
33 * </p>
Jason Samsa23d4e72011-01-04 18:59:12 -080034 *
Robert Ly11518ac2011-02-09 13:57:06 -080035 * <p>Allocations are the primary way data moves into and out of scripts. Memory is user
36 * synchronized and it's possible for allocations to exist in multiple memory spaces
37 * concurrently. Currently those spaces are:</p>
38 * <ul>
39 * <li>Script: accessable by RS scripts.</li>
40 * <li>Graphics Texture: accessable as a graphics texture.</li>
41 * <li>Graphics Vertex: accessable as graphical vertex data.</li>
42 * <li>Graphics Constants: Accessable as constants in user shaders</li>
43 * </ul>
44 * </p>
45 * <p>
46 * For example, when creating a allocation for a texture, the user can
47 * specify its memory spaces as both script and textures. This means that it can both
48 * be used as script binding and as a GPU texture for rendering. To maintain
49 * synchronization if a script modifies an allocation used by other targets it must
50 * call a synchronizing function to push the updates to the memory, otherwise the results
51 * are undefined.
52 * </p>
53 * <p>By default, Android system side updates are always applied to the script accessable
54 * memory. If this is not present, they are then applied to the various HW
55 * memory types. A {@link android.renderscript.Allocation#syncAll syncAll()}
56 * call is necessary after the script data is updated to
57 * keep the other memory spaces in sync.</p>
Jason Samsa23d4e72011-01-04 18:59:12 -080058 *
Robert Ly11518ac2011-02-09 13:57:06 -080059 * <p>Allocation data is uploaded in one of two primary ways. For simple
60 * arrays there are copyFrom() functions that take an array from the control code and
61 * copy it to the slave memory store. Both type checked and unchecked copies are provided.
62 * The unchecked variants exist to allow apps to copy over arrays of structures from a
63 * control language that does not support structures.</p>
Jason Samsb8c5a842009-07-31 20:40:47 -070064 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080065 * <div class="special reference">
66 * <h3>Developer Guides</h3>
67 * <p>For more information about creating an application that uses Renderscript, read the
68 * <a href="{@docRoot}guide/topics/graphics/renderscript.html">Renderscript</a> developer guide.</p>
69 * </div>
Jason Samsb8c5a842009-07-31 20:40:47 -070070 **/
71public class Allocation extends BaseObj {
Jason Sams43ee06852009-08-12 17:54:11 -070072 Type mType;
Jason Sams8a647432010-03-01 15:31:04 -080073 Bitmap mBitmap;
Jason Sams5476b452010-12-08 16:14:36 -080074 int mUsage;
Jason Samsba862d12011-07-07 15:24:42 -070075 Allocation mAdaptedAllocation;
76
77 boolean mConstrainedLOD;
78 boolean mConstrainedFace;
79 boolean mConstrainedY;
80 boolean mConstrainedZ;
81 int mSelectedY;
82 int mSelectedZ;
83 int mSelectedLOD;
84 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
85
86 int mCurrentDimX;
87 int mCurrentDimY;
88 int mCurrentDimZ;
89 int mCurrentCount;
90
Jason Sams5476b452010-12-08 16:14:36 -080091
Jason Samsf7086092011-01-12 13:28:37 -080092 /**
93 * The usage of the allocation. These signal to renderscript
94 * where to place the allocation in memory.
95 *
96 * SCRIPT The allocation will be bound to and accessed by
97 * scripts.
98 */
Jason Sams5476b452010-12-08 16:14:36 -080099 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -0800100
101 /**
102 * GRAPHICS_TEXTURE The allcation will be used as a texture
Stephen Hines836c4a52011-06-01 14:38:10 -0700103 * source by one or more graphics programs.
Jason Samsf7086092011-01-12 13:28:37 -0800104 *
105 */
Jason Sams5476b452010-12-08 16:14:36 -0800106 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -0800107
108 /**
109 * GRAPHICS_VERTEX The allocation will be used as a graphics
110 * mesh.
111 *
112 */
Jason Sams5476b452010-12-08 16:14:36 -0800113 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -0800114
115
116 /**
117 * GRAPHICS_CONSTANTS The allocation will be used as the source
118 * of shader constants by one or more programs.
119 *
120 */
Jason Sams5476b452010-12-08 16:14:36 -0800121 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
122
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700123 /**
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700124 * USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
125 * target for offscreen rendering
126 *
127 */
128 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
129
Jason Sams43ee06852009-08-12 17:54:11 -0700130
Jason Samsf7086092011-01-12 13:28:37 -0800131 /**
132 * Controls mipmap behavior when using the bitmap creation and
133 * update functions.
134 */
Jason Sams4ef66502010-12-10 16:03:15 -0800135 public enum MipmapControl {
Jason Samsf7086092011-01-12 13:28:37 -0800136 /**
137 * No mipmaps will be generated and the type generated from the
138 * incoming bitmap will not contain additional LODs.
139 */
Jason Sams5476b452010-12-08 16:14:36 -0800140 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800141
142 /**
143 * A Full mipmap chain will be created in script memory. The
144 * type of the allocation will contain a full mipmap chain. On
145 * upload to graphics the full chain will be transfered.
146 */
Jason Sams5476b452010-12-08 16:14:36 -0800147 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800148
149 /**
150 * The type of the allocation will be the same as MIPMAP_NONE.
151 * It will not contain mipmaps. On upload to graphics the
152 * graphics copy of the allocation data will contain a full
153 * mipmap chain generated from the top level in script memory.
154 */
Jason Sams5476b452010-12-08 16:14:36 -0800155 MIPMAP_ON_SYNC_TO_TEXTURE(2);
156
157 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800158 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800159 mID = id;
160 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700161 }
162
Jason Sams48fe5342011-07-08 13:52:30 -0700163
164 private int getIDSafe() {
165 if (mAdaptedAllocation != null) {
166 return mAdaptedAllocation.getID();
167 }
168 return getID();
169 }
170
Jason Sams452a7662011-07-07 16:05:18 -0700171 private void updateCacheInfo(Type t) {
172 mCurrentDimX = t.getX();
173 mCurrentDimY = t.getY();
174 mCurrentDimZ = t.getZ();
175 mCurrentCount = mCurrentDimX;
176 if (mCurrentDimY > 1) {
177 mCurrentCount *= mCurrentDimY;
178 }
179 if (mCurrentDimZ > 1) {
180 mCurrentCount *= mCurrentDimZ;
181 }
182 }
Jason Samsba862d12011-07-07 15:24:42 -0700183
Jason Sams5476b452010-12-08 16:14:36 -0800184 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700185 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800186 if ((usage & ~(USAGE_SCRIPT |
187 USAGE_GRAPHICS_TEXTURE |
188 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700189 USAGE_GRAPHICS_CONSTANTS |
190 USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800191 throw new RSIllegalArgumentException("Unknown usage specified.");
192 }
193 mType = t;
Jason Samsba862d12011-07-07 15:24:42 -0700194
Jason Sams452a7662011-07-07 16:05:18 -0700195 if (t != null) {
196 updateCacheInfo(t);
Jason Samsba862d12011-07-07 15:24:42 -0700197 }
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700198 }
199
Jason Samsb97b2512011-01-16 15:04:08 -0800200 private void validateIsInt32() {
201 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
202 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
203 return;
204 }
205 throw new RSIllegalArgumentException(
206 "32 bit integer source does not match allocation type " + mType.mElement.mType);
207 }
208
209 private void validateIsInt16() {
210 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
211 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
212 return;
213 }
214 throw new RSIllegalArgumentException(
215 "16 bit integer source does not match allocation type " + mType.mElement.mType);
216 }
217
218 private void validateIsInt8() {
219 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
220 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
221 return;
222 }
223 throw new RSIllegalArgumentException(
224 "8 bit integer source does not match allocation type " + mType.mElement.mType);
225 }
226
227 private void validateIsFloat32() {
228 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
229 return;
230 }
231 throw new RSIllegalArgumentException(
232 "32 bit float source does not match allocation type " + mType.mElement.mType);
233 }
234
235 private void validateIsObject() {
236 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
237 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
238 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
239 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
240 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
241 (mType.mElement.mType == Element.DataType.RS_MESH) ||
242 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
243 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
244 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
245 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
246 return;
247 }
248 throw new RSIllegalArgumentException(
249 "Object source does not match allocation type " + mType.mElement.mType);
250 }
251
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700252 @Override
253 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800254 super.updateFromNative();
255 int typeID = mRS.nAllocationGetType(getID());
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700256 if(typeID != 0) {
257 mType = new Type(typeID, mRS);
258 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700259 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700260 }
261 }
262
Jason Samsea87e962010-01-12 12:12:28 -0800263 public Type getType() {
264 return mType;
265 }
266
Jason Sams5476b452010-12-08 16:14:36 -0800267 public void syncAll(int srcLocation) {
268 switch (srcLocation) {
269 case USAGE_SCRIPT:
270 case USAGE_GRAPHICS_CONSTANTS:
271 case USAGE_GRAPHICS_TEXTURE:
272 case USAGE_GRAPHICS_VERTEX:
273 break;
274 default:
275 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
276 }
277 mRS.validate();
Jason Sams48fe5342011-07-08 13:52:30 -0700278 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
Jason Sams5476b452010-12-08 16:14:36 -0800279 }
280
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800281 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800282 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800283 validateIsObject();
Jason Samsba862d12011-07-07 15:24:42 -0700284 if (d.length != mCurrentCount) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800285 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
Jason Samsba862d12011-07-07 15:24:42 -0700286 mCurrentCount + ", array length = " + d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800287 }
288 int i[] = new int[d.length];
289 for (int ct=0; ct < d.length; ct++) {
290 i[ct] = d[ct].getID();
291 }
Jason Samsba862d12011-07-07 15:24:42 -0700292 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700293 }
294
Jason Samsfb9f82c2011-01-12 14:53:25 -0800295 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800296 Bitmap.Config bc = b.getConfig();
297 switch (bc) {
298 case ALPHA_8:
299 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
300 throw new RSIllegalArgumentException("Allocation kind is " +
301 mType.getElement().mKind + ", type " +
302 mType.getElement().mType +
303 " of " + mType.getElement().getSizeBytes() +
304 " bytes, passed bitmap was " + bc);
305 }
306 break;
307 case ARGB_8888:
308 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
309 (mType.getElement().getSizeBytes() != 4)) {
310 throw new RSIllegalArgumentException("Allocation kind is " +
311 mType.getElement().mKind + ", type " +
312 mType.getElement().mType +
313 " of " + mType.getElement().getSizeBytes() +
314 " bytes, passed bitmap was " + bc);
315 }
316 break;
317 case RGB_565:
318 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
319 (mType.getElement().getSizeBytes() != 2)) {
320 throw new RSIllegalArgumentException("Allocation kind is " +
321 mType.getElement().mKind + ", type " +
322 mType.getElement().mType +
323 " of " + mType.getElement().getSizeBytes() +
324 " bytes, passed bitmap was " + bc);
325 }
326 break;
327 case ARGB_4444:
328 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
329 (mType.getElement().getSizeBytes() != 2)) {
330 throw new RSIllegalArgumentException("Allocation kind is " +
331 mType.getElement().mKind + ", type " +
332 mType.getElement().mType +
333 " of " + mType.getElement().getSizeBytes() +
334 " bytes, passed bitmap was " + bc);
335 }
336 break;
337
338 }
Jason Sams4ef66502010-12-10 16:03:15 -0800339 }
340
Jason Samsfb9f82c2011-01-12 14:53:25 -0800341 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700342 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800343 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
344 }
345 }
346
Jason Sams4fa3eed2011-01-19 15:44:38 -0800347 /**
348 * Copy an allocation from an array. This variant is not type
349 * checked which allows an application to fill in structured
350 * data from an array.
351 *
352 * @param d the source data array
353 */
354 public void copyFromUnchecked(int[] d) {
355 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700356 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800357 }
358 /**
359 * Copy an allocation from an array. This variant is not type
360 * checked which allows an application to fill in structured
361 * data from an array.
362 *
363 * @param d the source data array
364 */
365 public void copyFromUnchecked(short[] d) {
366 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700367 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800368 }
369 /**
370 * Copy an allocation from an array. This variant is not type
371 * checked which allows an application to fill in structured
372 * data from an array.
373 *
374 * @param d the source data array
375 */
376 public void copyFromUnchecked(byte[] d) {
377 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700378 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800379 }
380 /**
381 * Copy an allocation from an array. This variant is not type
382 * checked which allows an application to fill in structured
383 * data from an array.
384 *
385 * @param d the source data array
386 */
387 public void copyFromUnchecked(float[] d) {
388 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700389 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800390 }
391
392 /**
393 * Copy an allocation from an array. This variant is type
394 * checked and will generate exceptions if the Allocation type
395 * is not a 32 bit integer type.
396 *
397 * @param d the source data array
398 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800399 public void copyFrom(int[] d) {
400 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700401 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800402 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800403
404 /**
405 * Copy an allocation from an array. This variant is type
406 * checked and will generate exceptions if the Allocation type
407 * is not a 16 bit integer type.
408 *
409 * @param d the source data array
410 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800411 public void copyFrom(short[] d) {
412 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700413 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800414 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800415
416 /**
417 * Copy an allocation from an array. This variant is type
418 * checked and will generate exceptions if the Allocation type
419 * is not a 8 bit integer type.
420 *
421 * @param d the source data array
422 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800423 public void copyFrom(byte[] d) {
424 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700425 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800426 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800427
428 /**
429 * Copy an allocation from an array. This variant is type
430 * checked and will generate exceptions if the Allocation type
431 * is not a 32 bit float type.
432 *
433 * @param d the source data array
434 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800435 public void copyFrom(float[] d) {
436 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700437 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800438 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800439
440 /**
441 * Copy an allocation from a bitmap. The height, width, and
442 * format of the bitmap must match the existing allocation.
443 *
444 * @param b the source bitmap
445 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800446 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800447 mRS.validate();
448 validateBitmapSize(b);
449 validateBitmapFormat(b);
Jason Sams4ef66502010-12-10 16:03:15 -0800450 mRS.nAllocationCopyFromBitmap(getID(), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700451 }
452
Jason Samsfa445b92011-01-07 17:00:07 -0800453 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800454 * This is only intended to be used by auto-generate code reflected from the
455 * renderscript script files.
456 *
457 * @param xoff
458 * @param fp
459 */
Jason Sams21b41032011-01-16 15:05:41 -0800460 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsa70f4162010-03-26 15:33:42 -0700461 int eSize = mType.mElement.getSizeBytes();
462 final byte[] data = fp.getData();
463
464 int count = data.length / eSize;
465 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800466 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700467 " not divisible by element size " + eSize + ".");
468 }
Jason Samsba862d12011-07-07 15:24:42 -0700469 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700470 }
471
Jason Samsfa445b92011-01-07 17:00:07 -0800472 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800473 * This is only intended to be used by auto-generate code reflected from the
474 * renderscript script files.
475 *
476 * @param xoff
477 * @param component_number
478 * @param fp
479 */
Jason Sams21b41032011-01-16 15:05:41 -0800480 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700481 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800482 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700483 }
484 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800485 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700486 }
487
488 final byte[] data = fp.getData();
489 int eSize = mType.mElement.mElements[component_number].getSizeBytes();
490
491 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800492 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700493 " does not match component size " + eSize + ".");
494 }
495
Jason Sams48fe5342011-07-08 13:52:30 -0700496 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
Jason Samsba862d12011-07-07 15:24:42 -0700497 component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700498 }
499
Jason Sams768bc022009-09-21 19:41:04 -0700500 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800501 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700502 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800503 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700504 }
505 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800506 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700507 }
Jason Samsba862d12011-07-07 15:24:42 -0700508 if((off + count) > mCurrentCount) {
509 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700510 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700511 }
Jason Samsba862d12011-07-07 15:24:42 -0700512 if(len < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800513 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700514 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700515 }
516
Jason Samsf7086092011-01-12 13:28:37 -0800517 /**
518 * Generate a mipmap chain. Requires the type of the allocation
519 * include mipmaps.
520 *
521 * This function will generate a complete set of mipmaps from
522 * the top level lod and place them into the script memoryspace.
523 *
524 * If the allocation is also using other memory spaces a
525 * followup sync will be required.
526 */
527 public void generateMipmaps() {
528 mRS.nAllocationGenerateMipmaps(getID());
529 }
530
Jason Sams4fa3eed2011-01-19 15:44:38 -0800531 /**
532 * Copy part of an allocation from an array. This variant is
533 * not type checked which allows an application to fill in
534 * structured data from an array.
535 *
536 * @param off The offset of the first element to be copied.
537 * @param count The number of elements to be copied.
538 * @param d the source data array
539 */
540 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700541 int dataSize = mType.mElement.getSizeBytes() * count;
542 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700543 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700544 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800545 /**
546 * Copy part of an allocation from an array. This variant is
547 * not type checked which allows an application to fill in
548 * structured data from an array.
549 *
550 * @param off The offset of the first element to be copied.
551 * @param count The number of elements to be copied.
552 * @param d the source data array
553 */
554 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700555 int dataSize = mType.mElement.getSizeBytes() * count;
556 data1DChecks(off, count, d.length * 2, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700557 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700558 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800559 /**
560 * Copy part of an allocation from an array. This variant is
561 * not type checked which allows an application to fill in
562 * structured data from an array.
563 *
564 * @param off The offset of the first element to be copied.
565 * @param count The number of elements to be copied.
566 * @param d the source data array
567 */
568 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700569 int dataSize = mType.mElement.getSizeBytes() * count;
570 data1DChecks(off, count, d.length, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700571 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700572 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800573 /**
574 * Copy part of an allocation from an array. This variant is
575 * not type checked which allows an application to fill in
576 * structured data from an array.
577 *
578 * @param off The offset of the first element to be copied.
579 * @param count The number of elements to be copied.
580 * @param d the source data array
581 */
582 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700583 int dataSize = mType.mElement.getSizeBytes() * count;
584 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700585 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700586 }
587
Jason Sams4fa3eed2011-01-19 15:44:38 -0800588 /**
589 * Copy part of an allocation from an array. This variant is
590 * type checked and will generate exceptions if the Allocation
591 * type is not a 32 bit integer type.
592 *
593 * @param off The offset of the first element to be copied.
594 * @param count The number of elements to be copied.
595 * @param d the source data array
596 */
Jason Samsb97b2512011-01-16 15:04:08 -0800597 public void copy1DRangeFrom(int off, int count, int[] d) {
598 validateIsInt32();
599 copy1DRangeFromUnchecked(off, count, d);
600 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800601
602 /**
603 * Copy part of an allocation from an array. This variant is
604 * type checked and will generate exceptions if the Allocation
605 * type is not a 16 bit integer type.
606 *
607 * @param off The offset of the first element to be copied.
608 * @param count The number of elements to be copied.
609 * @param d the source data array
610 */
Jason Samsb97b2512011-01-16 15:04:08 -0800611 public void copy1DRangeFrom(int off, int count, short[] d) {
612 validateIsInt16();
613 copy1DRangeFromUnchecked(off, count, d);
614 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800615
616 /**
617 * Copy part of an allocation from an array. This variant is
618 * type checked and will generate exceptions if the Allocation
619 * type is not a 8 bit integer type.
620 *
621 * @param off The offset of the first element to be copied.
622 * @param count The number of elements to be copied.
623 * @param d the source data array
624 */
Jason Samsb97b2512011-01-16 15:04:08 -0800625 public void copy1DRangeFrom(int off, int count, byte[] d) {
626 validateIsInt8();
627 copy1DRangeFromUnchecked(off, count, d);
628 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800629
630 /**
631 * Copy part of an allocation from an array. This variant is
632 * type checked and will generate exceptions if the Allocation
633 * type is not a 32 bit float type.
634 *
635 * @param off The offset of the first element to be copied.
636 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700637 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800638 */
Jason Samsb97b2512011-01-16 15:04:08 -0800639 public void copy1DRangeFrom(int off, int count, float[] d) {
640 validateIsFloat32();
641 copy1DRangeFromUnchecked(off, count, d);
642 }
643
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700644 /**
645 * Copy part of an allocation from another allocation.
646 *
647 * @param off The offset of the first element to be copied.
648 * @param count The number of elements to be copied.
649 * @param data the source data allocation.
650 * @param dataOff off The offset of the first element in data to
651 * be copied.
652 */
653 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Jason Sams48fe5342011-07-08 13:52:30 -0700654 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700655 mSelectedLOD, mSelectedFace.mID,
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700656 count, 1, data.getID(), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700657 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700658 }
659
Jason Samsfb9f82c2011-01-12 14:53:25 -0800660 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -0700661 if (mAdaptedAllocation != null) {
662
663 } else {
664
665 if (xoff < 0 || yoff < 0) {
666 throw new RSIllegalArgumentException("Offset cannot be negative.");
667 }
668 if (h < 0 || w < 0) {
669 throw new RSIllegalArgumentException("Height or width cannot be negative.");
670 }
671 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
672 throw new RSIllegalArgumentException("Updated region larger than allocation.");
673 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800674 }
675 }
Jason Sams768bc022009-09-21 19:41:04 -0700676
Jason Samsf7086092011-01-12 13:28:37 -0800677 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700678 * Copy a rectangular region from the array into the allocation.
679 * The incoming array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -0800680 *
681 * @param xoff X offset of the region to update
682 * @param yoff Y offset of the region to update
683 * @param w Width of the incoming region to update
684 * @param h Height of the incoming region to update
685 * @param data to be placed into the allocation
686 */
687 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800688 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800689 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700690 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700691 w, h, data, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -0800692 }
693
Jason Samsf7086092011-01-12 13:28:37 -0800694 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800695 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800696 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700697 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700698 w, h, data, data.length * 2);
Jason Samsfa445b92011-01-07 17:00:07 -0800699 }
700
Jason Samsf7086092011-01-12 13:28:37 -0800701 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800702 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800703 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700704 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700705 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700706 }
707
Jason Samsf7086092011-01-12 13:28:37 -0800708 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800709 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800710 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700711 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700712 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700713 }
714
Jason Samsf7086092011-01-12 13:28:37 -0800715 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700716 * Copy a rectangular region into the allocation from another
717 * allocation.
718 *
719 * @param xoff X offset of the region to update.
720 * @param yoff Y offset of the region to update.
721 * @param w Width of the incoming region to update.
722 * @param h Height of the incoming region to update.
723 * @param data source allocation.
724 * @param dataXoff X offset in data of the region to update.
725 * @param dataYoff Y offset in data of the region to update.
726 */
727 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
728 Allocation data, int dataXoff, int dataYoff) {
729 mRS.validate();
730 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700731 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
Jason Samsba862d12011-07-07 15:24:42 -0700732 mSelectedLOD, mSelectedFace.mID,
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700733 w, h, data.getID(), dataXoff, dataYoff,
Jason Samsba862d12011-07-07 15:24:42 -0700734 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700735 }
736
737 /**
Jason Samsf7086092011-01-12 13:28:37 -0800738 * Copy a bitmap into an allocation. The height and width of
739 * the update will use the height and width of the incoming
740 * bitmap.
741 *
742 * @param xoff X offset of the region to update
743 * @param yoff Y offset of the region to update
744 * @param data the bitmap to be copied
745 */
746 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800747 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800748 validateBitmapFormat(data);
749 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Sams48fe5342011-07-08 13:52:30 -0700750 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800751 }
752
753
Jason Sams48fe5342011-07-08 13:52:30 -0700754 /**
755 * Copy from the Allocation into a Bitmap. The bitmap must
756 * match the dimensions of the Allocation.
757 *
758 * @param b The bitmap to be set from the Allocation.
759 */
Jason Samsfa445b92011-01-07 17:00:07 -0800760 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800761 mRS.validate();
762 validateBitmapFormat(b);
763 validateBitmapSize(b);
Jason Samsfa445b92011-01-07 17:00:07 -0800764 mRS.nAllocationCopyToBitmap(getID(), b);
765 }
766
Jason Sams48fe5342011-07-08 13:52:30 -0700767 /**
768 * Copy from the Allocation into a byte array. The array must
769 * be at least as large as the Allocation. The allocation must
770 * be of an 8 bit elemental type.
771 *
772 * @param d The array to be set from the Allocation.
773 */
Jason Samsfa445b92011-01-07 17:00:07 -0800774 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800775 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -0800776 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800777 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700778 }
779
Jason Sams48fe5342011-07-08 13:52:30 -0700780 /**
781 * Copy from the Allocation into a short array. The array must
782 * be at least as large as the Allocation. The allocation must
783 * be of an 16 bit elemental type.
784 *
785 * @param d The array to be set from the Allocation.
786 */
Jason Samsfa445b92011-01-07 17:00:07 -0800787 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800788 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -0800789 mRS.validate();
790 mRS.nAllocationRead(getID(), d);
791 }
792
Jason Sams48fe5342011-07-08 13:52:30 -0700793 /**
794 * Copy from the Allocation into a int array. The array must be
795 * at least as large as the Allocation. The allocation must be
796 * of an 32 bit elemental type.
797 *
798 * @param d The array to be set from the Allocation.
799 */
Jason Samsfa445b92011-01-07 17:00:07 -0800800 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800801 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -0800802 mRS.validate();
803 mRS.nAllocationRead(getID(), d);
804 }
805
Jason Sams48fe5342011-07-08 13:52:30 -0700806 /**
807 * Copy from the Allocation into a float array. The array must
808 * be at least as large as the Allocation. The allocation must
809 * be of an 32 bit float elemental type.
810 *
811 * @param d The array to be set from the Allocation.
812 */
Jason Samsfa445b92011-01-07 17:00:07 -0800813 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800814 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -0800815 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800816 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700817 }
818
Jason Samsf7086092011-01-12 13:28:37 -0800819 /**
820 * Resize a 1D allocation. The contents of the allocation are
821 * preserved. If new elements are allocated objects are created
822 * with null contents and the new region is otherwise undefined.
823 *
824 * If the new region is smaller the references of any objects
825 * outside the new region will be released.
826 *
827 * A new type will be created with the new dimension.
828 *
829 * @param dimX The new size of the allocation.
830 */
Jason Sams31a7e422010-10-26 13:09:17 -0700831 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800832 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800833 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700834 }
Jason Sams06d69de2010-11-09 17:11:40 -0800835 mRS.nAllocationResize1D(getID(), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -0700836 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -0700837
Jason Sams06d69de2010-11-09 17:11:40 -0800838 int typeID = mRS.nAllocationGetType(getID());
Jason Sams31a7e422010-10-26 13:09:17 -0700839 mType = new Type(typeID, mRS);
840 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -0700841 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -0700842 }
843
844 /*
845 public void resize(int dimX, int dimY) {
846 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800847 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700848 }
849 if (mType.getY() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800850 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700851 }
Jason Sams06d69de2010-11-09 17:11:40 -0800852 mRS.nAllocationResize2D(getID(), dimX, dimY);
Jason Sams5edc6082010-10-05 13:32:49 -0700853 }
854 */
Jason Sams40a29e82009-08-10 14:55:26 -0700855
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700856
Jason Samsb8c5a842009-07-31 20:40:47 -0700857
858 // creation
859
Jason Sams49a05d72010-12-29 14:31:29 -0800860 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -0700861 static {
862 mBitmapOptions.inScaled = false;
863 }
864
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800865 /**
866 *
867 * @param type renderscript type describing data layout
868 * @param mips specifies desired mipmap behaviour for the
869 * allocation
870 * @param usage bit field specifying how the allocation is
871 * utilized
872 */
873 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800874 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800875 if (type.getID() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800876 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -0700877 }
Jason Sams857d0c72011-11-23 15:02:15 -0800878 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, 0);
879 if (id == 0) {
880 throw new RSRuntimeException("Allocation creation failed.");
881 }
882 return new Allocation(id, rs, type, usage);
883 }
884
885 /**
886 * @hide
887 * This API is hidden and only intended to be used for
888 * transitional purposes.
889 *
890 * @param type renderscript type describing data layout
891 * @param mips specifies desired mipmap behaviour for the
892 * allocation
893 * @param usage bit field specifying how the allocation is
894 * utilized
895 */
896 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips,
897 int usage, int pointer) {
898 rs.validate();
899 if (type.getID() == 0) {
900 throw new RSInvalidStateException("Bad Type");
901 }
902 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, pointer);
Jason Sams5476b452010-12-08 16:14:36 -0800903 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800904 throw new RSRuntimeException("Allocation creation failed.");
905 }
Jason Sams5476b452010-12-08 16:14:36 -0800906 return new Allocation(id, rs, type, usage);
Jason Samsb8c5a842009-07-31 20:40:47 -0700907 }
908
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800909 /**
910 * Creates a renderscript allocation with the size specified by
911 * the type and no mipmaps generated by default
912 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800913 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800914 * @param type renderscript type describing data layout
915 * @param usage bit field specifying how the allocation is
916 * utilized
917 *
918 * @return allocation
919 */
Jason Samse5d37122010-12-16 00:33:33 -0800920 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
921 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
922 }
923
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800924 /**
925 * Creates a renderscript allocation for use by the script with
926 * the size specified by the type and no mipmaps generated by
927 * default
928 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800929 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800930 * @param type renderscript type describing data layout
931 *
932 * @return allocation
933 */
Jason Sams5476b452010-12-08 16:14:36 -0800934 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800935 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -0800936 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700937
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800938 /**
939 * Creates a renderscript allocation with a specified number of
940 * given elements
941 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800942 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800943 * @param e describes what each element of an allocation is
944 * @param count specifies the number of element in the allocation
945 * @param usage bit field specifying how the allocation is
946 * utilized
947 *
948 * @return allocation
949 */
Jason Sams5476b452010-12-08 16:14:36 -0800950 static public Allocation createSized(RenderScript rs, Element e,
951 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800952 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -0700953 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800954 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -0700955 Type t = b.create();
956
Jason Sams857d0c72011-11-23 15:02:15 -0800957 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage, 0);
Jason Sams5476b452010-12-08 16:14:36 -0800958 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800959 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700960 }
Jason Sams5476b452010-12-08 16:14:36 -0800961 return new Allocation(id, rs, t, usage);
962 }
963
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800964 /**
965 * Creates a renderscript allocation with a specified number of
966 * given elements
967 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800968 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800969 * @param e describes what each element of an allocation is
970 * @param count specifies the number of element in the allocation
971 *
972 * @return allocation
973 */
Jason Sams5476b452010-12-08 16:14:36 -0800974 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800975 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -0700976 }
977
Jason Sams49a05d72010-12-29 14:31:29 -0800978 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -0800979 final Bitmap.Config bc = b.getConfig();
980 if (bc == Bitmap.Config.ALPHA_8) {
981 return Element.A_8(rs);
982 }
983 if (bc == Bitmap.Config.ARGB_4444) {
984 return Element.RGBA_4444(rs);
985 }
986 if (bc == Bitmap.Config.ARGB_8888) {
987 return Element.RGBA_8888(rs);
988 }
989 if (bc == Bitmap.Config.RGB_565) {
990 return Element.RGB_565(rs);
991 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -0800992 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -0800993 }
994
Jason Sams49a05d72010-12-29 14:31:29 -0800995 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800996 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -0800997 Element e = elementFromBitmap(rs, b);
998 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800999 tb.setX(b.getWidth());
1000 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -08001001 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -08001002 return tb.create();
1003 }
1004
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001005 /**
1006 * Creates a renderscript allocation from a bitmap
1007 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001008 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001009 * @param b bitmap source for the allocation data
1010 * @param mips specifies desired mipmap behaviour for the
1011 * allocation
1012 * @param usage bit field specifying how the allocation is
1013 * utilized
1014 *
1015 * @return renderscript allocation containing bitmap data
1016 *
1017 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001018 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001019 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001020 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -08001021 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001022 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -08001023
Jason Sams5476b452010-12-08 16:14:36 -08001024 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
1025 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001026 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -08001027 }
Jason Sams5476b452010-12-08 16:14:36 -08001028 return new Allocation(id, rs, t, usage);
1029 }
1030
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001031 /**
1032 * Creates a non-mipmapped renderscript allocation to use as a
1033 * graphics texture
1034 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001035 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001036 * @param b bitmap source for the allocation data
1037 *
1038 * @return renderscript allocation containing bitmap data
1039 *
1040 */
Jason Sams6d8eb262010-12-15 01:41:00 -08001041 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
1042 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1043 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08001044 }
1045
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001046 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001047 * Creates a cubemap allocation from a bitmap containing the
1048 * horizontal list of cube faces. Each individual face must be
1049 * the same size and power of 2
1050 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001051 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001052 * @param b bitmap with cubemap faces layed out in the following
1053 * format: right, left, top, bottom, front, back
1054 * @param mips specifies desired mipmap behaviour for the cubemap
1055 * @param usage bit field specifying how the cubemap is utilized
1056 *
1057 * @return allocation containing cubemap data
1058 *
1059 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001060 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001061 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001062 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001063 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001064
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001065 int height = b.getHeight();
1066 int width = b.getWidth();
1067
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001068 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001069 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
1070 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001071 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001072 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001073 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001074 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001075 if (!isPow2) {
1076 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1077 }
1078
1079 Element e = elementFromBitmap(rs, b);
1080 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001081 tb.setX(height);
1082 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001083 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08001084 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001085 Type t = tb.create();
1086
Jason Sams5476b452010-12-08 16:14:36 -08001087 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001088 if(id == 0) {
1089 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
1090 }
Jason Sams5476b452010-12-08 16:14:36 -08001091 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001092 }
1093
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001094 /**
1095 * Creates a non-mipmapped cubemap allocation for use as a
1096 * graphics texture from a bitmap containing the horizontal list
1097 * of cube faces. Each individual face must be the same size and
1098 * power of 2
1099 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001100 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001101 * @param b bitmap with cubemap faces layed out in the following
1102 * format: right, left, top, bottom, front, back
1103 *
1104 * @return allocation containing cubemap data
1105 *
1106 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001107 static public Allocation createCubemapFromBitmap(RenderScript rs,
1108 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08001109 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001110 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08001111 }
1112
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001113 /**
1114 * Creates a cubemap allocation from 6 bitmaps containing
1115 * the cube faces. All the faces must be the same size and
1116 * power of 2
1117 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001118 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001119 * @param xpos cubemap face in the positive x direction
1120 * @param xneg cubemap face in the negative x direction
1121 * @param ypos cubemap face in the positive y direction
1122 * @param yneg cubemap face in the negative y direction
1123 * @param zpos cubemap face in the positive z direction
1124 * @param zneg cubemap face in the negative z direction
1125 * @param mips specifies desired mipmap behaviour for the cubemap
1126 * @param usage bit field specifying how the cubemap is utilized
1127 *
1128 * @return allocation containing cubemap data
1129 *
1130 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001131 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1132 Bitmap xpos,
1133 Bitmap xneg,
1134 Bitmap ypos,
1135 Bitmap yneg,
1136 Bitmap zpos,
1137 Bitmap zneg,
1138 MipmapControl mips,
1139 int usage) {
1140 int height = xpos.getHeight();
1141 if (xpos.getWidth() != height ||
1142 xneg.getWidth() != height || xneg.getHeight() != height ||
1143 ypos.getWidth() != height || ypos.getHeight() != height ||
1144 yneg.getWidth() != height || yneg.getHeight() != height ||
1145 zpos.getWidth() != height || zpos.getHeight() != height ||
1146 zneg.getWidth() != height || zneg.getHeight() != height) {
1147 throw new RSIllegalArgumentException("Only square cube map faces supported");
1148 }
1149 boolean isPow2 = (height & (height - 1)) == 0;
1150 if (!isPow2) {
1151 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1152 }
1153
1154 Element e = elementFromBitmap(rs, xpos);
1155 Type.Builder tb = new Type.Builder(rs, e);
1156 tb.setX(height);
1157 tb.setY(height);
1158 tb.setFaces(true);
1159 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1160 Type t = tb.create();
1161 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1162
1163 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07001164 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001165 adapter.copyFrom(xpos);
1166 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1167 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001168 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001169 adapter.copyFrom(ypos);
1170 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1171 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001172 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001173 adapter.copyFrom(zpos);
1174 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1175 adapter.copyFrom(zneg);
1176
1177 return cubemap;
1178 }
1179
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001180 /**
1181 * Creates a non-mipmapped cubemap allocation for use as a
1182 * graphics texture from 6 bitmaps containing
1183 * the cube faces. All the faces must be the same size and
1184 * power of 2
1185 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001186 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001187 * @param xpos cubemap face in the positive x direction
1188 * @param xneg cubemap face in the negative x direction
1189 * @param ypos cubemap face in the positive y direction
1190 * @param yneg cubemap face in the negative y direction
1191 * @param zpos cubemap face in the positive z direction
1192 * @param zneg cubemap face in the negative z direction
1193 *
1194 * @return allocation containing cubemap data
1195 *
1196 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001197 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1198 Bitmap xpos,
1199 Bitmap xneg,
1200 Bitmap ypos,
1201 Bitmap yneg,
1202 Bitmap zpos,
1203 Bitmap zneg) {
1204 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1205 zpos, zneg, MipmapControl.MIPMAP_NONE,
1206 USAGE_GRAPHICS_TEXTURE);
1207 }
1208
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001209 /**
1210 * Creates a renderscript allocation from the bitmap referenced
1211 * by resource id
1212 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001213 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001214 * @param res application resources
1215 * @param id resource id to load the data from
1216 * @param mips specifies desired mipmap behaviour for the
1217 * allocation
1218 * @param usage bit field specifying how the allocation is
1219 * utilized
1220 *
1221 * @return renderscript allocation containing resource data
1222 *
1223 */
Jason Sams5476b452010-12-08 16:14:36 -08001224 static public Allocation createFromBitmapResource(RenderScript rs,
1225 Resources res,
1226 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001227 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001228 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001229
Jason Sams771bebb2009-12-07 12:40:12 -08001230 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001231 Bitmap b = BitmapFactory.decodeResource(res, id);
1232 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1233 b.recycle();
1234 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001235 }
1236
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001237 /**
1238 * Creates a non-mipmapped renderscript allocation to use as a
1239 * graphics texture from the bitmap referenced by resource id
1240 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001241 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001242 * @param res application resources
1243 * @param id resource id to load the data from
1244 *
1245 * @return renderscript allocation containing resource data
1246 *
1247 */
Jason Sams5476b452010-12-08 16:14:36 -08001248 static public Allocation createFromBitmapResource(RenderScript rs,
1249 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001250 int id) {
1251 return createFromBitmapResource(rs, res, id,
1252 MipmapControl.MIPMAP_NONE,
1253 USAGE_GRAPHICS_TEXTURE);
1254 }
1255
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001256 /**
1257 * Creates a renderscript allocation containing string data
1258 * encoded in UTF-8 format
1259 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001260 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001261 * @param str string to create the allocation from
1262 * @param usage bit field specifying how the allocaiton is
1263 * utilized
1264 *
1265 */
Jason Sams5476b452010-12-08 16:14:36 -08001266 static public Allocation createFromString(RenderScript rs,
1267 String str,
1268 int usage) {
1269 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001270 byte[] allocArray = null;
1271 try {
1272 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001273 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001274 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001275 return alloc;
1276 }
1277 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001278 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001279 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001280 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001281}
1282
1283