blob: f285f5b5ac0c98738243f2cbe5b1752c0ce7c86e [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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 Samsbf6ef8d2010-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 }
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800878 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800879 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800880 throw new RSRuntimeException("Allocation creation failed.");
881 }
Jason Sams5476b452010-12-08 16:14:36 -0800882 return new Allocation(id, rs, type, usage);
Jason Samsb8c5a842009-07-31 20:40:47 -0700883 }
884
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800885 /**
886 * Creates a renderscript allocation with the size specified by
887 * the type and no mipmaps generated by default
888 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800889 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800890 * @param type renderscript type describing data layout
891 * @param usage bit field specifying how the allocation is
892 * utilized
893 *
894 * @return allocation
895 */
Jason Samse5d37122010-12-16 00:33:33 -0800896 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
897 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
898 }
899
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800900 /**
901 * Creates a renderscript allocation for use by the script with
902 * the size specified by the type and no mipmaps generated by
903 * default
904 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800905 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800906 * @param type renderscript type describing data layout
907 *
908 * @return allocation
909 */
Jason Sams5476b452010-12-08 16:14:36 -0800910 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800911 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -0800912 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700913
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800914 /**
915 * Creates a renderscript allocation with a specified number of
916 * given elements
917 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800918 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800919 * @param e describes what each element of an allocation is
920 * @param count specifies the number of element in the allocation
921 * @param usage bit field specifying how the allocation is
922 * utilized
923 *
924 * @return allocation
925 */
Jason Sams5476b452010-12-08 16:14:36 -0800926 static public Allocation createSized(RenderScript rs, Element e,
927 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800928 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -0700929 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800930 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -0700931 Type t = b.create();
932
Jason Samsd4b23b52010-12-13 15:32:35 -0800933 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800934 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800935 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700936 }
Jason Sams5476b452010-12-08 16:14:36 -0800937 return new Allocation(id, rs, t, usage);
938 }
939
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800940 /**
941 * Creates a renderscript allocation with a specified number of
942 * given elements
943 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800944 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800945 * @param e describes what each element of an allocation is
946 * @param count specifies the number of element in the allocation
947 *
948 * @return allocation
949 */
Jason Sams5476b452010-12-08 16:14:36 -0800950 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800951 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -0700952 }
953
Jason Sams49a05d72010-12-29 14:31:29 -0800954 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -0800955 final Bitmap.Config bc = b.getConfig();
956 if (bc == Bitmap.Config.ALPHA_8) {
957 return Element.A_8(rs);
958 }
959 if (bc == Bitmap.Config.ARGB_4444) {
960 return Element.RGBA_4444(rs);
961 }
962 if (bc == Bitmap.Config.ARGB_8888) {
963 return Element.RGBA_8888(rs);
964 }
965 if (bc == Bitmap.Config.RGB_565) {
966 return Element.RGB_565(rs);
967 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -0800968 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -0800969 }
970
Jason Sams49a05d72010-12-29 14:31:29 -0800971 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800972 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -0800973 Element e = elementFromBitmap(rs, b);
974 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800975 tb.setX(b.getWidth());
976 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -0800977 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -0800978 return tb.create();
979 }
980
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800981 /**
982 * Creates a renderscript allocation from a bitmap
983 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800984 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800985 * @param b bitmap source for the allocation data
986 * @param mips specifies desired mipmap behaviour for the
987 * allocation
988 * @param usage bit field specifying how the allocation is
989 * utilized
990 *
991 * @return renderscript allocation containing bitmap data
992 *
993 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800994 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800995 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800996 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800997 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800998 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -0800999
Jason Sams5476b452010-12-08 16:14:36 -08001000 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
1001 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -08001002 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -08001003 }
Jason Sams5476b452010-12-08 16:14:36 -08001004 return new Allocation(id, rs, t, usage);
1005 }
1006
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001007 /**
1008 * Creates a non-mipmapped renderscript allocation to use as a
1009 * graphics texture
1010 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001011 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001012 * @param b bitmap source for the allocation data
1013 *
1014 * @return renderscript allocation containing bitmap data
1015 *
1016 */
Jason Sams6d8eb262010-12-15 01:41:00 -08001017 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
1018 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1019 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08001020 }
1021
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001022 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001023 * Creates a cubemap allocation from a bitmap containing the
1024 * horizontal list of cube faces. Each individual face must be
1025 * the same size and power of 2
1026 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001027 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001028 * @param b bitmap with cubemap faces layed out in the following
1029 * format: right, left, top, bottom, front, back
1030 * @param mips specifies desired mipmap behaviour for the cubemap
1031 * @param usage bit field specifying how the cubemap is utilized
1032 *
1033 * @return allocation containing cubemap data
1034 *
1035 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001036 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001037 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001038 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001039 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001040
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001041 int height = b.getHeight();
1042 int width = b.getWidth();
1043
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001044 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001045 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
1046 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001047 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001048 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001049 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001050 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001051 if (!isPow2) {
1052 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1053 }
1054
1055 Element e = elementFromBitmap(rs, b);
1056 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001057 tb.setX(height);
1058 tb.setY(height);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08001059 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08001060 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001061 Type t = tb.create();
1062
Jason Sams5476b452010-12-08 16:14:36 -08001063 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001064 if(id == 0) {
1065 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
1066 }
Jason Sams5476b452010-12-08 16:14:36 -08001067 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001068 }
1069
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001070 /**
1071 * Creates a non-mipmapped cubemap allocation for use as a
1072 * graphics texture from a bitmap containing the horizontal list
1073 * of cube faces. Each individual face must be the same size and
1074 * power of 2
1075 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001076 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001077 * @param b bitmap with cubemap faces layed out in the following
1078 * format: right, left, top, bottom, front, back
1079 *
1080 * @return allocation containing cubemap data
1081 *
1082 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001083 static public Allocation createCubemapFromBitmap(RenderScript rs,
1084 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08001085 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001086 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08001087 }
1088
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001089 /**
1090 * Creates a cubemap allocation from 6 bitmaps containing
1091 * the cube faces. All the faces must be the same size and
1092 * power of 2
1093 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001094 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001095 * @param xpos cubemap face in the positive x direction
1096 * @param xneg cubemap face in the negative x direction
1097 * @param ypos cubemap face in the positive y direction
1098 * @param yneg cubemap face in the negative y direction
1099 * @param zpos cubemap face in the positive z direction
1100 * @param zneg cubemap face in the negative z direction
1101 * @param mips specifies desired mipmap behaviour for the cubemap
1102 * @param usage bit field specifying how the cubemap is utilized
1103 *
1104 * @return allocation containing cubemap data
1105 *
1106 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001107 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1108 Bitmap xpos,
1109 Bitmap xneg,
1110 Bitmap ypos,
1111 Bitmap yneg,
1112 Bitmap zpos,
1113 Bitmap zneg,
1114 MipmapControl mips,
1115 int usage) {
1116 int height = xpos.getHeight();
1117 if (xpos.getWidth() != height ||
1118 xneg.getWidth() != height || xneg.getHeight() != height ||
1119 ypos.getWidth() != height || ypos.getHeight() != height ||
1120 yneg.getWidth() != height || yneg.getHeight() != height ||
1121 zpos.getWidth() != height || zpos.getHeight() != height ||
1122 zneg.getWidth() != height || zneg.getHeight() != height) {
1123 throw new RSIllegalArgumentException("Only square cube map faces supported");
1124 }
1125 boolean isPow2 = (height & (height - 1)) == 0;
1126 if (!isPow2) {
1127 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1128 }
1129
1130 Element e = elementFromBitmap(rs, xpos);
1131 Type.Builder tb = new Type.Builder(rs, e);
1132 tb.setX(height);
1133 tb.setY(height);
1134 tb.setFaces(true);
1135 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1136 Type t = tb.create();
1137 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1138
1139 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07001140 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001141 adapter.copyFrom(xpos);
1142 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1143 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001144 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001145 adapter.copyFrom(ypos);
1146 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1147 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001148 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001149 adapter.copyFrom(zpos);
1150 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1151 adapter.copyFrom(zneg);
1152
1153 return cubemap;
1154 }
1155
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001156 /**
1157 * Creates a non-mipmapped cubemap allocation for use as a
1158 * graphics texture from 6 bitmaps containing
1159 * the cube faces. All the faces must be the same size and
1160 * power of 2
1161 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001162 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001163 * @param xpos cubemap face in the positive x direction
1164 * @param xneg cubemap face in the negative x direction
1165 * @param ypos cubemap face in the positive y direction
1166 * @param yneg cubemap face in the negative y direction
1167 * @param zpos cubemap face in the positive z direction
1168 * @param zneg cubemap face in the negative z direction
1169 *
1170 * @return allocation containing cubemap data
1171 *
1172 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001173 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1174 Bitmap xpos,
1175 Bitmap xneg,
1176 Bitmap ypos,
1177 Bitmap yneg,
1178 Bitmap zpos,
1179 Bitmap zneg) {
1180 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1181 zpos, zneg, MipmapControl.MIPMAP_NONE,
1182 USAGE_GRAPHICS_TEXTURE);
1183 }
1184
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001185 /**
1186 * Creates a renderscript allocation from the bitmap referenced
1187 * by resource id
1188 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001189 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001190 * @param res application resources
1191 * @param id resource id to load the data from
1192 * @param mips specifies desired mipmap behaviour for the
1193 * allocation
1194 * @param usage bit field specifying how the allocation is
1195 * utilized
1196 *
1197 * @return renderscript allocation containing resource data
1198 *
1199 */
Jason Sams5476b452010-12-08 16:14:36 -08001200 static public Allocation createFromBitmapResource(RenderScript rs,
1201 Resources res,
1202 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001203 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001204 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001205
Jason Sams771bebb2009-12-07 12:40:12 -08001206 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001207 Bitmap b = BitmapFactory.decodeResource(res, id);
1208 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1209 b.recycle();
1210 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001211 }
1212
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001213 /**
1214 * Creates a non-mipmapped renderscript allocation to use as a
1215 * graphics texture from the bitmap referenced by resource id
1216 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001217 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001218 * @param res application resources
1219 * @param id resource id to load the data from
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,
Jason Sams6d8eb262010-12-15 01:41:00 -08001226 int id) {
1227 return createFromBitmapResource(rs, res, id,
1228 MipmapControl.MIPMAP_NONE,
1229 USAGE_GRAPHICS_TEXTURE);
1230 }
1231
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001232 /**
1233 * Creates a renderscript allocation containing string data
1234 * encoded in UTF-8 format
1235 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001236 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001237 * @param str string to create the allocation from
1238 * @param usage bit field specifying how the allocaiton is
1239 * utilized
1240 *
1241 */
Jason Sams5476b452010-12-08 16:14:36 -08001242 static public Allocation createFromString(RenderScript rs,
1243 String str,
1244 int usage) {
1245 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001246 byte[] allocArray = null;
1247 try {
1248 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001249 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08001250 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001251 return alloc;
1252 }
1253 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001254 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001255 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001256 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001257}
1258
1259