blob: 44cdc1cd45420e9204cce2e93c37cb1ab425fdff [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 Samsba862d12011-07-07 15:24:42 -0700158
Jason Sams5476b452010-12-08 16:14:36 -0800159 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700160 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800161 if ((usage & ~(USAGE_SCRIPT |
162 USAGE_GRAPHICS_TEXTURE |
163 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700164 USAGE_GRAPHICS_CONSTANTS |
165 USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800166 throw new RSIllegalArgumentException("Unknown usage specified.");
167 }
168 mType = t;
Jason Samsba862d12011-07-07 15:24:42 -0700169
170 mCurrentDimX = t.getX();
171 mCurrentDimY = t.getY();
172 mCurrentDimZ = t.getZ();
173 mCurrentCount = mCurrentDimX;
174 if (mCurrentDimY > 1) {
175 mCurrentCount *= mCurrentDimY;
176 }
177 if (mCurrentDimZ > 1) {
178 mCurrentCount *= mCurrentDimZ;
179 }
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700180 }
181
Jason Samsb97b2512011-01-16 15:04:08 -0800182 private void validateIsInt32() {
183 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
184 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
185 return;
186 }
187 throw new RSIllegalArgumentException(
188 "32 bit integer source does not match allocation type " + mType.mElement.mType);
189 }
190
191 private void validateIsInt16() {
192 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
193 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
194 return;
195 }
196 throw new RSIllegalArgumentException(
197 "16 bit integer source does not match allocation type " + mType.mElement.mType);
198 }
199
200 private void validateIsInt8() {
201 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
202 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
203 return;
204 }
205 throw new RSIllegalArgumentException(
206 "8 bit integer source does not match allocation type " + mType.mElement.mType);
207 }
208
209 private void validateIsFloat32() {
210 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
211 return;
212 }
213 throw new RSIllegalArgumentException(
214 "32 bit float source does not match allocation type " + mType.mElement.mType);
215 }
216
217 private void validateIsObject() {
218 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
219 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
220 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
221 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
222 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
223 (mType.mElement.mType == Element.DataType.RS_MESH) ||
224 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
225 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
226 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
227 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
228 return;
229 }
230 throw new RSIllegalArgumentException(
231 "Object source does not match allocation type " + mType.mElement.mType);
232 }
233
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700234 @Override
235 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800236 super.updateFromNative();
237 int typeID = mRS.nAllocationGetType(getID());
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700238 if(typeID != 0) {
239 mType = new Type(typeID, mRS);
240 mType.updateFromNative();
241 }
242 }
243
Jason Samsea87e962010-01-12 12:12:28 -0800244 public Type getType() {
245 return mType;
246 }
247
Jason Sams5476b452010-12-08 16:14:36 -0800248 public void syncAll(int srcLocation) {
249 switch (srcLocation) {
250 case USAGE_SCRIPT:
251 case USAGE_GRAPHICS_CONSTANTS:
252 case USAGE_GRAPHICS_TEXTURE:
253 case USAGE_GRAPHICS_VERTEX:
254 break;
255 default:
256 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
257 }
258 mRS.validate();
259 mRS.nAllocationSyncAll(getID(), srcLocation);
260 }
261
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800262 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800263 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800264 validateIsObject();
Jason Samsba862d12011-07-07 15:24:42 -0700265 if (d.length != mCurrentCount) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800266 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
Jason Samsba862d12011-07-07 15:24:42 -0700267 mCurrentCount + ", array length = " + d.length);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800268 }
269 int i[] = new int[d.length];
270 for (int ct=0; ct < d.length; ct++) {
271 i[ct] = d[ct].getID();
272 }
Jason Samsba862d12011-07-07 15:24:42 -0700273 copy1DRangeFromUnchecked(0, mCurrentCount, i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700274 }
275
Jason Samsfb9f82c2011-01-12 14:53:25 -0800276 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800277 Bitmap.Config bc = b.getConfig();
278 switch (bc) {
279 case ALPHA_8:
280 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
281 throw new RSIllegalArgumentException("Allocation kind is " +
282 mType.getElement().mKind + ", type " +
283 mType.getElement().mType +
284 " of " + mType.getElement().getSizeBytes() +
285 " bytes, passed bitmap was " + bc);
286 }
287 break;
288 case ARGB_8888:
289 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
290 (mType.getElement().getSizeBytes() != 4)) {
291 throw new RSIllegalArgumentException("Allocation kind is " +
292 mType.getElement().mKind + ", type " +
293 mType.getElement().mType +
294 " of " + mType.getElement().getSizeBytes() +
295 " bytes, passed bitmap was " + bc);
296 }
297 break;
298 case RGB_565:
299 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
300 (mType.getElement().getSizeBytes() != 2)) {
301 throw new RSIllegalArgumentException("Allocation kind is " +
302 mType.getElement().mKind + ", type " +
303 mType.getElement().mType +
304 " of " + mType.getElement().getSizeBytes() +
305 " bytes, passed bitmap was " + bc);
306 }
307 break;
308 case ARGB_4444:
309 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
310 (mType.getElement().getSizeBytes() != 2)) {
311 throw new RSIllegalArgumentException("Allocation kind is " +
312 mType.getElement().mKind + ", type " +
313 mType.getElement().mType +
314 " of " + mType.getElement().getSizeBytes() +
315 " bytes, passed bitmap was " + bc);
316 }
317 break;
318
319 }
Jason Sams4ef66502010-12-10 16:03:15 -0800320 }
321
Jason Samsfb9f82c2011-01-12 14:53:25 -0800322 private void validateBitmapSize(Bitmap b) {
Jason Samsba862d12011-07-07 15:24:42 -0700323 if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800324 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
325 }
326 }
327
Jason Sams4fa3eed2011-01-19 15:44:38 -0800328 /**
329 * Copy an allocation from an array. This variant is not type
330 * checked which allows an application to fill in structured
331 * data from an array.
332 *
333 * @param d the source data array
334 */
335 public void copyFromUnchecked(int[] d) {
336 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700337 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800338 }
339 /**
340 * Copy an allocation from an array. This variant is not type
341 * checked which allows an application to fill in structured
342 * data from an array.
343 *
344 * @param d the source data array
345 */
346 public void copyFromUnchecked(short[] d) {
347 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700348 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800349 }
350 /**
351 * Copy an allocation from an array. This variant is not type
352 * checked which allows an application to fill in structured
353 * data from an array.
354 *
355 * @param d the source data array
356 */
357 public void copyFromUnchecked(byte[] d) {
358 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700359 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800360 }
361 /**
362 * Copy an allocation from an array. This variant is not type
363 * checked which allows an application to fill in structured
364 * data from an array.
365 *
366 * @param d the source data array
367 */
368 public void copyFromUnchecked(float[] d) {
369 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700370 copy1DRangeFromUnchecked(0, mCurrentCount, d);
Jason Sams4fa3eed2011-01-19 15:44:38 -0800371 }
372
373 /**
374 * Copy an allocation from an array. This variant is type
375 * checked and will generate exceptions if the Allocation type
376 * is not a 32 bit integer type.
377 *
378 * @param d the source data array
379 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800380 public void copyFrom(int[] d) {
381 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700382 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800383 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800384
385 /**
386 * Copy an allocation from an array. This variant is type
387 * checked and will generate exceptions if the Allocation type
388 * is not a 16 bit integer type.
389 *
390 * @param d the source data array
391 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800392 public void copyFrom(short[] d) {
393 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700394 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800395 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800396
397 /**
398 * Copy an allocation from an array. This variant is type
399 * checked and will generate exceptions if the Allocation type
400 * is not a 8 bit integer type.
401 *
402 * @param d the source data array
403 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800404 public void copyFrom(byte[] d) {
405 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700406 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800407 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800408
409 /**
410 * Copy an allocation from an array. This variant is type
411 * checked and will generate exceptions if the Allocation type
412 * is not a 32 bit float type.
413 *
414 * @param d the source data array
415 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800416 public void copyFrom(float[] d) {
417 mRS.validate();
Jason Samsba862d12011-07-07 15:24:42 -0700418 copy1DRangeFrom(0, mCurrentCount, d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800419 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800420
421 /**
422 * Copy an allocation from a bitmap. The height, width, and
423 * format of the bitmap must match the existing allocation.
424 *
425 * @param b the source bitmap
426 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800427 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800428 mRS.validate();
429 validateBitmapSize(b);
430 validateBitmapFormat(b);
Jason Sams4ef66502010-12-10 16:03:15 -0800431 mRS.nAllocationCopyFromBitmap(getID(), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700432 }
433
Jason Samsfa445b92011-01-07 17:00:07 -0800434 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800435 * This is only intended to be used by auto-generate code reflected from the
436 * renderscript script files.
437 *
438 * @param xoff
439 * @param fp
440 */
Jason Sams21b41032011-01-16 15:05:41 -0800441 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsa70f4162010-03-26 15:33:42 -0700442 int eSize = mType.mElement.getSizeBytes();
443 final byte[] data = fp.getData();
444
445 int count = data.length / eSize;
446 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800447 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700448 " not divisible by element size " + eSize + ".");
449 }
Jason Samsba862d12011-07-07 15:24:42 -0700450 copy1DRangeFromUnchecked(xoff, count, data);
Jason Sams49bdaf02010-08-31 13:50:42 -0700451 }
452
Jason Samsfa445b92011-01-07 17:00:07 -0800453 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800454 * This is only intended to be used by auto-generate code reflected from the
455 * renderscript script files.
456 *
457 * @param xoff
458 * @param component_number
459 * @param fp
460 */
Jason Sams21b41032011-01-16 15:05:41 -0800461 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700462 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800463 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700464 }
465 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800466 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700467 }
468
469 final byte[] data = fp.getData();
470 int eSize = mType.mElement.mElements[component_number].getSizeBytes();
471
472 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800473 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700474 " does not match component size " + eSize + ".");
475 }
476
Jason Samsba862d12011-07-07 15:24:42 -0700477 mRS.nAllocationElementData1D(getID(), xoff, mSelectedLOD,
478 component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700479 }
480
Jason Sams768bc022009-09-21 19:41:04 -0700481 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800482 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700483 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800484 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700485 }
486 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800487 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700488 }
Jason Samsba862d12011-07-07 15:24:42 -0700489 if((off + count) > mCurrentCount) {
490 throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
Jason Samsa70f4162010-03-26 15:33:42 -0700491 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700492 }
Jason Samsba862d12011-07-07 15:24:42 -0700493 if(len < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800494 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700495 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700496 }
497
Jason Samsf7086092011-01-12 13:28:37 -0800498 /**
499 * Generate a mipmap chain. Requires the type of the allocation
500 * include mipmaps.
501 *
502 * This function will generate a complete set of mipmaps from
503 * the top level lod and place them into the script memoryspace.
504 *
505 * If the allocation is also using other memory spaces a
506 * followup sync will be required.
507 */
508 public void generateMipmaps() {
509 mRS.nAllocationGenerateMipmaps(getID());
510 }
511
Jason Sams4fa3eed2011-01-19 15:44:38 -0800512 /**
513 * Copy part of an allocation from an array. This variant is
514 * not type checked which allows an application to fill in
515 * structured data from an array.
516 *
517 * @param off The offset of the first element to be copied.
518 * @param count The number of elements to be copied.
519 * @param d the source data array
520 */
521 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700522 int dataSize = mType.mElement.getSizeBytes() * count;
523 data1DChecks(off, count, d.length * 4, dataSize);
Jason Samsba862d12011-07-07 15:24:42 -0700524 mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700525 }
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, short[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700536 int dataSize = mType.mElement.getSizeBytes() * count;
537 data1DChecks(off, count, d.length * 2, dataSize);
Jason Samsba862d12011-07-07 15:24:42 -0700538 mRS.nAllocationData1D(getID(), 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, byte[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700550 int dataSize = mType.mElement.getSizeBytes() * count;
551 data1DChecks(off, count, d.length, dataSize);
Jason Samsba862d12011-07-07 15:24:42 -0700552 mRS.nAllocationData1D(getID(), 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, float[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700564 int dataSize = mType.mElement.getSizeBytes() * count;
565 data1DChecks(off, count, d.length * 4, dataSize);
Jason Samsba862d12011-07-07 15:24:42 -0700566 mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700567 }
568
Jason Sams4fa3eed2011-01-19 15:44:38 -0800569 /**
570 * Copy part of an allocation from an array. This variant is
571 * type checked and will generate exceptions if the Allocation
572 * type is not a 32 bit integer type.
573 *
574 * @param off The offset of the first element to be copied.
575 * @param count The number of elements to be copied.
576 * @param d the source data array
577 */
Jason Samsb97b2512011-01-16 15:04:08 -0800578 public void copy1DRangeFrom(int off, int count, int[] d) {
579 validateIsInt32();
580 copy1DRangeFromUnchecked(off, count, d);
581 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800582
583 /**
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 16 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, short[] d) {
593 validateIsInt16();
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 8 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, byte[] d) {
607 validateIsInt8();
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 32 bit float type.
615 *
616 * @param off The offset of the first element to be copied.
617 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700618 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800619 */
Jason Samsb97b2512011-01-16 15:04:08 -0800620 public void copy1DRangeFrom(int off, int count, float[] d) {
621 validateIsFloat32();
622 copy1DRangeFromUnchecked(off, count, d);
623 }
624
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700625 /**
626 * Copy part of an allocation from another allocation.
627 *
628 * @param off The offset of the first element to be copied.
629 * @param count The number of elements to be copied.
630 * @param data the source data allocation.
631 * @param dataOff off The offset of the first element in data to
632 * be copied.
633 */
634 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
635 mRS.nAllocationData2D(getID(), off, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700636 mSelectedLOD, mSelectedFace.mID,
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700637 count, 1, data.getID(), dataOff, 0,
Jason Samsba862d12011-07-07 15:24:42 -0700638 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700639 }
640
Jason Samsfb9f82c2011-01-12 14:53:25 -0800641 private void validate2DRange(int xoff, int yoff, int w, int h) {
Jason Samsba862d12011-07-07 15:24:42 -0700642 if (mAdaptedAllocation != null) {
643
644 } else {
645
646 if (xoff < 0 || yoff < 0) {
647 throw new RSIllegalArgumentException("Offset cannot be negative.");
648 }
649 if (h < 0 || w < 0) {
650 throw new RSIllegalArgumentException("Height or width cannot be negative.");
651 }
652 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
653 throw new RSIllegalArgumentException("Updated region larger than allocation.");
654 }
Jason Samsfb9f82c2011-01-12 14:53:25 -0800655 }
656 }
Jason Sams768bc022009-09-21 19:41:04 -0700657
Jason Samsf7086092011-01-12 13:28:37 -0800658 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700659 * Copy a rectangular region from the array into the allocation.
660 * The incoming array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -0800661 *
662 * @param xoff X offset of the region to update
663 * @param yoff Y offset of the region to update
664 * @param w Width of the incoming region to update
665 * @param h Height of the incoming region to update
666 * @param data to be placed into the allocation
667 */
668 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800669 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800670 validate2DRange(xoff, yoff, w, h);
Jason Samsba862d12011-07-07 15:24:42 -0700671 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
672 w, h, data, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -0800673 }
674
Jason Samsf7086092011-01-12 13:28:37 -0800675 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800676 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800677 validate2DRange(xoff, yoff, w, h);
Jason Samsba862d12011-07-07 15:24:42 -0700678 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
679 w, h, data, data.length * 2);
Jason Samsfa445b92011-01-07 17:00:07 -0800680 }
681
Jason Samsf7086092011-01-12 13:28:37 -0800682 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800683 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800684 validate2DRange(xoff, yoff, w, h);
Jason Samsba862d12011-07-07 15:24:42 -0700685 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
686 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700687 }
688
Jason Samsf7086092011-01-12 13:28:37 -0800689 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800690 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800691 validate2DRange(xoff, yoff, w, h);
Jason Samsba862d12011-07-07 15:24:42 -0700692 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID,
693 w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700694 }
695
Jason Samsf7086092011-01-12 13:28:37 -0800696 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700697 * Copy a rectangular region into the allocation from another
698 * allocation.
699 *
700 * @param xoff X offset of the region to update.
701 * @param yoff Y offset of the region to update.
702 * @param w Width of the incoming region to update.
703 * @param h Height of the incoming region to update.
704 * @param data source allocation.
705 * @param dataXoff X offset in data of the region to update.
706 * @param dataYoff Y offset in data of the region to update.
707 */
708 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
709 Allocation data, int dataXoff, int dataYoff) {
710 mRS.validate();
711 validate2DRange(xoff, yoff, w, h);
712 mRS.nAllocationData2D(getID(), xoff, yoff,
Jason Samsba862d12011-07-07 15:24:42 -0700713 mSelectedLOD, mSelectedFace.mID,
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700714 w, h, data.getID(), dataXoff, dataYoff,
Jason Samsba862d12011-07-07 15:24:42 -0700715 data.mSelectedLOD, data.mSelectedFace.mID);
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700716 }
717
718 /**
Jason Samsf7086092011-01-12 13:28:37 -0800719 * Copy a bitmap into an allocation. The height and width of
720 * the update will use the height and width of the incoming
721 * bitmap.
722 *
723 * @param xoff X offset of the region to update
724 * @param yoff Y offset of the region to update
725 * @param data the bitmap to be copied
726 */
727 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800728 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800729 validateBitmapFormat(data);
730 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Samsba862d12011-07-07 15:24:42 -0700731 mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800732 }
733
734
735 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800736 mRS.validate();
737 validateBitmapFormat(b);
738 validateBitmapSize(b);
Jason Samsfa445b92011-01-07 17:00:07 -0800739 mRS.nAllocationCopyToBitmap(getID(), b);
740 }
741
742 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800743 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -0800744 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800745 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700746 }
747
Jason Samsfa445b92011-01-07 17:00:07 -0800748 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800749 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -0800750 mRS.validate();
751 mRS.nAllocationRead(getID(), d);
752 }
753
754 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800755 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -0800756 mRS.validate();
757 mRS.nAllocationRead(getID(), d);
758 }
759
760 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800761 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -0800762 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800763 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700764 }
765
Jason Samsf7086092011-01-12 13:28:37 -0800766 /**
767 * Resize a 1D allocation. The contents of the allocation are
768 * preserved. If new elements are allocated objects are created
769 * with null contents and the new region is otherwise undefined.
770 *
771 * If the new region is smaller the references of any objects
772 * outside the new region will be released.
773 *
774 * A new type will be created with the new dimension.
775 *
776 * @param dimX The new size of the allocation.
777 */
Jason Sams31a7e422010-10-26 13:09:17 -0700778 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800779 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800780 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700781 }
Jason Sams06d69de2010-11-09 17:11:40 -0800782 mRS.nAllocationResize1D(getID(), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -0700783 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -0700784
Jason Sams06d69de2010-11-09 17:11:40 -0800785 int typeID = mRS.nAllocationGetType(getID());
Jason Sams31a7e422010-10-26 13:09:17 -0700786 mType = new Type(typeID, mRS);
787 mType.updateFromNative();
Jason Sams5edc6082010-10-05 13:32:49 -0700788 }
789
790 /*
791 public void resize(int dimX, int dimY) {
792 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800793 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700794 }
795 if (mType.getY() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800796 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700797 }
Jason Sams06d69de2010-11-09 17:11:40 -0800798 mRS.nAllocationResize2D(getID(), dimX, dimY);
Jason Sams5edc6082010-10-05 13:32:49 -0700799 }
800 */
Jason Sams40a29e82009-08-10 14:55:26 -0700801
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700802
Jason Samsb8c5a842009-07-31 20:40:47 -0700803
804 // creation
805
Jason Sams49a05d72010-12-29 14:31:29 -0800806 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -0700807 static {
808 mBitmapOptions.inScaled = false;
809 }
810
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800811 /**
812 *
813 * @param type renderscript type describing data layout
814 * @param mips specifies desired mipmap behaviour for the
815 * allocation
816 * @param usage bit field specifying how the allocation is
817 * utilized
818 */
819 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800820 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800821 if (type.getID() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800822 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -0700823 }
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800824 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800825 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800826 throw new RSRuntimeException("Allocation creation failed.");
827 }
Jason Sams5476b452010-12-08 16:14:36 -0800828 return new Allocation(id, rs, type, usage);
Jason Samsb8c5a842009-07-31 20:40:47 -0700829 }
830
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800831 /**
832 * Creates a renderscript allocation with the size specified by
833 * the type and no mipmaps generated by default
834 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800835 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800836 * @param type renderscript type describing data layout
837 * @param usage bit field specifying how the allocation is
838 * utilized
839 *
840 * @return allocation
841 */
Jason Samse5d37122010-12-16 00:33:33 -0800842 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
843 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
844 }
845
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800846 /**
847 * Creates a renderscript allocation for use by the script with
848 * the size specified by the type and no mipmaps generated by
849 * default
850 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800851 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800852 * @param type renderscript type describing data layout
853 *
854 * @return allocation
855 */
Jason Sams5476b452010-12-08 16:14:36 -0800856 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800857 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -0800858 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700859
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800860 /**
861 * Creates a renderscript allocation with a specified number of
862 * given elements
863 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800864 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800865 * @param e describes what each element of an allocation is
866 * @param count specifies the number of element in the allocation
867 * @param usage bit field specifying how the allocation is
868 * utilized
869 *
870 * @return allocation
871 */
Jason Sams5476b452010-12-08 16:14:36 -0800872 static public Allocation createSized(RenderScript rs, Element e,
873 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800874 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -0700875 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800876 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -0700877 Type t = b.create();
878
Jason Samsd4b23b52010-12-13 15:32:35 -0800879 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800880 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800881 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700882 }
Jason Sams5476b452010-12-08 16:14:36 -0800883 return new Allocation(id, rs, t, usage);
884 }
885
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800886 /**
887 * Creates a renderscript allocation with a specified number of
888 * given elements
889 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800890 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800891 * @param e describes what each element of an allocation is
892 * @param count specifies the number of element in the allocation
893 *
894 * @return allocation
895 */
Jason Sams5476b452010-12-08 16:14:36 -0800896 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800897 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -0700898 }
899
Jason Sams49a05d72010-12-29 14:31:29 -0800900 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -0800901 final Bitmap.Config bc = b.getConfig();
902 if (bc == Bitmap.Config.ALPHA_8) {
903 return Element.A_8(rs);
904 }
905 if (bc == Bitmap.Config.ARGB_4444) {
906 return Element.RGBA_4444(rs);
907 }
908 if (bc == Bitmap.Config.ARGB_8888) {
909 return Element.RGBA_8888(rs);
910 }
911 if (bc == Bitmap.Config.RGB_565) {
912 return Element.RGB_565(rs);
913 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -0800914 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -0800915 }
916
Jason Sams49a05d72010-12-29 14:31:29 -0800917 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800918 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -0800919 Element e = elementFromBitmap(rs, b);
920 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800921 tb.setX(b.getWidth());
922 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -0800923 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -0800924 return tb.create();
925 }
926
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800927 /**
928 * Creates a renderscript allocation from a bitmap
929 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800930 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800931 * @param b bitmap source for the allocation data
932 * @param mips specifies desired mipmap behaviour for the
933 * allocation
934 * @param usage bit field specifying how the allocation is
935 * utilized
936 *
937 * @return renderscript allocation containing bitmap data
938 *
939 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800940 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800941 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800942 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800943 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800944 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -0800945
Jason Sams5476b452010-12-08 16:14:36 -0800946 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
947 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800948 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -0800949 }
Jason Sams5476b452010-12-08 16:14:36 -0800950 return new Allocation(id, rs, t, usage);
951 }
952
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800953 /**
954 * Creates a non-mipmapped renderscript allocation to use as a
955 * graphics texture
956 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800957 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800958 * @param b bitmap source for the allocation data
959 *
960 * @return renderscript allocation containing bitmap data
961 *
962 */
Jason Sams6d8eb262010-12-15 01:41:00 -0800963 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
964 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
965 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -0800966 }
967
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800968 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800969 * Creates a cubemap allocation from a bitmap containing the
970 * horizontal list of cube faces. Each individual face must be
971 * the same size and power of 2
972 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800973 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800974 * @param b bitmap with cubemap faces layed out in the following
975 * format: right, left, top, bottom, front, back
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 Sakhartchouk67f2e442010-11-18 15:22:43 -0800982 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800983 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800984 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800985 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800986
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800987 int height = b.getHeight();
988 int width = b.getWidth();
989
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800990 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800991 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
992 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800993 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -0800994 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800995 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800996 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800997 if (!isPow2) {
998 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
999 }
1000
1001 Element e = elementFromBitmap(rs, b);
1002 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001003 tb.setX(height);
1004 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001005 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -08001006 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001007 Type t = tb.create();
1008
Jason Sams5476b452010-12-08 16:14:36 -08001009 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001010 if(id == 0) {
1011 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
1012 }
Jason Sams5476b452010-12-08 16:14:36 -08001013 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -08001014 }
1015
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001016 /**
1017 * Creates a non-mipmapped cubemap allocation for use as a
1018 * graphics texture from a bitmap containing the horizontal list
1019 * of cube faces. Each individual face must be the same size and
1020 * 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 *
1026 * @return allocation containing cubemap data
1027 *
1028 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001029 static public Allocation createCubemapFromBitmap(RenderScript rs,
1030 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -08001031 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -08001032 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -08001033 }
1034
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001035 /**
1036 * Creates a cubemap allocation from 6 bitmaps containing
1037 * the cube faces. All the faces must be the same size and
1038 * power of 2
1039 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001040 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001041 * @param xpos cubemap face in the positive x direction
1042 * @param xneg cubemap face in the negative x direction
1043 * @param ypos cubemap face in the positive y direction
1044 * @param yneg cubemap face in the negative y direction
1045 * @param zpos cubemap face in the positive z direction
1046 * @param zneg cubemap face in the negative z direction
1047 * @param mips specifies desired mipmap behaviour for the cubemap
1048 * @param usage bit field specifying how the cubemap is utilized
1049 *
1050 * @return allocation containing cubemap data
1051 *
1052 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001053 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1054 Bitmap xpos,
1055 Bitmap xneg,
1056 Bitmap ypos,
1057 Bitmap yneg,
1058 Bitmap zpos,
1059 Bitmap zneg,
1060 MipmapControl mips,
1061 int usage) {
1062 int height = xpos.getHeight();
1063 if (xpos.getWidth() != height ||
1064 xneg.getWidth() != height || xneg.getHeight() != height ||
1065 ypos.getWidth() != height || ypos.getHeight() != height ||
1066 yneg.getWidth() != height || yneg.getHeight() != height ||
1067 zpos.getWidth() != height || zpos.getHeight() != height ||
1068 zneg.getWidth() != height || zneg.getHeight() != height) {
1069 throw new RSIllegalArgumentException("Only square cube map faces supported");
1070 }
1071 boolean isPow2 = (height & (height - 1)) == 0;
1072 if (!isPow2) {
1073 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1074 }
1075
1076 Element e = elementFromBitmap(rs, xpos);
1077 Type.Builder tb = new Type.Builder(rs, e);
1078 tb.setX(height);
1079 tb.setY(height);
1080 tb.setFaces(true);
1081 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1082 Type t = tb.create();
1083 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1084
1085 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
Stephen Hines20fbd012011-06-16 17:44:53 -07001086 adapter.setFace(Type.CubemapFace.POSITIVE_X);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001087 adapter.copyFrom(xpos);
1088 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1089 adapter.copyFrom(xneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001090 adapter.setFace(Type.CubemapFace.POSITIVE_Y);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001091 adapter.copyFrom(ypos);
1092 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1093 adapter.copyFrom(yneg);
Stephen Hines20fbd012011-06-16 17:44:53 -07001094 adapter.setFace(Type.CubemapFace.POSITIVE_Z);
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001095 adapter.copyFrom(zpos);
1096 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1097 adapter.copyFrom(zneg);
1098
1099 return cubemap;
1100 }
1101
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001102 /**
1103 * Creates a non-mipmapped cubemap allocation for use as a
1104 * graphics texture from 6 bitmaps containing
1105 * the cube faces. All the faces must be the same size and
1106 * power of 2
1107 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001108 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001109 * @param xpos cubemap face in the positive x direction
1110 * @param xneg cubemap face in the negative x direction
1111 * @param ypos cubemap face in the positive y direction
1112 * @param yneg cubemap face in the negative y direction
1113 * @param zpos cubemap face in the positive z direction
1114 * @param zneg cubemap face in the negative z direction
1115 *
1116 * @return allocation containing cubemap data
1117 *
1118 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001119 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1120 Bitmap xpos,
1121 Bitmap xneg,
1122 Bitmap ypos,
1123 Bitmap yneg,
1124 Bitmap zpos,
1125 Bitmap zneg) {
1126 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1127 zpos, zneg, MipmapControl.MIPMAP_NONE,
1128 USAGE_GRAPHICS_TEXTURE);
1129 }
1130
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001131 /**
1132 * Creates a renderscript allocation from the bitmap referenced
1133 * by resource id
1134 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001135 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001136 * @param res application resources
1137 * @param id resource id to load the data from
1138 * @param mips specifies desired mipmap behaviour for the
1139 * allocation
1140 * @param usage bit field specifying how the allocation is
1141 * utilized
1142 *
1143 * @return renderscript allocation containing resource data
1144 *
1145 */
Jason Sams5476b452010-12-08 16:14:36 -08001146 static public Allocation createFromBitmapResource(RenderScript rs,
1147 Resources res,
1148 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001149 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001150 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001151
Jason Sams771bebb2009-12-07 12:40:12 -08001152 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001153 Bitmap b = BitmapFactory.decodeResource(res, id);
1154 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1155 b.recycle();
1156 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001157 }
1158
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001159 /**
1160 * Creates a non-mipmapped renderscript allocation to use as a
1161 * graphics texture from the bitmap referenced by resource id
1162 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001163 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001164 * @param res application resources
1165 * @param id resource id to load the data from
1166 *
1167 * @return renderscript allocation containing resource data
1168 *
1169 */
Jason Sams5476b452010-12-08 16:14:36 -08001170 static public Allocation createFromBitmapResource(RenderScript rs,
1171 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001172 int id) {
1173 return createFromBitmapResource(rs, res, id,
1174 MipmapControl.MIPMAP_NONE,
1175 USAGE_GRAPHICS_TEXTURE);
1176 }
1177
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001178 /**
1179 * Creates a renderscript allocation containing string data
1180 * encoded in UTF-8 format
1181 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001182 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001183 * @param str string to create the allocation from
1184 * @param usage bit field specifying how the allocaiton is
1185 * utilized
1186 *
1187 */
Jason Sams5476b452010-12-08 16:14:36 -08001188 static public Allocation createFromString(RenderScript rs,
1189 String str,
1190 int usage) {
1191 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001192 byte[] allocArray = null;
1193 try {
1194 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001195 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001196 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001197 return alloc;
1198 }
1199 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001200 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001201 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001202 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001203}
1204
1205