blob: 9ac1a00b9a8a91131c15222426f3d570259566b9 [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;
70
Jason Samsf7086092011-01-12 13:28:37 -080071 /**
72 * The usage of the allocation. These signal to renderscript
73 * where to place the allocation in memory.
74 *
75 * SCRIPT The allocation will be bound to and accessed by
76 * scripts.
77 */
Jason Sams5476b452010-12-08 16:14:36 -080078 public static final int USAGE_SCRIPT = 0x0001;
Jason Samsf7086092011-01-12 13:28:37 -080079
80 /**
81 * GRAPHICS_TEXTURE The allcation will be used as a texture
82 * source by one or more graphcics programs.
83 *
84 */
Jason Sams5476b452010-12-08 16:14:36 -080085 public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
Jason Samsf7086092011-01-12 13:28:37 -080086
87 /**
88 * GRAPHICS_VERTEX The allocation will be used as a graphics
89 * mesh.
90 *
91 */
Jason Sams5476b452010-12-08 16:14:36 -080092 public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
Jason Samsf7086092011-01-12 13:28:37 -080093
94
95 /**
96 * GRAPHICS_CONSTANTS The allocation will be used as the source
97 * of shader constants by one or more programs.
98 *
99 */
Jason Sams5476b452010-12-08 16:14:36 -0800100 public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
101
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700102 /**
103 * @hide
104 * USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
105 * target for offscreen rendering
106 *
107 */
108 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
109
Jason Sams43ee06852009-08-12 17:54:11 -0700110
Jason Samsf7086092011-01-12 13:28:37 -0800111 /**
112 * Controls mipmap behavior when using the bitmap creation and
113 * update functions.
114 */
Jason Sams4ef66502010-12-10 16:03:15 -0800115 public enum MipmapControl {
Jason Samsf7086092011-01-12 13:28:37 -0800116 /**
117 * No mipmaps will be generated and the type generated from the
118 * incoming bitmap will not contain additional LODs.
119 */
Jason Sams5476b452010-12-08 16:14:36 -0800120 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800121
122 /**
123 * A Full mipmap chain will be created in script memory. The
124 * type of the allocation will contain a full mipmap chain. On
125 * upload to graphics the full chain will be transfered.
126 */
Jason Sams5476b452010-12-08 16:14:36 -0800127 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800128
129 /**
130 * The type of the allocation will be the same as MIPMAP_NONE.
131 * It will not contain mipmaps. On upload to graphics the
132 * graphics copy of the allocation data will contain a full
133 * mipmap chain generated from the top level in script memory.
134 */
Jason Sams5476b452010-12-08 16:14:36 -0800135 MIPMAP_ON_SYNC_TO_TEXTURE(2);
136
137 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800138 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800139 mID = id;
140 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700141 }
142
Jason Sams5476b452010-12-08 16:14:36 -0800143 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700144 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800145 if ((usage & ~(USAGE_SCRIPT |
146 USAGE_GRAPHICS_TEXTURE |
147 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700148 USAGE_GRAPHICS_CONSTANTS |
149 USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800150 throw new RSIllegalArgumentException("Unknown usage specified.");
151 }
152 mType = t;
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700153 }
154
Jason Samsb97b2512011-01-16 15:04:08 -0800155 private void validateIsInt32() {
156 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
157 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
158 return;
159 }
160 throw new RSIllegalArgumentException(
161 "32 bit integer source does not match allocation type " + mType.mElement.mType);
162 }
163
164 private void validateIsInt16() {
165 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
166 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
167 return;
168 }
169 throw new RSIllegalArgumentException(
170 "16 bit integer source does not match allocation type " + mType.mElement.mType);
171 }
172
173 private void validateIsInt8() {
174 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
175 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
176 return;
177 }
178 throw new RSIllegalArgumentException(
179 "8 bit integer source does not match allocation type " + mType.mElement.mType);
180 }
181
182 private void validateIsFloat32() {
183 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
184 return;
185 }
186 throw new RSIllegalArgumentException(
187 "32 bit float source does not match allocation type " + mType.mElement.mType);
188 }
189
190 private void validateIsObject() {
191 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
192 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
193 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
194 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
195 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
196 (mType.mElement.mType == Element.DataType.RS_MESH) ||
197 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
198 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
199 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
200 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
201 return;
202 }
203 throw new RSIllegalArgumentException(
204 "Object source does not match allocation type " + mType.mElement.mType);
205 }
206
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700207 @Override
208 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800209 super.updateFromNative();
210 int typeID = mRS.nAllocationGetType(getID());
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700211 if(typeID != 0) {
212 mType = new Type(typeID, mRS);
213 mType.updateFromNative();
214 }
215 }
216
Jason Samsea87e962010-01-12 12:12:28 -0800217 public Type getType() {
218 return mType;
219 }
220
Jason Sams5476b452010-12-08 16:14:36 -0800221 public void syncAll(int srcLocation) {
222 switch (srcLocation) {
223 case USAGE_SCRIPT:
224 case USAGE_GRAPHICS_CONSTANTS:
225 case USAGE_GRAPHICS_TEXTURE:
226 case USAGE_GRAPHICS_VERTEX:
227 break;
228 default:
229 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
230 }
231 mRS.validate();
232 mRS.nAllocationSyncAll(getID(), srcLocation);
233 }
234
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800235 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800236 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800237 validateIsObject();
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800238 if (d.length != mType.getCount()) {
239 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
240 mType.getCount() + ", array length = " + d.length);
241 }
242 int i[] = new int[d.length];
243 for (int ct=0; ct < d.length; ct++) {
244 i[ct] = d[ct].getID();
245 }
Jason Samsed5bab92011-01-21 13:08:02 -0800246 copy1DRangeFromUnchecked(0, mType.getCount(), i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700247 }
248
Jason Samsfb9f82c2011-01-12 14:53:25 -0800249 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800250 Bitmap.Config bc = b.getConfig();
251 switch (bc) {
252 case ALPHA_8:
253 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
254 throw new RSIllegalArgumentException("Allocation kind is " +
255 mType.getElement().mKind + ", type " +
256 mType.getElement().mType +
257 " of " + mType.getElement().getSizeBytes() +
258 " bytes, passed bitmap was " + bc);
259 }
260 break;
261 case ARGB_8888:
262 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
263 (mType.getElement().getSizeBytes() != 4)) {
264 throw new RSIllegalArgumentException("Allocation kind is " +
265 mType.getElement().mKind + ", type " +
266 mType.getElement().mType +
267 " of " + mType.getElement().getSizeBytes() +
268 " bytes, passed bitmap was " + bc);
269 }
270 break;
271 case RGB_565:
272 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
273 (mType.getElement().getSizeBytes() != 2)) {
274 throw new RSIllegalArgumentException("Allocation kind is " +
275 mType.getElement().mKind + ", type " +
276 mType.getElement().mType +
277 " of " + mType.getElement().getSizeBytes() +
278 " bytes, passed bitmap was " + bc);
279 }
280 break;
281 case ARGB_4444:
282 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
283 (mType.getElement().getSizeBytes() != 2)) {
284 throw new RSIllegalArgumentException("Allocation kind is " +
285 mType.getElement().mKind + ", type " +
286 mType.getElement().mType +
287 " of " + mType.getElement().getSizeBytes() +
288 " bytes, passed bitmap was " + bc);
289 }
290 break;
291
292 }
Jason Sams4ef66502010-12-10 16:03:15 -0800293 }
294
Jason Samsfb9f82c2011-01-12 14:53:25 -0800295 private void validateBitmapSize(Bitmap b) {
296 if(mType.getX() != b.getWidth() ||
297 mType.getY() != b.getHeight()) {
298 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
299 }
300 }
301
Jason Sams4fa3eed2011-01-19 15:44:38 -0800302 /**
303 * Copy an allocation from an array. This variant is not type
304 * checked which allows an application to fill in structured
305 * data from an array.
306 *
307 * @param d the source data array
308 */
309 public void copyFromUnchecked(int[] d) {
310 mRS.validate();
311 copy1DRangeFromUnchecked(0, mType.getCount(), d);
312 }
313 /**
314 * Copy an allocation from an array. This variant is not type
315 * checked which allows an application to fill in structured
316 * data from an array.
317 *
318 * @param d the source data array
319 */
320 public void copyFromUnchecked(short[] d) {
321 mRS.validate();
322 copy1DRangeFromUnchecked(0, mType.getCount(), d);
323 }
324 /**
325 * Copy an allocation from an array. This variant is not type
326 * checked which allows an application to fill in structured
327 * data from an array.
328 *
329 * @param d the source data array
330 */
331 public void copyFromUnchecked(byte[] d) {
332 mRS.validate();
333 copy1DRangeFromUnchecked(0, mType.getCount(), d);
334 }
335 /**
336 * Copy an allocation from an array. This variant is not type
337 * checked which allows an application to fill in structured
338 * data from an array.
339 *
340 * @param d the source data array
341 */
342 public void copyFromUnchecked(float[] d) {
343 mRS.validate();
344 copy1DRangeFromUnchecked(0, mType.getCount(), d);
345 }
346
347 /**
348 * Copy an allocation from an array. This variant is type
349 * checked and will generate exceptions if the Allocation type
350 * is not a 32 bit integer type.
351 *
352 * @param d the source data array
353 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800354 public void copyFrom(int[] d) {
355 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800356 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800357 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800358
359 /**
360 * Copy an allocation from an array. This variant is type
361 * checked and will generate exceptions if the Allocation type
362 * is not a 16 bit integer type.
363 *
364 * @param d the source data array
365 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800366 public void copyFrom(short[] d) {
367 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800368 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800369 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800370
371 /**
372 * Copy an allocation from an array. This variant is type
373 * checked and will generate exceptions if the Allocation type
374 * is not a 8 bit integer type.
375 *
376 * @param d the source data array
377 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800378 public void copyFrom(byte[] d) {
379 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800380 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800381 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800382
383 /**
384 * Copy an allocation from an array. This variant is type
385 * checked and will generate exceptions if the Allocation type
386 * is not a 32 bit float type.
387 *
388 * @param d the source data array
389 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800390 public void copyFrom(float[] d) {
391 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800392 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800393 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800394
395 /**
396 * Copy an allocation from a bitmap. The height, width, and
397 * format of the bitmap must match the existing allocation.
398 *
399 * @param b the source bitmap
400 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800401 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800402 mRS.validate();
403 validateBitmapSize(b);
404 validateBitmapFormat(b);
Jason Sams4ef66502010-12-10 16:03:15 -0800405 mRS.nAllocationCopyFromBitmap(getID(), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700406 }
407
Jason Samsfa445b92011-01-07 17:00:07 -0800408 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800409 * This is only intended to be used by auto-generate code reflected from the
410 * renderscript script files.
411 *
412 * @param xoff
413 * @param fp
414 */
Jason Sams21b41032011-01-16 15:05:41 -0800415 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsa70f4162010-03-26 15:33:42 -0700416 int eSize = mType.mElement.getSizeBytes();
417 final byte[] data = fp.getData();
418
419 int count = data.length / eSize;
420 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800421 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700422 " not divisible by element size " + eSize + ".");
423 }
Jason Sams49bdaf02010-08-31 13:50:42 -0700424 data1DChecks(xoff, count, data.length, data.length);
Jason Sams49a05d72010-12-29 14:31:29 -0800425 mRS.nAllocationData1D(getID(), xoff, 0, count, data, data.length);
Jason Sams49bdaf02010-08-31 13:50:42 -0700426 }
427
Jason Samsfa445b92011-01-07 17:00:07 -0800428 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800429 * This is only intended to be used by auto-generate code reflected from the
430 * renderscript script files.
431 *
432 * @param xoff
433 * @param component_number
434 * @param fp
435 */
Jason Sams21b41032011-01-16 15:05:41 -0800436 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700437 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800438 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700439 }
440 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800441 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700442 }
443
444 final byte[] data = fp.getData();
445 int eSize = mType.mElement.mElements[component_number].getSizeBytes();
446
447 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800448 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700449 " does not match component size " + eSize + ".");
450 }
451
Jason Sams49a05d72010-12-29 14:31:29 -0800452 mRS.nAllocationElementData1D(getID(), xoff, 0, component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700453 }
454
Jason Sams768bc022009-09-21 19:41:04 -0700455 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800456 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700457 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800458 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700459 }
460 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800461 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700462 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800463 if((off + count) > mType.getCount()) {
464 throw new RSIllegalArgumentException("Overflow, Available count " + mType.getCount() +
Jason Samsa70f4162010-03-26 15:33:42 -0700465 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700466 }
Jason Sams768bc022009-09-21 19:41:04 -0700467 if((len) < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800468 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700469 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700470 }
471
Jason Samsf7086092011-01-12 13:28:37 -0800472 /**
473 * Generate a mipmap chain. Requires the type of the allocation
474 * include mipmaps.
475 *
476 * This function will generate a complete set of mipmaps from
477 * the top level lod and place them into the script memoryspace.
478 *
479 * If the allocation is also using other memory spaces a
480 * followup sync will be required.
481 */
482 public void generateMipmaps() {
483 mRS.nAllocationGenerateMipmaps(getID());
484 }
485
Jason Sams4fa3eed2011-01-19 15:44:38 -0800486 /**
487 * Copy part of an allocation from an array. This variant is
488 * not type checked which allows an application to fill in
489 * structured data from an array.
490 *
491 * @param off The offset of the first element to be copied.
492 * @param count The number of elements to be copied.
493 * @param d the source data array
494 */
495 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700496 int dataSize = mType.mElement.getSizeBytes() * count;
497 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800498 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700499 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800500 /**
501 * Copy part of an allocation from an array. This variant is
502 * not type checked which allows an application to fill in
503 * structured data from an array.
504 *
505 * @param off The offset of the first element to be copied.
506 * @param count The number of elements to be copied.
507 * @param d the source data array
508 */
509 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700510 int dataSize = mType.mElement.getSizeBytes() * count;
511 data1DChecks(off, count, d.length * 2, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800512 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700513 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800514 /**
515 * Copy part of an allocation from an array. This variant is
516 * not type checked which allows an application to fill in
517 * structured data from an array.
518 *
519 * @param off The offset of the first element to be copied.
520 * @param count The number of elements to be copied.
521 * @param d the source data array
522 */
523 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700524 int dataSize = mType.mElement.getSizeBytes() * count;
525 data1DChecks(off, count, d.length, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800526 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700527 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800528 /**
529 * Copy part of an allocation from an array. This variant is
530 * not type checked which allows an application to fill in
531 * structured data from an array.
532 *
533 * @param off The offset of the first element to be copied.
534 * @param count The number of elements to be copied.
535 * @param d the source data array
536 */
537 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700538 int dataSize = mType.mElement.getSizeBytes() * count;
539 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800540 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700541 }
542
Jason Sams4fa3eed2011-01-19 15:44:38 -0800543 /**
544 * Copy part of an allocation from an array. This variant is
545 * type checked and will generate exceptions if the Allocation
546 * type is not a 32 bit integer type.
547 *
548 * @param off The offset of the first element to be copied.
549 * @param count The number of elements to be copied.
550 * @param d the source data array
551 */
Jason Samsb97b2512011-01-16 15:04:08 -0800552 public void copy1DRangeFrom(int off, int count, int[] d) {
553 validateIsInt32();
554 copy1DRangeFromUnchecked(off, count, d);
555 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800556
557 /**
558 * Copy part of an allocation from an array. This variant is
559 * type checked and will generate exceptions if the Allocation
560 * type is not a 16 bit integer type.
561 *
562 * @param off The offset of the first element to be copied.
563 * @param count The number of elements to be copied.
564 * @param d the source data array
565 */
Jason Samsb97b2512011-01-16 15:04:08 -0800566 public void copy1DRangeFrom(int off, int count, short[] d) {
567 validateIsInt16();
568 copy1DRangeFromUnchecked(off, count, d);
569 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800570
571 /**
572 * Copy part of an allocation from an array. This variant is
573 * type checked and will generate exceptions if the Allocation
574 * type is not a 8 bit integer type.
575 *
576 * @param off The offset of the first element to be copied.
577 * @param count The number of elements to be copied.
578 * @param d the source data array
579 */
Jason Samsb97b2512011-01-16 15:04:08 -0800580 public void copy1DRangeFrom(int off, int count, byte[] d) {
581 validateIsInt8();
582 copy1DRangeFromUnchecked(off, count, d);
583 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800584
585 /**
586 * Copy part of an allocation from an array. This variant is
587 * type checked and will generate exceptions if the Allocation
588 * type is not a 32 bit float type.
589 *
590 * @param off The offset of the first element to be copied.
591 * @param count The number of elements to be copied.
592 * @param d the source data array
593 */
Jason Samsb97b2512011-01-16 15:04:08 -0800594 public void copy1DRangeFrom(int off, int count, float[] d) {
595 validateIsFloat32();
596 copy1DRangeFromUnchecked(off, count, d);
597 }
598
Jason Samsfb9f82c2011-01-12 14:53:25 -0800599 private void validate2DRange(int xoff, int yoff, int w, int h) {
600 if (xoff < 0 || yoff < 0) {
601 throw new RSIllegalArgumentException("Offset cannot be negative.");
602 }
603 if (h < 0 || w < 0) {
604 throw new RSIllegalArgumentException("Height or width cannot be negative.");
605 }
606 if ((xoff + w) > mType.mDimX ||
607 (yoff + h) > mType.mDimY) {
608 throw new RSIllegalArgumentException("Updated region larger than allocation.");
609 }
610 }
Jason Sams768bc022009-09-21 19:41:04 -0700611
Jason Samsf7086092011-01-12 13:28:37 -0800612 /**
613 * Copy a rectanglular region from the array into the
614 * allocation. The incoming array is assumed to be tightly
615 * packed.
616 *
617 * @param xoff X offset of the region to update
618 * @param yoff Y offset of the region to update
619 * @param w Width of the incoming region to update
620 * @param h Height of the incoming region to update
621 * @param data to be placed into the allocation
622 */
623 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800624 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800625 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800626 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -0800627 }
628
Jason Samsf7086092011-01-12 13:28:37 -0800629 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800630 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800631 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800632 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 2);
Jason Samsfa445b92011-01-07 17:00:07 -0800633 }
634
Jason Samsf7086092011-01-12 13:28:37 -0800635 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800636 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800637 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800638 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700639 }
640
Jason Samsf7086092011-01-12 13:28:37 -0800641 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800642 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800643 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800644 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700645 }
646
Jason Samsf7086092011-01-12 13:28:37 -0800647 /**
648 * Copy a bitmap into an allocation. The height and width of
649 * the update will use the height and width of the incoming
650 * bitmap.
651 *
652 * @param xoff X offset of the region to update
653 * @param yoff Y offset of the region to update
654 * @param data the bitmap to be copied
655 */
656 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800657 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800658 validateBitmapFormat(data);
659 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Samsf7086092011-01-12 13:28:37 -0800660 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800661 }
662
663
664 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800665 mRS.validate();
666 validateBitmapFormat(b);
667 validateBitmapSize(b);
Jason Samsfa445b92011-01-07 17:00:07 -0800668 mRS.nAllocationCopyToBitmap(getID(), b);
669 }
670
671 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800672 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -0800673 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800674 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700675 }
676
Jason Samsfa445b92011-01-07 17:00:07 -0800677 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800678 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -0800679 mRS.validate();
680 mRS.nAllocationRead(getID(), d);
681 }
682
683 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800684 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -0800685 mRS.validate();
686 mRS.nAllocationRead(getID(), d);
687 }
688
689 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800690 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -0800691 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800692 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700693 }
694
Jason Samsf7086092011-01-12 13:28:37 -0800695 /**
696 * Resize a 1D allocation. The contents of the allocation are
697 * preserved. If new elements are allocated objects are created
698 * with null contents and the new region is otherwise undefined.
699 *
700 * If the new region is smaller the references of any objects
701 * outside the new region will be released.
702 *
703 * A new type will be created with the new dimension.
704 *
705 * @param dimX The new size of the allocation.
706 */
Jason Sams31a7e422010-10-26 13:09:17 -0700707 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800708 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800709 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700710 }
Jason Sams06d69de2010-11-09 17:11:40 -0800711 mRS.nAllocationResize1D(getID(), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -0700712 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -0700713
Jason Sams06d69de2010-11-09 17:11:40 -0800714 int typeID = mRS.nAllocationGetType(getID());
Jason Sams31a7e422010-10-26 13:09:17 -0700715 mType = new Type(typeID, mRS);
716 mType.updateFromNative();
Jason Sams5edc6082010-10-05 13:32:49 -0700717 }
718
719 /*
720 public void resize(int dimX, int dimY) {
721 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800722 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700723 }
724 if (mType.getY() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800725 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700726 }
Jason Sams06d69de2010-11-09 17:11:40 -0800727 mRS.nAllocationResize2D(getID(), dimX, dimY);
Jason Sams5edc6082010-10-05 13:32:49 -0700728 }
729 */
Jason Sams40a29e82009-08-10 14:55:26 -0700730
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700731
Jason Samsb8c5a842009-07-31 20:40:47 -0700732
733 // creation
734
Jason Sams49a05d72010-12-29 14:31:29 -0800735 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -0700736 static {
737 mBitmapOptions.inScaled = false;
738 }
739
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800740 /**
741 *
742 * @param type renderscript type describing data layout
743 * @param mips specifies desired mipmap behaviour for the
744 * allocation
745 * @param usage bit field specifying how the allocation is
746 * utilized
747 */
748 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800749 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800750 if (type.getID() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800751 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -0700752 }
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800753 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800754 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800755 throw new RSRuntimeException("Allocation creation failed.");
756 }
Jason Sams5476b452010-12-08 16:14:36 -0800757 return new Allocation(id, rs, type, usage);
Jason Samsb8c5a842009-07-31 20:40:47 -0700758 }
759
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800760 /**
761 * Creates a renderscript allocation with the size specified by
762 * the type and no mipmaps generated by default
763 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800764 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800765 * @param type renderscript type describing data layout
766 * @param usage bit field specifying how the allocation is
767 * utilized
768 *
769 * @return allocation
770 */
Jason Samse5d37122010-12-16 00:33:33 -0800771 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
772 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
773 }
774
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800775 /**
776 * Creates a renderscript allocation for use by the script with
777 * the size specified by the type and no mipmaps generated by
778 * default
779 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800780 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800781 * @param type renderscript type describing data layout
782 *
783 * @return allocation
784 */
Jason Sams5476b452010-12-08 16:14:36 -0800785 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800786 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -0800787 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700788
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800789 /**
790 * Creates a renderscript allocation with a specified number of
791 * given elements
792 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800793 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800794 * @param e describes what each element of an allocation is
795 * @param count specifies the number of element in the allocation
796 * @param usage bit field specifying how the allocation is
797 * utilized
798 *
799 * @return allocation
800 */
Jason Sams5476b452010-12-08 16:14:36 -0800801 static public Allocation createSized(RenderScript rs, Element e,
802 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800803 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -0700804 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800805 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -0700806 Type t = b.create();
807
Jason Samsd4b23b52010-12-13 15:32:35 -0800808 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800809 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800810 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700811 }
Jason Sams5476b452010-12-08 16:14:36 -0800812 return new Allocation(id, rs, t, usage);
813 }
814
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800815 /**
816 * Creates a renderscript allocation with a specified number of
817 * given elements
818 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800819 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800820 * @param e describes what each element of an allocation is
821 * @param count specifies the number of element in the allocation
822 *
823 * @return allocation
824 */
Jason Sams5476b452010-12-08 16:14:36 -0800825 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800826 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -0700827 }
828
Jason Sams49a05d72010-12-29 14:31:29 -0800829 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -0800830 final Bitmap.Config bc = b.getConfig();
831 if (bc == Bitmap.Config.ALPHA_8) {
832 return Element.A_8(rs);
833 }
834 if (bc == Bitmap.Config.ARGB_4444) {
835 return Element.RGBA_4444(rs);
836 }
837 if (bc == Bitmap.Config.ARGB_8888) {
838 return Element.RGBA_8888(rs);
839 }
840 if (bc == Bitmap.Config.RGB_565) {
841 return Element.RGB_565(rs);
842 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -0800843 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -0800844 }
845
Jason Sams49a05d72010-12-29 14:31:29 -0800846 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800847 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -0800848 Element e = elementFromBitmap(rs, b);
849 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800850 tb.setX(b.getWidth());
851 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -0800852 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -0800853 return tb.create();
854 }
855
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800856 /**
857 * Creates a renderscript allocation from a bitmap
858 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800859 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800860 * @param b bitmap source for the allocation data
861 * @param mips specifies desired mipmap behaviour for the
862 * allocation
863 * @param usage bit field specifying how the allocation is
864 * utilized
865 *
866 * @return renderscript allocation containing bitmap data
867 *
868 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800869 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800870 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800871 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800872 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800873 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -0800874
Jason Sams5476b452010-12-08 16:14:36 -0800875 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
876 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800877 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -0800878 }
Jason Sams5476b452010-12-08 16:14:36 -0800879 return new Allocation(id, rs, t, usage);
880 }
881
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800882 /**
883 * Creates a non-mipmapped renderscript allocation to use as a
884 * graphics texture
885 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800886 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800887 * @param b bitmap source for the allocation data
888 *
889 * @return renderscript allocation containing bitmap data
890 *
891 */
Jason Sams6d8eb262010-12-15 01:41:00 -0800892 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
893 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
894 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -0800895 }
896
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800897 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800898 * Creates a cubemap allocation from a bitmap containing the
899 * horizontal list of cube faces. Each individual face must be
900 * the same size and power of 2
901 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800902 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800903 * @param b bitmap with cubemap faces layed out in the following
904 * format: right, left, top, bottom, front, back
905 * @param mips specifies desired mipmap behaviour for the cubemap
906 * @param usage bit field specifying how the cubemap is utilized
907 *
908 * @return allocation containing cubemap data
909 *
910 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800911 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800912 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800913 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800914 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800915
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800916 int height = b.getHeight();
917 int width = b.getWidth();
918
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800919 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800920 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
921 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800922 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -0800923 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800924 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800925 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800926 if (!isPow2) {
927 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
928 }
929
930 Element e = elementFromBitmap(rs, b);
931 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800932 tb.setX(height);
933 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800934 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -0800935 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800936 Type t = tb.create();
937
Jason Sams5476b452010-12-08 16:14:36 -0800938 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800939 if(id == 0) {
940 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
941 }
Jason Sams5476b452010-12-08 16:14:36 -0800942 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800943 }
944
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800945 /**
946 * Creates a non-mipmapped cubemap allocation for use as a
947 * graphics texture from a bitmap containing the horizontal list
948 * of cube faces. Each individual face must be the same size and
949 * power of 2
950 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800951 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800952 * @param b bitmap with cubemap faces layed out in the following
953 * format: right, left, top, bottom, front, back
954 *
955 * @return allocation containing cubemap data
956 *
957 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -0800958 static public Allocation createCubemapFromBitmap(RenderScript rs,
959 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -0800960 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800961 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -0800962 }
963
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800964 /**
965 * Creates a cubemap allocation from 6 bitmaps containing
966 * the cube faces. All the faces must be the same size and
967 * power of 2
968 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800969 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800970 * @param xpos cubemap face in the positive x direction
971 * @param xneg cubemap face in the negative x direction
972 * @param ypos cubemap face in the positive y direction
973 * @param yneg cubemap face in the negative y direction
974 * @param zpos cubemap face in the positive z direction
975 * @param zneg cubemap face in the negative z direction
976 * @param mips specifies desired mipmap behaviour for the cubemap
977 * @param usage bit field specifying how the cubemap is utilized
978 *
979 * @return allocation containing cubemap data
980 *
981 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -0800982 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
983 Bitmap xpos,
984 Bitmap xneg,
985 Bitmap ypos,
986 Bitmap yneg,
987 Bitmap zpos,
988 Bitmap zneg,
989 MipmapControl mips,
990 int usage) {
991 int height = xpos.getHeight();
992 if (xpos.getWidth() != height ||
993 xneg.getWidth() != height || xneg.getHeight() != height ||
994 ypos.getWidth() != height || ypos.getHeight() != height ||
995 yneg.getWidth() != height || yneg.getHeight() != height ||
996 zpos.getWidth() != height || zpos.getHeight() != height ||
997 zneg.getWidth() != height || zneg.getHeight() != height) {
998 throw new RSIllegalArgumentException("Only square cube map faces supported");
999 }
1000 boolean isPow2 = (height & (height - 1)) == 0;
1001 if (!isPow2) {
1002 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1003 }
1004
1005 Element e = elementFromBitmap(rs, xpos);
1006 Type.Builder tb = new Type.Builder(rs, e);
1007 tb.setX(height);
1008 tb.setY(height);
1009 tb.setFaces(true);
1010 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1011 Type t = tb.create();
1012 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1013
1014 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
1015 adapter.setFace(Type.CubemapFace.POSITVE_X);
1016 adapter.copyFrom(xpos);
1017 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1018 adapter.copyFrom(xneg);
1019 adapter.setFace(Type.CubemapFace.POSITVE_Y);
1020 adapter.copyFrom(ypos);
1021 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1022 adapter.copyFrom(yneg);
1023 adapter.setFace(Type.CubemapFace.POSITVE_Z);
1024 adapter.copyFrom(zpos);
1025 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1026 adapter.copyFrom(zneg);
1027
1028 return cubemap;
1029 }
1030
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001031 /**
1032 * Creates a non-mipmapped cubemap allocation for use as a
1033 * graphics texture from 6 bitmaps containing
1034 * the cube faces. All the faces must be the same size and
1035 * power of 2
1036 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001037 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001038 * @param xpos cubemap face in the positive x direction
1039 * @param xneg cubemap face in the negative x direction
1040 * @param ypos cubemap face in the positive y direction
1041 * @param yneg cubemap face in the negative y direction
1042 * @param zpos cubemap face in the positive z direction
1043 * @param zneg cubemap face in the negative z direction
1044 *
1045 * @return allocation containing cubemap data
1046 *
1047 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001048 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1049 Bitmap xpos,
1050 Bitmap xneg,
1051 Bitmap ypos,
1052 Bitmap yneg,
1053 Bitmap zpos,
1054 Bitmap zneg) {
1055 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1056 zpos, zneg, MipmapControl.MIPMAP_NONE,
1057 USAGE_GRAPHICS_TEXTURE);
1058 }
1059
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001060 /**
1061 * Creates a renderscript allocation from the bitmap referenced
1062 * by resource id
1063 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001064 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001065 * @param res application resources
1066 * @param id resource id to load the data from
1067 * @param mips specifies desired mipmap behaviour for the
1068 * allocation
1069 * @param usage bit field specifying how the allocation is
1070 * utilized
1071 *
1072 * @return renderscript allocation containing resource data
1073 *
1074 */
Jason Sams5476b452010-12-08 16:14:36 -08001075 static public Allocation createFromBitmapResource(RenderScript rs,
1076 Resources res,
1077 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001078 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001079 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001080
Jason Sams771bebb2009-12-07 12:40:12 -08001081 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001082 Bitmap b = BitmapFactory.decodeResource(res, id);
1083 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1084 b.recycle();
1085 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001086 }
1087
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001088 /**
1089 * Creates a non-mipmapped renderscript allocation to use as a
1090 * graphics texture from the bitmap referenced by resource id
1091 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001092 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001093 * @param res application resources
1094 * @param id resource id to load the data from
1095 *
1096 * @return renderscript allocation containing resource data
1097 *
1098 */
Jason Sams5476b452010-12-08 16:14:36 -08001099 static public Allocation createFromBitmapResource(RenderScript rs,
1100 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001101 int id) {
1102 return createFromBitmapResource(rs, res, id,
1103 MipmapControl.MIPMAP_NONE,
1104 USAGE_GRAPHICS_TEXTURE);
1105 }
1106
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001107 /**
1108 * Creates a renderscript allocation containing string data
1109 * encoded in UTF-8 format
1110 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001111 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001112 * @param str string to create the allocation from
1113 * @param usage bit field specifying how the allocaiton is
1114 * utilized
1115 *
1116 */
Jason Sams5476b452010-12-08 16:14:36 -08001117 static public Allocation createFromString(RenderScript rs,
1118 String str,
1119 int usage) {
1120 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001121 byte[] allocArray = null;
1122 try {
1123 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001124 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001125 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001126 return alloc;
1127 }
1128 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001129 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001130 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001131 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001132}
1133
1134