blob: 12e5ada5c67390f9aebeccc3b4729ee7959cd6a5 [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 *
65 **/
66public class Allocation extends BaseObj {
Jason Sams43ee06852009-08-12 17:54:11 -070067 Type mType;
Jason Sams8a647432010-03-01 15:31:04 -080068 Bitmap mBitmap;
Jason Sams5476b452010-12-08 16:14:36 -080069 int mUsage;
Jason Samsba862d12011-07-07 15:24:42 -070070 Allocation mAdaptedAllocation;
71
72 boolean mConstrainedLOD;
73 boolean mConstrainedFace;
74 boolean mConstrainedY;
75 boolean mConstrainedZ;
76 int mSelectedY;
77 int mSelectedZ;
78 int mSelectedLOD;
79 Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
80
81 int mCurrentDimX;
82 int mCurrentDimY;
83 int mCurrentDimZ;
84 int mCurrentCount;
85
Jason Sams5476b452010-12-08 16:14:36 -080086
Jason Samsf7086092011-01-12 13:28:37 -080087 /**
88 * The usage of the allocation. These signal to renderscript
89 * where to place the allocation in memory.
90 *
91 * SCRIPT The allocation will be bound to and accessed by
92 * scripts.
93 */
Jason Sams5476b452010-12-08 16:14:36 -080094 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -080095
96 /**
97 * GRAPHICS_TEXTURE The allcation will be used as a texture
Stephen Hines836c4a52011-06-01 14:38:10 -070098 * source by one or more graphics programs.
Jason Samsf7086092011-01-12 13:28:37 -080099 *
100 */
Jason Sams5476b452010-12-08 16:14:36 -0800101 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -0800102
103 /**
104 * GRAPHICS_VERTEX The allocation will be used as a graphics
105 * mesh.
106 *
107 */
Jason Sams5476b452010-12-08 16:14:36 -0800108 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -0800109
110
111 /**
112 * GRAPHICS_CONSTANTS The allocation will be used as the source
113 * of shader constants by one or more programs.
114 *
115 */
Jason Sams5476b452010-12-08 16:14:36 -0800116 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
117
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700118 /**
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700119 * USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
120 * target for offscreen rendering
121 *
122 */
123 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
124
Jason Sams43ee06852009-08-12 17:54:11 -0700125
Jason Samsf7086092011-01-12 13:28:37 -0800126 /**
127 * Controls mipmap behavior when using the bitmap creation and
128 * update functions.
129 */
Jason Sams4ef66502010-12-10 16:03:15 -0800130 public enum MipmapControl {
Jason Samsf7086092011-01-12 13:28:37 -0800131 /**
132 * No mipmaps will be generated and the type generated from the
133 * incoming bitmap will not contain additional LODs.
134 */
Jason Sams5476b452010-12-08 16:14:36 -0800135 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800136
137 /**
138 * A Full mipmap chain will be created in script memory. The
139 * type of the allocation will contain a full mipmap chain. On
140 * upload to graphics the full chain will be transfered.
141 */
Jason Sams5476b452010-12-08 16:14:36 -0800142 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800143
144 /**
145 * The type of the allocation will be the same as MIPMAP_NONE.
146 * It will not contain mipmaps. On upload to graphics the
147 * graphics copy of the allocation data will contain a full
148 * mipmap chain generated from the top level in script memory.
149 */
Jason Sams5476b452010-12-08 16:14:36 -0800150 MIPMAP_ON_SYNC_TO_TEXTURE(2);
151
152 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800153 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800154 mID = id;
155 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700156 }
157
Jason Sams48fe5342011-07-08 13:52:30 -0700158
159 private int getIDSafe() {
160 if (mAdaptedAllocation != null) {
161 return mAdaptedAllocation.getID();
162 }
163 return getID();
164 }
165
Jason Sams452a7662011-07-07 16:05:18 -0700166 private void updateCacheInfo(Type t) {
167 mCurrentDimX = t.getX();
168 mCurrentDimY = t.getY();
169 mCurrentDimZ = t.getZ();
170 mCurrentCount = mCurrentDimX;
171 if (mCurrentDimY > 1) {
172 mCurrentCount *= mCurrentDimY;
173 }
174 if (mCurrentDimZ > 1) {
175 mCurrentCount *= mCurrentDimZ;
176 }
177 }
Jason Samsba862d12011-07-07 15:24:42 -0700178
Jason Sams5476b452010-12-08 16:14:36 -0800179 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700180 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800181 if ((usage & ~(USAGE_SCRIPT |
182 USAGE_GRAPHICS_TEXTURE |
183 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700184 USAGE_GRAPHICS_CONSTANTS |
185 USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800186 throw new RSIllegalArgumentException("Unknown usage specified.");
187 }
188 mType = t;
Jason Samsba862d12011-07-07 15:24:42 -0700189
Jason Sams452a7662011-07-07 16:05:18 -0700190 if (t != null) {
191 updateCacheInfo(t);
Jason Samsba862d12011-07-07 15:24:42 -0700192 }
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700193 }
194
Jason Samsb97b2512011-01-16 15:04:08 -0800195 private void validateIsInt32() {
196 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
197 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
198 return;
199 }
200 throw new RSIllegalArgumentException(
201 "32 bit integer source does not match allocation type " + mType.mElement.mType);
202 }
203
204 private void validateIsInt16() {
205 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
206 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
207 return;
208 }
209 throw new RSIllegalArgumentException(
210 "16 bit integer source does not match allocation type " + mType.mElement.mType);
211 }
212
213 private void validateIsInt8() {
214 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
215 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
216 return;
217 }
218 throw new RSIllegalArgumentException(
219 "8 bit integer source does not match allocation type " + mType.mElement.mType);
220 }
221
222 private void validateIsFloat32() {
223 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
224 return;
225 }
226 throw new RSIllegalArgumentException(
227 "32 bit float source does not match allocation type " + mType.mElement.mType);
228 }
229
230 private void validateIsObject() {
231 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
232 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
233 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
234 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
235 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
236 (mType.mElement.mType == Element.DataType.RS_MESH) ||
237 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
238 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
239 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
240 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
241 return;
242 }
243 throw new RSIllegalArgumentException(
244 "Object source does not match allocation type " + mType.mElement.mType);
245 }
246
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700247 @Override
248 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800249 super.updateFromNative();
250 int typeID = mRS.nAllocationGetType(getID());
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700251 if(typeID != 0) {
252 mType = new Type(typeID, mRS);
253 mType.updateFromNative();
Jason Samsad37cb22011-07-07 16:17:36 -0700254 updateCacheInfo(mType);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700255 }
256 }
257
Jason Samsea87e962010-01-12 12:12:28 -0800258 public Type getType() {
259 return mType;
260 }
261
Jason Sams5476b452010-12-08 16:14:36 -0800262 public void syncAll(int srcLocation) {
263 switch (srcLocation) {
264 case USAGE_SCRIPT:
265 case USAGE_GRAPHICS_CONSTANTS:
266 case USAGE_GRAPHICS_TEXTURE:
267 case USAGE_GRAPHICS_VERTEX:
268 break;
269 default:
270 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
271 }
272 mRS.validate();
Jason Sams48fe5342011-07-08 13:52:30 -0700273 mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
Jason Sams5476b452010-12-08 16:14:36 -0800274 }
275
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800276 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800277 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800278 validateIsObject();
Jason Samsba862d12011-07-07 15:24:42 -0700279 if (d.length != mCurrentCount) {
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800280 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
Jason Samsba862d12011-07-07 15:24:42 -0700281 mCurrentCount + ", array length = " + d.length);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800282 }
283 int i[] = new int[d.length];
284 for (int ct=0; ct < d.length; ct++) {
285 i[ct] = d[ct].getID();
286 }
Jason Samsba862d12011-07-07 15:24:42 -0700287 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700288 }
289
Jason Samsfb9f82c2011-01-12 14:53:25 -0800290 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800291 Bitmap.Config bc = b.getConfig();
292 switch (bc) {
293 case ALPHA_8:
294 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
295 throw new RSIllegalArgumentException("Allocation kind is " +
296 mType.getElement().mKind + ", type " +
297 mType.getElement().mType +
298 " of " + mType.getElement().getSizeBytes() +
299 " bytes, passed bitmap was " + bc);
300 }
301 break;
302 case ARGB_8888:
303 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
304 (mType.getElement().getSizeBytes() != 4)) {
305 throw new RSIllegalArgumentException("Allocation kind is " +
306 mType.getElement().mKind + ", type " +
307 mType.getElement().mType +
308 " of " + mType.getElement().getSizeBytes() +
309 " bytes, passed bitmap was " + bc);
310 }
311 break;
312 case RGB_565:
313 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
314 (mType.getElement().getSizeBytes() != 2)) {
315 throw new RSIllegalArgumentException("Allocation kind is " +
316 mType.getElement().mKind + ", type " +
317 mType.getElement().mType +
318 " of " + mType.getElement().getSizeBytes() +
319 " bytes, passed bitmap was " + bc);
320 }
321 break;
322 case ARGB_4444:
323 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
324 (mType.getElement().getSizeBytes() != 2)) {
325 throw new RSIllegalArgumentException("Allocation kind is " +
326 mType.getElement().mKind + ", type " +
327 mType.getElement().mType +
328 " of " + mType.getElement().getSizeBytes() +
329 " bytes, passed bitmap was " + bc);
330 }
331 break;
332
333 }
Jason Sams4ef66502010-12-10 16:03:15 -0800334 }
335
Jason Samsfb9f82c2011-01-12 14:53:25 -0800336 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700337 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800338 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
339 }
340 }
341
Jason Sams4fa3eed2011-01-19 15:44:38 -0800342 /**
343 * Copy an allocation from an array. This variant is not type
344 * checked which allows an application to fill in structured
345 * data from an array.
346 *
347 * @param d the source data array
348 */
349 public void copyFromUnchecked(int[] d) {
350 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700351 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800352 }
353 /**
354 * Copy an allocation from an array. This variant is not type
355 * checked which allows an application to fill in structured
356 * data from an array.
357 *
358 * @param d the source data array
359 */
360 public void copyFromUnchecked(short[] d) {
361 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700362 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800363 }
364 /**
365 * Copy an allocation from an array. This variant is not type
366 * checked which allows an application to fill in structured
367 * data from an array.
368 *
369 * @param d the source data array
370 */
371 public void copyFromUnchecked(byte[] d) {
372 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700373 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800374 }
375 /**
376 * Copy an allocation from an array. This variant is not type
377 * checked which allows an application to fill in structured
378 * data from an array.
379 *
380 * @param d the source data array
381 */
382 public void copyFromUnchecked(float[] d) {
383 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700384 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800385 }
386
387 /**
388 * Copy an allocation from an array. This variant is type
389 * checked and will generate exceptions if the Allocation type
390 * is not a 32 bit integer type.
391 *
392 * @param d the source data array
393 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800394 public void copyFrom(int[] d) {
395 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700396 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800397 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800398
399 /**
400 * Copy an allocation from an array. This variant is type
401 * checked and will generate exceptions if the Allocation type
402 * is not a 16 bit integer type.
403 *
404 * @param d the source data array
405 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800406 public void copyFrom(short[] d) {
407 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700408 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800409 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800410
411 /**
412 * Copy an allocation from an array. This variant is type
413 * checked and will generate exceptions if the Allocation type
414 * is not a 8 bit integer type.
415 *
416 * @param d the source data array
417 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800418 public void copyFrom(byte[] d) {
419 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700420 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800421 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800422
423 /**
424 * Copy an allocation from an array. This variant is type
425 * checked and will generate exceptions if the Allocation type
426 * is not a 32 bit float type.
427 *
428 * @param d the source data array
429 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800430 public void copyFrom(float[] d) {
431 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700432 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800433 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800434
435 /**
436 * Copy an allocation from a bitmap. The height, width, and
437 * format of the bitmap must match the existing allocation.
438 *
439 * @param b the source bitmap
440 */
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800441 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800442 mRS.validate();
443 validateBitmapSize(b);
444 validateBitmapFormat(b);
Jason Sams4ef66502010-12-10 16:03:15 -0800445 mRS.nAllocationCopyFromBitmap(getID(), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700446 }
447
Jason Samsfa445b92011-01-07 17:00:07 -0800448 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800449 * This is only intended to be used by auto-generate code reflected from the
450 * renderscript script files.
451 *
452 * @param xoff
453 * @param fp
454 */
Jason Sams21b41032011-01-16 15:05:41 -0800455 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsa70f4162010-03-26 15:33:42 -0700456 int eSize = mType.mElement.getSizeBytes();
457 final byte[] data = fp.getData();
458
459 int count = data.length / eSize;
460 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800461 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700462 " not divisible by element size " + eSize + ".");
463 }
Jason Samsba862d12011-07-07 15:24:42 -0700464 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700465 }
466
Jason Samsfa445b92011-01-07 17:00:07 -0800467 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800468 * This is only intended to be used by auto-generate code reflected from the
469 * renderscript script files.
470 *
471 * @param xoff
472 * @param component_number
473 * @param fp
474 */
Jason Sams21b41032011-01-16 15:05:41 -0800475 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700476 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800477 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700478 }
479 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800480 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700481 }
482
483 final byte[] data = fp.getData();
484 int eSize = mType.mElement.mElements[component_number].getSizeBytes();
485
486 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800487 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700488 " does not match component size " + eSize + ".");
489 }
490
Jason Sams48fe5342011-07-08 13:52:30 -0700491 mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
Jason Samsba862d12011-07-07 15:24:42 -0700492 component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700493 }
494
Jason Sams768bc022009-09-21 19:41:04 -0700495 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800496 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700497 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800498 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700499 }
500 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800501 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700502 }
Jason Samsba862d12011-07-07 15:24:42 -0700503 if((off + count) > mCurrentCount) {
504 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700505 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700506 }
Jason Samsba862d12011-07-07 15:24:42 -0700507 if(len < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800508 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700509 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700510 }
511
Jason Samsf7086092011-01-12 13:28:37 -0800512 /**
513 * Generate a mipmap chain. Requires the type of the allocation
514 * include mipmaps.
515 *
516 * This function will generate a complete set of mipmaps from
517 * the top level lod and place them into the script memoryspace.
518 *
519 * If the allocation is also using other memory spaces a
520 * followup sync will be required.
521 */
522 public void generateMipmaps() {
523 mRS.nAllocationGenerateMipmaps(getID());
524 }
525
Jason Sams4fa3eed2011-01-19 15:44:38 -0800526 /**
527 * Copy part of an allocation from an array. This variant is
528 * not type checked which allows an application to fill in
529 * structured data from an array.
530 *
531 * @param off The offset of the first element to be copied.
532 * @param count The number of elements to be copied.
533 * @param d the source data array
534 */
535 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700536 int dataSize = mType.mElement.getSizeBytes() * count;
537 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700538 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700539 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800540 /**
541 * Copy part of an allocation from an array. This variant is
542 * not type checked which allows an application to fill in
543 * structured data from an array.
544 *
545 * @param off The offset of the first element to be copied.
546 * @param count The number of elements to be copied.
547 * @param d the source data array
548 */
549 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700550 int dataSize = mType.mElement.getSizeBytes() * count;
551 data1DChecks(off, count, d.length * 2, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700552 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700553 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800554 /**
555 * Copy part of an allocation from an array. This variant is
556 * not type checked which allows an application to fill in
557 * structured data from an array.
558 *
559 * @param off The offset of the first element to be copied.
560 * @param count The number of elements to be copied.
561 * @param d the source data array
562 */
563 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700564 int dataSize = mType.mElement.getSizeBytes() * count;
565 data1DChecks(off, count, d.length, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700566 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700567 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800568 /**
569 * Copy part of an allocation from an array. This variant is
570 * not type checked which allows an application to fill in
571 * structured data from an array.
572 *
573 * @param off The offset of the first element to be copied.
574 * @param count The number of elements to be copied.
575 * @param d the source data array
576 */
577 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700578 int dataSize = mType.mElement.getSizeBytes() * count;
579 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams48fe5342011-07-08 13:52:30 -0700580 mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700581 }
582
Jason Sams4fa3eed2011-01-19 15:44:38 -0800583 /**
584 * Copy part of an allocation from an array. This variant is
585 * type checked and will generate exceptions if the Allocation
586 * type is not a 32 bit integer type.
587 *
588 * @param off The offset of the first element to be copied.
589 * @param count The number of elements to be copied.
590 * @param d the source data array
591 */
Jason Samsb97b2512011-01-16 15:04:08 -0800592 public void copy1DRangeFrom(int off, int count, int[] d) {
593 validateIsInt32();
594 copy1DRangeFromUnchecked(off, count, d);
595 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800596
597 /**
598 * Copy part of an allocation from an array. This variant is
599 * type checked and will generate exceptions if the Allocation
600 * type is not a 16 bit integer type.
601 *
602 * @param off The offset of the first element to be copied.
603 * @param count The number of elements to be copied.
604 * @param d the source data array
605 */
Jason Samsb97b2512011-01-16 15:04:08 -0800606 public void copy1DRangeFrom(int off, int count, short[] d) {
607 validateIsInt16();
608 copy1DRangeFromUnchecked(off, count, d);
609 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800610
611 /**
612 * Copy part of an allocation from an array. This variant is
613 * type checked and will generate exceptions if the Allocation
614 * type is not a 8 bit integer type.
615 *
616 * @param off The offset of the first element to be copied.
617 * @param count The number of elements to be copied.
618 * @param d the source data array
619 */
Jason Samsb97b2512011-01-16 15:04:08 -0800620 public void copy1DRangeFrom(int off, int count, byte[] d) {
621 validateIsInt8();
622 copy1DRangeFromUnchecked(off, count, d);
623 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800624
625 /**
626 * Copy part of an allocation from an array. This variant is
627 * type checked and will generate exceptions if the Allocation
628 * type is not a 32 bit float type.
629 *
630 * @param off The offset of the first element to be copied.
631 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700632 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800633 */
Jason Samsb97b2512011-01-16 15:04:08 -0800634 public void copy1DRangeFrom(int off, int count, float[] d) {
635 validateIsFloat32();
636 copy1DRangeFromUnchecked(off, count, d);
637 }
638
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700639 /**
640 * Copy part of an allocation from another allocation.
641 *
642 * @param off The offset of the first element to be copied.
643 * @param count The number of elements to be copied.
644 * @param data the source data allocation.
645 * @param dataOff off The offset of the first element in data to
646 * be copied.
647 */
648 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
Jason Sams48fe5342011-07-08 13:52:30 -0700649 mRS.nAllocationData2D(getIDSafe(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700650 mSelectedLOD, mSelectedFace.mID,
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700651 count, 1, data.getID(), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700652 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700653 }
654
Jason Samsfb9f82c2011-01-12 14:53:25 -0800655 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -0700656 if (mAdaptedAllocation != null) {
657
658 } else {
659
660 if (xoff < 0 || yoff < 0) {
661 throw new RSIllegalArgumentException("Offset cannot be negative.");
662 }
663 if (h < 0 || w < 0) {
664 throw new RSIllegalArgumentException("Height or width cannot be negative.");
665 }
666 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
667 throw new RSIllegalArgumentException("Updated region larger than allocation.");
668 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800669 }
670 }
Jason Sams768bc022009-09-21 19:41:04 -0700671
Jason Samsf7086092011-01-12 13:28:37 -0800672 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700673 * Copy a rectangular region from the array into the allocation.
674 * The incoming array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -0800675 *
676 * @param xoff X offset of the region to update
677 * @param yoff Y offset of the region to update
678 * @param w Width of the incoming region to update
679 * @param h Height of the incoming region to update
680 * @param data to be placed into the allocation
681 */
682 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800683 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800684 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700685 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700686 w, h, data, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -0800687 }
688
Jason Samsf7086092011-01-12 13:28:37 -0800689 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800690 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800691 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700692 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700693 w, h, data, data.length * 2);
Jason Samsfa445b92011-01-07 17:00:07 -0800694 }
695
Jason Samsf7086092011-01-12 13:28:37 -0800696 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800697 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800698 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700699 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700700 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700701 }
702
Jason Samsf7086092011-01-12 13:28:37 -0800703 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800704 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800705 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700706 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
Jason Samsba862d12011-07-07 15:24:42 -0700707 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700708 }
709
Jason Samsf7086092011-01-12 13:28:37 -0800710 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700711 * Copy a rectangular region into the allocation from another
712 * allocation.
713 *
714 * @param xoff X offset of the region to update.
715 * @param yoff Y offset of the region to update.
716 * @param w Width of the incoming region to update.
717 * @param h Height of the incoming region to update.
718 * @param data source allocation.
719 * @param dataXoff X offset in data of the region to update.
720 * @param dataYoff Y offset in data of the region to update.
721 */
722 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
723 Allocation data, int dataXoff, int dataYoff) {
724 mRS.validate();
725 validate2DRange(xoff, yoff, w, h);
Jason Sams48fe5342011-07-08 13:52:30 -0700726 mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
Jason Samsba862d12011-07-07 15:24:42 -0700727 mSelectedLOD, mSelectedFace.mID,
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700728 w, h, data.getID(), dataXoff, dataYoff,
Jason Samsba862d12011-07-07 15:24:42 -0700729 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700730 }
731
732 /**
Jason Samsf7086092011-01-12 13:28:37 -0800733 * Copy a bitmap into an allocation. The height and width of
734 * the update will use the height and width of the incoming
735 * bitmap.
736 *
737 * @param xoff X offset of the region to update
738 * @param yoff Y offset of the region to update
739 * @param data the bitmap to be copied
740 */
741 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800742 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800743 validateBitmapFormat(data);
744 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Sams48fe5342011-07-08 13:52:30 -0700745 mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800746 }
747
748
Jason Sams48fe5342011-07-08 13:52:30 -0700749 /**
750 * Copy from the Allocation into a Bitmap. The bitmap must
751 * match the dimensions of the Allocation.
752 *
753 * @param b The bitmap to be set from the Allocation.
754 */
Jason Samsfa445b92011-01-07 17:00:07 -0800755 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800756 mRS.validate();
757 validateBitmapFormat(b);
758 validateBitmapSize(b);
Jason Samsfa445b92011-01-07 17:00:07 -0800759 mRS.nAllocationCopyToBitmap(getID(), b);
760 }
761
Jason Sams48fe5342011-07-08 13:52:30 -0700762 /**
763 * Copy from the Allocation into a byte array. The array must
764 * be at least as large as the Allocation. The allocation must
765 * be of an 8 bit elemental type.
766 *
767 * @param d The array to be set from the Allocation.
768 */
Jason Samsfa445b92011-01-07 17:00:07 -0800769 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800770 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -0800771 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800772 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700773 }
774
Jason Sams48fe5342011-07-08 13:52:30 -0700775 /**
776 * Copy from the Allocation into a short array. The array must
777 * be at least as large as the Allocation. The allocation must
778 * be of an 16 bit elemental type.
779 *
780 * @param d The array to be set from the Allocation.
781 */
Jason Samsfa445b92011-01-07 17:00:07 -0800782 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800783 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -0800784 mRS.validate();
785 mRS.nAllocationRead(getID(), d);
786 }
787
Jason Sams48fe5342011-07-08 13:52:30 -0700788 /**
789 * Copy from the Allocation into a int array. The array must be
790 * at least as large as the Allocation. The allocation must be
791 * of an 32 bit elemental type.
792 *
793 * @param d The array to be set from the Allocation.
794 */
Jason Samsfa445b92011-01-07 17:00:07 -0800795 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800796 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -0800797 mRS.validate();
798 mRS.nAllocationRead(getID(), d);
799 }
800
Jason Sams48fe5342011-07-08 13:52:30 -0700801 /**
802 * Copy from the Allocation into a float array. The array must
803 * be at least as large as the Allocation. The allocation must
804 * be of an 32 bit float elemental type.
805 *
806 * @param d The array to be set from the Allocation.
807 */
Jason Samsfa445b92011-01-07 17:00:07 -0800808 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800809 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -0800810 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800811 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700812 }
813
Jason Samsf7086092011-01-12 13:28:37 -0800814 /**
815 * Resize a 1D allocation. The contents of the allocation are
816 * preserved. If new elements are allocated objects are created
817 * with null contents and the new region is otherwise undefined.
818 *
819 * If the new region is smaller the references of any objects
820 * outside the new region will be released.
821 *
822 * A new type will be created with the new dimension.
823 *
824 * @param dimX The new size of the allocation.
825 */
Jason Sams31a7e422010-10-26 13:09:17 -0700826 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800827 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800828 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700829 }
Jason Sams06d69de2010-11-09 17:11:40 -0800830 mRS.nAllocationResize1D(getID(), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -0700831 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -0700832
Jason Sams06d69de2010-11-09 17:11:40 -0800833 int typeID = mRS.nAllocationGetType(getID());
Jason Sams31a7e422010-10-26 13:09:17 -0700834 mType = new Type(typeID, mRS);
835 mType.updateFromNative();
Jason Sams452a7662011-07-07 16:05:18 -0700836 updateCacheInfo(mType);
Jason Sams5edc6082010-10-05 13:32:49 -0700837 }
838
839 /*
840 public void resize(int dimX, int dimY) {
841 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800842 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700843 }
844 if (mType.getY() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800845 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700846 }
Jason Sams06d69de2010-11-09 17:11:40 -0800847 mRS.nAllocationResize2D(getID(), dimX, dimY);
Jason Sams5edc6082010-10-05 13:32:49 -0700848 }
849 */
Jason Sams40a29e82009-08-10 14:55:26 -0700850
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700851
Jason Samsb8c5a842009-07-31 20:40:47 -0700852
853 // creation
854
Jason Sams49a05d72010-12-29 14:31:29 -0800855 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -0700856 static {
857 mBitmapOptions.inScaled = false;
858 }
859
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800860 /**
861 *
862 * @param type renderscript type describing data layout
863 * @param mips specifies desired mipmap behaviour for the
864 * allocation
865 * @param usage bit field specifying how the allocation is
866 * utilized
867 */
868 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800869 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800870 if (type.getID() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800871 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -0700872 }
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800873 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800874 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800875 throw new RSRuntimeException("Allocation creation failed.");
876 }
Jason Sams5476b452010-12-08 16:14:36 -0800877 return new Allocation(id, rs, type, usage);
Jason Samsb8c5a842009-07-31 20:40:47 -0700878 }
879
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800880 /**
881 * Creates a renderscript allocation with the size specified by
882 * the type and no mipmaps generated by default
883 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800884 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800885 * @param type renderscript type describing data layout
886 * @param usage bit field specifying how the allocation is
887 * utilized
888 *
889 * @return allocation
890 */
Jason Samse5d37122010-12-16 00:33:33 -0800891 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
892 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
893 }
894
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800895 /**
896 * Creates a renderscript allocation for use by the script with
897 * the size specified by the type and no mipmaps generated by
898 * default
899 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800900 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800901 * @param type renderscript type describing data layout
902 *
903 * @return allocation
904 */
Jason Sams5476b452010-12-08 16:14:36 -0800905 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800906 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -0800907 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700908
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800909 /**
910 * Creates a renderscript allocation with a specified number of
911 * given elements
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 e describes what each element of an allocation is
915 * @param count specifies the number of element in the allocation
916 * @param usage bit field specifying how the allocation is
917 * utilized
918 *
919 * @return allocation
920 */
Jason Sams5476b452010-12-08 16:14:36 -0800921 static public Allocation createSized(RenderScript rs, Element e,
922 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800923 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -0700924 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800925 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -0700926 Type t = b.create();
927
Jason Samsd4b23b52010-12-13 15:32:35 -0800928 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800929 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800930 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700931 }
Jason Sams5476b452010-12-08 16:14:36 -0800932 return new Allocation(id, rs, t, usage);
933 }
934
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800935 /**
936 * Creates a renderscript allocation with a specified number of
937 * given elements
938 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800939 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800940 * @param e describes what each element of an allocation is
941 * @param count specifies the number of element in the allocation
942 *
943 * @return allocation
944 */
Jason Sams5476b452010-12-08 16:14:36 -0800945 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800946 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -0700947 }
948
Jason Sams49a05d72010-12-29 14:31:29 -0800949 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -0800950 final Bitmap.Config bc = b.getConfig();
951 if (bc == Bitmap.Config.ALPHA_8) {
952 return Element.A_8(rs);
953 }
954 if (bc == Bitmap.Config.ARGB_4444) {
955 return Element.RGBA_4444(rs);
956 }
957 if (bc == Bitmap.Config.ARGB_8888) {
958 return Element.RGBA_8888(rs);
959 }
960 if (bc == Bitmap.Config.RGB_565) {
961 return Element.RGB_565(rs);
962 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -0800963 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -0800964 }
965
Jason Sams49a05d72010-12-29 14:31:29 -0800966 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800967 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -0800968 Element e = elementFromBitmap(rs, b);
969 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d2010-12-06 15:59:59 -0800970 tb.setX(b.getWidth());
971 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -0800972 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -0800973 return tb.create();
974 }
975
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800976 /**
977 * Creates a renderscript allocation from a bitmap
978 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800979 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800980 * @param b bitmap source for the allocation data
981 * @param mips specifies desired mipmap behaviour for the
982 * allocation
983 * @param usage bit field specifying how the allocation is
984 * utilized
985 *
986 * @return renderscript allocation containing bitmap data
987 *
988 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800989 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800990 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800991 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800992 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800993 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -0800994
Jason Sams5476b452010-12-08 16:14:36 -0800995 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
996 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800997 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -0800998 }
Jason Sams5476b452010-12-08 16:14:36 -0800999 return new Allocation(id, rs, t, usage);
1000 }
1001
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001002 /**
1003 * Creates a non-mipmapped renderscript allocation to use as a
1004 * graphics texture
1005 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001006 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001007 * @param b bitmap source for the allocation data
1008 *
1009 * @return renderscript allocation containing bitmap data
1010 *
1011 */
Jason Sams6d8eb262010-12-15 01:41:00 -08001012 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
1013 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
1014 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -08001015 }
1016
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001017 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001018 * Creates a cubemap allocation from a bitmap containing the
1019 * horizontal list of cube faces. Each individual face must be
1020 * the same size and power of 2
1021 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001022 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001023 * @param b bitmap with cubemap faces layed out in the following
1024 * format: right, left, top, bottom, front, back
1025 * @param mips specifies desired mipmap behaviour for the cubemap
1026 * @param usage bit field specifying how the cubemap is utilized
1027 *
1028 * @return allocation containing cubemap data
1029 *
1030 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001031 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -08001032 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001033 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001034 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001035
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001036 int height = b.getHeight();
1037 int width = b.getWidth();
1038
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001039 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001040 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
1041 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001042 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001043 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001044 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001045 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001046 if (!isPow2) {
1047 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1048 }
1049
1050 Element e = elementFromBitmap(rs, b);
1051 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001052 tb.setX(height);
1053 tb.setY(height);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08001054 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08001055 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001056 Type t = tb.create();
1057
Jason Sams5476b452010-12-08 16:14:36 -08001058 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001059 if(id == 0) {
1060 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
1061 }
Jason Sams5476b452010-12-08 16:14:36 -08001062 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001063 }
1064
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001065 /**
1066 * Creates a non-mipmapped cubemap allocation for use as a
1067 * graphics texture from a bitmap containing the horizontal list
1068 * of cube faces. Each individual face must be the same size and
1069 * power of 2
1070 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001071 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001072 * @param b bitmap with cubemap faces layed out in the following
1073 * format: right, left, top, bottom, front, back
1074 *
1075 * @return allocation containing cubemap data
1076 *
1077 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001078 static public Allocation createCubemapFromBitmap(RenderScript rs,
1079 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08001080 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001081 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08001082 }
1083
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001084 /**
1085 * Creates a cubemap allocation from 6 bitmaps containing
1086 * the cube faces. All the faces must be the same size and
1087 * power of 2
1088 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001089 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001090 * @param xpos cubemap face in the positive x direction
1091 * @param xneg cubemap face in the negative x direction
1092 * @param ypos cubemap face in the positive y direction
1093 * @param yneg cubemap face in the negative y direction
1094 * @param zpos cubemap face in the positive z direction
1095 * @param zneg cubemap face in the negative z direction
1096 * @param mips specifies desired mipmap behaviour for the cubemap
1097 * @param usage bit field specifying how the cubemap is utilized
1098 *
1099 * @return allocation containing cubemap data
1100 *
1101 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001102 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1103 Bitmap xpos,
1104 Bitmap xneg,
1105 Bitmap ypos,
1106 Bitmap yneg,
1107 Bitmap zpos,
1108 Bitmap zneg,
1109 MipmapControl mips,
1110 int usage) {
1111 int height = xpos.getHeight();
1112 if (xpos.getWidth() != height ||
1113 xneg.getWidth() != height || xneg.getHeight() != height ||
1114 ypos.getWidth() != height || ypos.getHeight() != height ||
1115 yneg.getWidth() != height || yneg.getHeight() != height ||
1116 zpos.getWidth() != height || zpos.getHeight() != height ||
1117 zneg.getWidth() != height || zneg.getHeight() != height) {
1118 throw new RSIllegalArgumentException("Only square cube map faces supported");
1119 }
1120 boolean isPow2 = (height & (height - 1)) == 0;
1121 if (!isPow2) {
1122 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1123 }
1124
1125 Element e = elementFromBitmap(rs, xpos);
1126 Type.Builder tb = new Type.Builder(rs, e);
1127 tb.setX(height);
1128 tb.setY(height);
1129 tb.setFaces(true);
1130 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1131 Type t = tb.create();
1132 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1133
1134 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07001135 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001136 adapter.copyFrom(xpos);
1137 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1138 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001139 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001140 adapter.copyFrom(ypos);
1141 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1142 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001143 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001144 adapter.copyFrom(zpos);
1145 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1146 adapter.copyFrom(zneg);
1147
1148 return cubemap;
1149 }
1150
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001151 /**
1152 * Creates a non-mipmapped cubemap allocation for use as a
1153 * graphics texture from 6 bitmaps containing
1154 * the cube faces. All the faces must be the same size and
1155 * power of 2
1156 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001157 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001158 * @param xpos cubemap face in the positive x direction
1159 * @param xneg cubemap face in the negative x direction
1160 * @param ypos cubemap face in the positive y direction
1161 * @param yneg cubemap face in the negative y direction
1162 * @param zpos cubemap face in the positive z direction
1163 * @param zneg cubemap face in the negative z direction
1164 *
1165 * @return allocation containing cubemap data
1166 *
1167 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001168 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1169 Bitmap xpos,
1170 Bitmap xneg,
1171 Bitmap ypos,
1172 Bitmap yneg,
1173 Bitmap zpos,
1174 Bitmap zneg) {
1175 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1176 zpos, zneg, MipmapControl.MIPMAP_NONE,
1177 USAGE_GRAPHICS_TEXTURE);
1178 }
1179
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001180 /**
1181 * Creates a renderscript allocation from the bitmap referenced
1182 * by resource id
1183 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001184 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001185 * @param res application resources
1186 * @param id resource id to load the data from
1187 * @param mips specifies desired mipmap behaviour for the
1188 * allocation
1189 * @param usage bit field specifying how the allocation is
1190 * utilized
1191 *
1192 * @return renderscript allocation containing resource data
1193 *
1194 */
Jason Sams5476b452010-12-08 16:14:36 -08001195 static public Allocation createFromBitmapResource(RenderScript rs,
1196 Resources res,
1197 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001198 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001199 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001200
Jason Sams771bebb2009-12-07 12:40:12 -08001201 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001202 Bitmap b = BitmapFactory.decodeResource(res, id);
1203 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1204 b.recycle();
1205 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001206 }
1207
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001208 /**
1209 * Creates a non-mipmapped renderscript allocation to use as a
1210 * graphics texture from the bitmap referenced by resource id
1211 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001212 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001213 * @param res application resources
1214 * @param id resource id to load the data from
1215 *
1216 * @return renderscript allocation containing resource data
1217 *
1218 */
Jason Sams5476b452010-12-08 16:14:36 -08001219 static public Allocation createFromBitmapResource(RenderScript rs,
1220 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001221 int id) {
1222 return createFromBitmapResource(rs, res, id,
1223 MipmapControl.MIPMAP_NONE,
1224 USAGE_GRAPHICS_TEXTURE);
1225 }
1226
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001227 /**
1228 * Creates a renderscript allocation containing string data
1229 * encoded in UTF-8 format
1230 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001231 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001232 * @param str string to create the allocation from
1233 * @param usage bit field specifying how the allocaiton is
1234 * utilized
1235 *
1236 */
Jason Sams5476b452010-12-08 16:14:36 -08001237 static public Allocation createFromString(RenderScript rs,
1238 String str,
1239 int usage) {
1240 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001241 byte[] allocArray = null;
1242 try {
1243 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001244 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d2010-12-06 15:59:59 -08001245 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001246 return alloc;
1247 }
1248 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001249 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001250 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001251 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001252}
1253
1254