blob: a63abb9f9bc72141c2a53d0c14959418e7b96ff4 [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 /**
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700103 * USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
104 * target for offscreen rendering
105 *
106 */
107 public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
108
Jason Sams43ee06852009-08-12 17:54:11 -0700109
Jason Samsf7086092011-01-12 13:28:37 -0800110 /**
111 * Controls mipmap behavior when using the bitmap creation and
112 * update functions.
113 */
Jason Sams4ef66502010-12-10 16:03:15 -0800114 public enum MipmapControl {
Jason Samsf7086092011-01-12 13:28:37 -0800115 /**
116 * No mipmaps will be generated and the type generated from the
117 * incoming bitmap will not contain additional LODs.
118 */
Jason Sams5476b452010-12-08 16:14:36 -0800119 MIPMAP_NONE(0),
Jason Samsf7086092011-01-12 13:28:37 -0800120
121 /**
122 * A Full mipmap chain will be created in script memory. The
123 * type of the allocation will contain a full mipmap chain. On
124 * upload to graphics the full chain will be transfered.
125 */
Jason Sams5476b452010-12-08 16:14:36 -0800126 MIPMAP_FULL(1),
Jason Samsf7086092011-01-12 13:28:37 -0800127
128 /**
129 * The type of the allocation will be the same as MIPMAP_NONE.
130 * It will not contain mipmaps. On upload to graphics the
131 * graphics copy of the allocation data will contain a full
132 * mipmap chain generated from the top level in script memory.
133 */
Jason Sams5476b452010-12-08 16:14:36 -0800134 MIPMAP_ON_SYNC_TO_TEXTURE(2);
135
136 int mID;
Jason Sams4ef66502010-12-10 16:03:15 -0800137 MipmapControl(int id) {
Jason Sams5476b452010-12-08 16:14:36 -0800138 mID = id;
139 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700140 }
141
Jason Sams5476b452010-12-08 16:14:36 -0800142 Allocation(int id, RenderScript rs, Type t, int usage) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700143 super(id, rs);
Jason Sams49a05d72010-12-29 14:31:29 -0800144 if ((usage & ~(USAGE_SCRIPT |
145 USAGE_GRAPHICS_TEXTURE |
146 USAGE_GRAPHICS_VERTEX |
Alex Sakhartchouk8e90f2b2011-04-01 14:19:01 -0700147 USAGE_GRAPHICS_CONSTANTS |
148 USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
Jason Sams5476b452010-12-08 16:14:36 -0800149 throw new RSIllegalArgumentException("Unknown usage specified.");
150 }
151 mType = t;
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700152 }
153
Jason Samsb97b2512011-01-16 15:04:08 -0800154 private void validateIsInt32() {
155 if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
156 (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
157 return;
158 }
159 throw new RSIllegalArgumentException(
160 "32 bit integer source does not match allocation type " + mType.mElement.mType);
161 }
162
163 private void validateIsInt16() {
164 if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
165 (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
166 return;
167 }
168 throw new RSIllegalArgumentException(
169 "16 bit integer source does not match allocation type " + mType.mElement.mType);
170 }
171
172 private void validateIsInt8() {
173 if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
174 (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
175 return;
176 }
177 throw new RSIllegalArgumentException(
178 "8 bit integer source does not match allocation type " + mType.mElement.mType);
179 }
180
181 private void validateIsFloat32() {
182 if (mType.mElement.mType == Element.DataType.FLOAT_32) {
183 return;
184 }
185 throw new RSIllegalArgumentException(
186 "32 bit float source does not match allocation type " + mType.mElement.mType);
187 }
188
189 private void validateIsObject() {
190 if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
191 (mType.mElement.mType == Element.DataType.RS_TYPE) ||
192 (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
193 (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
194 (mType.mElement.mType == Element.DataType.RS_SCRIPT) ||
195 (mType.mElement.mType == Element.DataType.RS_MESH) ||
196 (mType.mElement.mType == Element.DataType.RS_PROGRAM_FRAGMENT) ||
197 (mType.mElement.mType == Element.DataType.RS_PROGRAM_VERTEX) ||
198 (mType.mElement.mType == Element.DataType.RS_PROGRAM_RASTER) ||
199 (mType.mElement.mType == Element.DataType.RS_PROGRAM_STORE)) {
200 return;
201 }
202 throw new RSIllegalArgumentException(
203 "Object source does not match allocation type " + mType.mElement.mType);
204 }
205
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700206 @Override
207 void updateFromNative() {
Jason Sams06d69de2010-11-09 17:11:40 -0800208 super.updateFromNative();
209 int typeID = mRS.nAllocationGetType(getID());
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -0700210 if(typeID != 0) {
211 mType = new Type(typeID, mRS);
212 mType.updateFromNative();
213 }
214 }
215
Jason Samsea87e962010-01-12 12:12:28 -0800216 public Type getType() {
217 return mType;
218 }
219
Jason Sams5476b452010-12-08 16:14:36 -0800220 public void syncAll(int srcLocation) {
221 switch (srcLocation) {
222 case USAGE_SCRIPT:
223 case USAGE_GRAPHICS_CONSTANTS:
224 case USAGE_GRAPHICS_TEXTURE:
225 case USAGE_GRAPHICS_VERTEX:
226 break;
227 default:
228 throw new RSIllegalArgumentException("Source must be exactly one usage type.");
229 }
230 mRS.validate();
231 mRS.nAllocationSyncAll(getID(), srcLocation);
232 }
233
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800234 public void copyFrom(BaseObj[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800235 mRS.validate();
Jason Samsb97b2512011-01-16 15:04:08 -0800236 validateIsObject();
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800237 if (d.length != mType.getCount()) {
238 throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
239 mType.getCount() + ", array length = " + d.length);
240 }
241 int i[] = new int[d.length];
242 for (int ct=0; ct < d.length; ct++) {
243 i[ct] = d[ct].getID();
244 }
Jason Samsed5bab92011-01-21 13:08:02 -0800245 copy1DRangeFromUnchecked(0, mType.getCount(), i);
Jason Samsb8c5a842009-07-31 20:40:47 -0700246 }
247
Jason Samsfb9f82c2011-01-12 14:53:25 -0800248 private void validateBitmapFormat(Bitmap b) {
Jason Sams252c0782011-01-11 17:42:52 -0800249 Bitmap.Config bc = b.getConfig();
250 switch (bc) {
251 case ALPHA_8:
252 if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
253 throw new RSIllegalArgumentException("Allocation kind is " +
254 mType.getElement().mKind + ", type " +
255 mType.getElement().mType +
256 " of " + mType.getElement().getSizeBytes() +
257 " bytes, passed bitmap was " + bc);
258 }
259 break;
260 case ARGB_8888:
261 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
262 (mType.getElement().getSizeBytes() != 4)) {
263 throw new RSIllegalArgumentException("Allocation kind is " +
264 mType.getElement().mKind + ", type " +
265 mType.getElement().mType +
266 " of " + mType.getElement().getSizeBytes() +
267 " bytes, passed bitmap was " + bc);
268 }
269 break;
270 case RGB_565:
271 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
272 (mType.getElement().getSizeBytes() != 2)) {
273 throw new RSIllegalArgumentException("Allocation kind is " +
274 mType.getElement().mKind + ", type " +
275 mType.getElement().mType +
276 " of " + mType.getElement().getSizeBytes() +
277 " bytes, passed bitmap was " + bc);
278 }
279 break;
280 case ARGB_4444:
281 if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
282 (mType.getElement().getSizeBytes() != 2)) {
283 throw new RSIllegalArgumentException("Allocation kind is " +
284 mType.getElement().mKind + ", type " +
285 mType.getElement().mType +
286 " of " + mType.getElement().getSizeBytes() +
287 " bytes, passed bitmap was " + bc);
288 }
289 break;
290
291 }
Jason Sams4ef66502010-12-10 16:03:15 -0800292 }
293
Jason Samsfb9f82c2011-01-12 14:53:25 -0800294 private void validateBitmapSize(Bitmap b) {
295 if(mType.getX() != b.getWidth() ||
296 mType.getY() != b.getHeight()) {
297 throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
298 }
299 }
300
Jason Sams4fa3eed2011-01-19 15:44:38 -0800301 /**
302 * Copy an allocation from an array. This variant is not type
303 * checked which allows an application to fill in structured
304 * data from an array.
305 *
306 * @param d the source data array
307 */
308 public void copyFromUnchecked(int[] d) {
309 mRS.validate();
310 copy1DRangeFromUnchecked(0, mType.getCount(), d);
311 }
312 /**
313 * Copy an allocation from an array. This variant is not type
314 * checked which allows an application to fill in structured
315 * data from an array.
316 *
317 * @param d the source data array
318 */
319 public void copyFromUnchecked(short[] d) {
320 mRS.validate();
321 copy1DRangeFromUnchecked(0, mType.getCount(), d);
322 }
323 /**
324 * Copy an allocation from an array. This variant is not type
325 * checked which allows an application to fill in structured
326 * data from an array.
327 *
328 * @param d the source data array
329 */
330 public void copyFromUnchecked(byte[] d) {
331 mRS.validate();
332 copy1DRangeFromUnchecked(0, mType.getCount(), d);
333 }
334 /**
335 * Copy an allocation from an array. This variant is not type
336 * checked which allows an application to fill in structured
337 * data from an array.
338 *
339 * @param d the source data array
340 */
341 public void copyFromUnchecked(float[] d) {
342 mRS.validate();
343 copy1DRangeFromUnchecked(0, mType.getCount(), d);
344 }
345
346 /**
347 * Copy an allocation from an array. This variant is type
348 * checked and will generate exceptions if the Allocation type
349 * is not a 32 bit integer type.
350 *
351 * @param d the source data array
352 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800353 public void copyFrom(int[] d) {
354 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800355 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800356 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800357
358 /**
359 * Copy an allocation from an array. This variant is type
360 * checked and will generate exceptions if the Allocation type
361 * is not a 16 bit integer type.
362 *
363 * @param d the source data array
364 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800365 public void copyFrom(short[] d) {
366 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800367 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800368 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800369
370 /**
371 * Copy an allocation from an array. This variant is type
372 * checked and will generate exceptions if the Allocation type
373 * is not a 8 bit integer type.
374 *
375 * @param d the source data array
376 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800377 public void copyFrom(byte[] d) {
378 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800379 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800380 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800381
382 /**
383 * Copy an allocation from an array. This variant is type
384 * checked and will generate exceptions if the Allocation type
385 * is not a 32 bit float type.
386 *
387 * @param d the source data array
388 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800389 public void copyFrom(float[] d) {
390 mRS.validate();
Jason Samsfa445b92011-01-07 17:00:07 -0800391 copy1DRangeFrom(0, mType.getCount(), d);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800392 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800393
394 /**
395 * Copy an allocation from a bitmap. The height, width, and
396 * format of the bitmap must match the existing allocation.
397 *
398 * @param b the source bitmap
399 */
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800400 public void copyFrom(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800401 mRS.validate();
402 validateBitmapSize(b);
403 validateBitmapFormat(b);
Jason Sams4ef66502010-12-10 16:03:15 -0800404 mRS.nAllocationCopyFromBitmap(getID(), b);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700405 }
406
Jason Samsfa445b92011-01-07 17:00:07 -0800407 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800408 * This is only intended to be used by auto-generate code reflected from the
409 * renderscript script files.
410 *
411 * @param xoff
412 * @param fp
413 */
Jason Sams21b41032011-01-16 15:05:41 -0800414 public void setFromFieldPacker(int xoff, FieldPacker fp) {
Jason Samsa70f4162010-03-26 15:33:42 -0700415 int eSize = mType.mElement.getSizeBytes();
416 final byte[] data = fp.getData();
417
418 int count = data.length / eSize;
419 if ((eSize * count) != data.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800420 throw new RSIllegalArgumentException("Field packer length " + data.length +
Jason Samsa70f4162010-03-26 15:33:42 -0700421 " not divisible by element size " + eSize + ".");
422 }
Jason Sams49bdaf02010-08-31 13:50:42 -0700423 data1DChecks(xoff, count, data.length, data.length);
Jason Sams49a05d72010-12-29 14:31:29 -0800424 mRS.nAllocationData1D(getID(), xoff, 0, count, data, data.length);
Jason Sams49bdaf02010-08-31 13:50:42 -0700425 }
426
Jason Samsfa445b92011-01-07 17:00:07 -0800427 /**
Jason Samsfa445b92011-01-07 17:00:07 -0800428 * This is only intended to be used by auto-generate code reflected from the
429 * renderscript script files.
430 *
431 * @param xoff
432 * @param component_number
433 * @param fp
434 */
Jason Sams21b41032011-01-16 15:05:41 -0800435 public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700436 if (component_number >= mType.mElement.mElements.length) {
Jason Sams06d69de2010-11-09 17:11:40 -0800437 throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700438 }
439 if(xoff < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800440 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Sams49bdaf02010-08-31 13:50:42 -0700441 }
442
443 final byte[] data = fp.getData();
444 int eSize = mType.mElement.mElements[component_number].getSizeBytes();
445
446 if (data.length != eSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800447 throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
Jason Sams49bdaf02010-08-31 13:50:42 -0700448 " does not match component size " + eSize + ".");
449 }
450
Jason Sams49a05d72010-12-29 14:31:29 -0800451 mRS.nAllocationElementData1D(getID(), xoff, 0, component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700452 }
453
Jason Sams768bc022009-09-21 19:41:04 -0700454 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800455 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700456 if(off < 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800457 throw new RSIllegalArgumentException("Offset must be >= 0.");
Jason Samsa70f4162010-03-26 15:33:42 -0700458 }
459 if(count < 1) {
Jason Sams06d69de2010-11-09 17:11:40 -0800460 throw new RSIllegalArgumentException("Count must be >= 1.");
Jason Samsa70f4162010-03-26 15:33:42 -0700461 }
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800462 if((off + count) > mType.getCount()) {
463 throw new RSIllegalArgumentException("Overflow, Available count " + mType.getCount() +
Jason Samsa70f4162010-03-26 15:33:42 -0700464 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700465 }
Jason Sams768bc022009-09-21 19:41:04 -0700466 if((len) < dataSize) {
Jason Sams06d69de2010-11-09 17:11:40 -0800467 throw new RSIllegalArgumentException("Array too small for allocation type.");
Jason Sams768bc022009-09-21 19:41:04 -0700468 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700469 }
470
Jason Samsf7086092011-01-12 13:28:37 -0800471 /**
472 * Generate a mipmap chain. Requires the type of the allocation
473 * include mipmaps.
474 *
475 * This function will generate a complete set of mipmaps from
476 * the top level lod and place them into the script memoryspace.
477 *
478 * If the allocation is also using other memory spaces a
479 * followup sync will be required.
480 */
481 public void generateMipmaps() {
482 mRS.nAllocationGenerateMipmaps(getID());
483 }
484
Jason Sams4fa3eed2011-01-19 15:44:38 -0800485 /**
486 * Copy part of an allocation from an array. This variant is
487 * not type checked which allows an application to fill in
488 * structured data from an array.
489 *
490 * @param off The offset of the first element to be copied.
491 * @param count The number of elements to be copied.
492 * @param d the source data array
493 */
494 public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700495 int dataSize = mType.mElement.getSizeBytes() * count;
496 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800497 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700498 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800499 /**
500 * Copy part of an allocation from an array. This variant is
501 * not type checked which allows an application to fill in
502 * structured data from an array.
503 *
504 * @param off The offset of the first element to be copied.
505 * @param count The number of elements to be copied.
506 * @param d the source data array
507 */
508 public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700509 int dataSize = mType.mElement.getSizeBytes() * count;
510 data1DChecks(off, count, d.length * 2, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800511 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700512 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800513 /**
514 * Copy part of an allocation from an array. This variant is
515 * not type checked which allows an application to fill in
516 * structured data from an array.
517 *
518 * @param off The offset of the first element to be copied.
519 * @param count The number of elements to be copied.
520 * @param d the source data array
521 */
522 public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700523 int dataSize = mType.mElement.getSizeBytes() * count;
524 data1DChecks(off, count, d.length, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800525 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Sams768bc022009-09-21 19:41:04 -0700526 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800527 /**
528 * Copy part of an allocation from an array. This variant is
529 * not type checked which allows an application to fill in
530 * structured data from an array.
531 *
532 * @param off The offset of the first element to be copied.
533 * @param count The number of elements to be copied.
534 * @param d the source data array
535 */
536 public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700537 int dataSize = mType.mElement.getSizeBytes() * count;
538 data1DChecks(off, count, d.length * 4, dataSize);
Jason Sams49a05d72010-12-29 14:31:29 -0800539 mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700540 }
541
Jason Sams4fa3eed2011-01-19 15:44:38 -0800542 /**
543 * Copy part of an allocation from an array. This variant is
544 * type checked and will generate exceptions if the Allocation
545 * type is not a 32 bit integer type.
546 *
547 * @param off The offset of the first element to be copied.
548 * @param count The number of elements to be copied.
549 * @param d the source data array
550 */
Jason Samsb97b2512011-01-16 15:04:08 -0800551 public void copy1DRangeFrom(int off, int count, int[] d) {
552 validateIsInt32();
553 copy1DRangeFromUnchecked(off, count, d);
554 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800555
556 /**
557 * Copy part of an allocation from an array. This variant is
558 * type checked and will generate exceptions if the Allocation
559 * type is not a 16 bit integer type.
560 *
561 * @param off The offset of the first element to be copied.
562 * @param count The number of elements to be copied.
563 * @param d the source data array
564 */
Jason Samsb97b2512011-01-16 15:04:08 -0800565 public void copy1DRangeFrom(int off, int count, short[] d) {
566 validateIsInt16();
567 copy1DRangeFromUnchecked(off, count, d);
568 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800569
570 /**
571 * Copy part of an allocation from an array. This variant is
572 * type checked and will generate exceptions if the Allocation
573 * type is not a 8 bit integer type.
574 *
575 * @param off The offset of the first element to be copied.
576 * @param count The number of elements to be copied.
577 * @param d the source data array
578 */
Jason Samsb97b2512011-01-16 15:04:08 -0800579 public void copy1DRangeFrom(int off, int count, byte[] d) {
580 validateIsInt8();
581 copy1DRangeFromUnchecked(off, count, d);
582 }
Jason Sams4fa3eed2011-01-19 15:44:38 -0800583
584 /**
585 * Copy part of an allocation from an array. This variant is
586 * type checked and will generate exceptions if the Allocation
587 * type is not a 32 bit float type.
588 *
589 * @param off The offset of the first element to be copied.
590 * @param count The number of elements to be copied.
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700591 * @param d the source data array.
Jason Sams4fa3eed2011-01-19 15:44:38 -0800592 */
Jason Samsb97b2512011-01-16 15:04:08 -0800593 public void copy1DRangeFrom(int off, int count, float[] d) {
594 validateIsFloat32();
595 copy1DRangeFromUnchecked(off, count, d);
596 }
597
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700598 /**
599 * Copy part of an allocation from another allocation.
600 *
601 * @param off The offset of the first element to be copied.
602 * @param count The number of elements to be copied.
603 * @param data the source data allocation.
604 * @param dataOff off The offset of the first element in data to
605 * be copied.
606 */
607 public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
608 mRS.nAllocationData2D(getID(), off, 0,
609 0, Type.CubemapFace.POSITVE_X.mID,
610 count, 1, data.getID(), dataOff, 0,
611 0, Type.CubemapFace.POSITVE_X.mID);
612 }
613
Jason Samsfb9f82c2011-01-12 14:53:25 -0800614 private void validate2DRange(int xoff, int yoff, int w, int h) {
615 if (xoff < 0 || yoff < 0) {
616 throw new RSIllegalArgumentException("Offset cannot be negative.");
617 }
618 if (h < 0 || w < 0) {
619 throw new RSIllegalArgumentException("Height or width cannot be negative.");
620 }
621 if ((xoff + w) > mType.mDimX ||
622 (yoff + h) > mType.mDimY) {
623 throw new RSIllegalArgumentException("Updated region larger than allocation.");
624 }
625 }
Jason Sams768bc022009-09-21 19:41:04 -0700626
Jason Samsf7086092011-01-12 13:28:37 -0800627 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700628 * Copy a rectangular region from the array into the allocation.
629 * The incoming array is assumed to be tightly packed.
Jason Samsf7086092011-01-12 13:28:37 -0800630 *
631 * @param xoff X offset of the region to update
632 * @param yoff Y offset of the region to update
633 * @param w Width of the incoming region to update
634 * @param h Height of the incoming region to update
635 * @param data to be placed into the allocation
636 */
637 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800638 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800639 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800640 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length);
Jason Samsfa445b92011-01-07 17:00:07 -0800641 }
642
Jason Samsf7086092011-01-12 13:28:37 -0800643 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800644 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800645 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800646 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 2);
Jason Samsfa445b92011-01-07 17:00:07 -0800647 }
648
Jason Samsf7086092011-01-12 13:28:37 -0800649 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800650 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800651 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800652 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700653 }
654
Jason Samsf7086092011-01-12 13:28:37 -0800655 public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
Jason Sams771bebb2009-12-07 12:40:12 -0800656 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800657 validate2DRange(xoff, yoff, w, h);
Jason Samsf7086092011-01-12 13:28:37 -0800658 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, w, h, data, data.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700659 }
660
Jason Samsf7086092011-01-12 13:28:37 -0800661 /**
Alex Sakhartchouk304b1f52011-06-14 11:13:19 -0700662 * Copy a rectangular region into the allocation from another
663 * allocation.
664 *
665 * @param xoff X offset of the region to update.
666 * @param yoff Y offset of the region to update.
667 * @param w Width of the incoming region to update.
668 * @param h Height of the incoming region to update.
669 * @param data source allocation.
670 * @param dataXoff X offset in data of the region to update.
671 * @param dataYoff Y offset in data of the region to update.
672 */
673 public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
674 Allocation data, int dataXoff, int dataYoff) {
675 mRS.validate();
676 validate2DRange(xoff, yoff, w, h);
677 mRS.nAllocationData2D(getID(), xoff, yoff,
678 0, Type.CubemapFace.POSITVE_X.mID,
679 w, h, data.getID(), dataXoff, dataYoff,
680 0, Type.CubemapFace.POSITVE_X.mID);
681 }
682
683 /**
Jason Samsf7086092011-01-12 13:28:37 -0800684 * Copy a bitmap into an allocation. The height and width of
685 * the update will use the height and width of the incoming
686 * bitmap.
687 *
688 * @param xoff X offset of the region to update
689 * @param yoff Y offset of the region to update
690 * @param data the bitmap to be copied
691 */
692 public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
Jason Samsfa445b92011-01-07 17:00:07 -0800693 mRS.validate();
Jason Samsfb9f82c2011-01-12 14:53:25 -0800694 validateBitmapFormat(data);
695 validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
Jason Samsf7086092011-01-12 13:28:37 -0800696 mRS.nAllocationData2D(getID(), xoff, yoff, 0, 0, data);
Jason Samsfa445b92011-01-07 17:00:07 -0800697 }
698
699
700 public void copyTo(Bitmap b) {
Jason Samsfb9f82c2011-01-12 14:53:25 -0800701 mRS.validate();
702 validateBitmapFormat(b);
703 validateBitmapSize(b);
Jason Samsfa445b92011-01-07 17:00:07 -0800704 mRS.nAllocationCopyToBitmap(getID(), b);
705 }
706
707 public void copyTo(byte[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800708 validateIsInt8();
Jason Sams771bebb2009-12-07 12:40:12 -0800709 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800710 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700711 }
712
Jason Samsfa445b92011-01-07 17:00:07 -0800713 public void copyTo(short[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800714 validateIsInt16();
Jason Samsfa445b92011-01-07 17:00:07 -0800715 mRS.validate();
716 mRS.nAllocationRead(getID(), d);
717 }
718
719 public void copyTo(int[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800720 validateIsInt32();
Jason Samsfa445b92011-01-07 17:00:07 -0800721 mRS.validate();
722 mRS.nAllocationRead(getID(), d);
723 }
724
725 public void copyTo(float[] d) {
Jason Samsb97b2512011-01-16 15:04:08 -0800726 validateIsFloat32();
Jason Sams771bebb2009-12-07 12:40:12 -0800727 mRS.validate();
Jason Sams06d69de2010-11-09 17:11:40 -0800728 mRS.nAllocationRead(getID(), d);
Jason Sams40a29e82009-08-10 14:55:26 -0700729 }
730
Jason Samsf7086092011-01-12 13:28:37 -0800731 /**
732 * Resize a 1D allocation. The contents of the allocation are
733 * preserved. If new elements are allocated objects are created
734 * with null contents and the new region is otherwise undefined.
735 *
736 * If the new region is smaller the references of any objects
737 * outside the new region will be released.
738 *
739 * A new type will be created with the new dimension.
740 *
741 * @param dimX The new size of the allocation.
742 */
Jason Sams31a7e422010-10-26 13:09:17 -0700743 public synchronized void resize(int dimX) {
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800744 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800745 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700746 }
Jason Sams06d69de2010-11-09 17:11:40 -0800747 mRS.nAllocationResize1D(getID(), dimX);
Jason Samsd26297f2010-11-01 16:08:59 -0700748 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -0700749
Jason Sams06d69de2010-11-09 17:11:40 -0800750 int typeID = mRS.nAllocationGetType(getID());
Jason Sams31a7e422010-10-26 13:09:17 -0700751 mType = new Type(typeID, mRS);
752 mType.updateFromNative();
Jason Sams5edc6082010-10-05 13:32:49 -0700753 }
754
755 /*
756 public void resize(int dimX, int dimY) {
757 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
Jason Sams06d69de2010-11-09 17:11:40 -0800758 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700759 }
760 if (mType.getY() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800761 throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
Jason Sams5edc6082010-10-05 13:32:49 -0700762 }
Jason Sams06d69de2010-11-09 17:11:40 -0800763 mRS.nAllocationResize2D(getID(), dimX, dimY);
Jason Sams5edc6082010-10-05 13:32:49 -0700764 }
765 */
Jason Sams40a29e82009-08-10 14:55:26 -0700766
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700767
Jason Samsb8c5a842009-07-31 20:40:47 -0700768
769 // creation
770
Jason Sams49a05d72010-12-29 14:31:29 -0800771 static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
Jason Samsb8c5a842009-07-31 20:40:47 -0700772 static {
773 mBitmapOptions.inScaled = false;
774 }
775
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800776 /**
777 *
778 * @param type renderscript type describing data layout
779 * @param mips specifies desired mipmap behaviour for the
780 * allocation
781 * @param usage bit field specifying how the allocation is
782 * utilized
783 */
784 static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800785 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800786 if (type.getID() == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800787 throw new RSInvalidStateException("Bad Type");
Jason Sams1bada8c2009-08-09 17:01:55 -0700788 }
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800789 int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800790 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800791 throw new RSRuntimeException("Allocation creation failed.");
792 }
Jason Sams5476b452010-12-08 16:14:36 -0800793 return new Allocation(id, rs, type, usage);
Jason Samsb8c5a842009-07-31 20:40:47 -0700794 }
795
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800796 /**
797 * Creates a renderscript allocation with the size specified by
798 * the type and no mipmaps generated by default
799 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800800 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800801 * @param type renderscript type describing data layout
802 * @param usage bit field specifying how the allocation is
803 * utilized
804 *
805 * @return allocation
806 */
Jason Samse5d37122010-12-16 00:33:33 -0800807 static public Allocation createTyped(RenderScript rs, Type type, int usage) {
808 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
809 }
810
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800811 /**
812 * Creates a renderscript allocation for use by the script with
813 * the size specified by the type and no mipmaps generated by
814 * default
815 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800816 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800817 * @param type renderscript type describing data layout
818 *
819 * @return allocation
820 */
Jason Sams5476b452010-12-08 16:14:36 -0800821 static public Allocation createTyped(RenderScript rs, Type type) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800822 return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
Jason Sams5476b452010-12-08 16:14:36 -0800823 }
Jason Sams1bada8c2009-08-09 17:01:55 -0700824
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800825 /**
826 * Creates a renderscript allocation with a specified number of
827 * given elements
828 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800829 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800830 * @param e describes what each element of an allocation is
831 * @param count specifies the number of element in the allocation
832 * @param usage bit field specifying how the allocation is
833 * utilized
834 *
835 * @return allocation
836 */
Jason Sams5476b452010-12-08 16:14:36 -0800837 static public Allocation createSized(RenderScript rs, Element e,
838 int count, int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800839 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -0700840 Type.Builder b = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800841 b.setX(count);
Jason Sams768bc022009-09-21 19:41:04 -0700842 Type t = b.create();
843
Jason Samsd4b23b52010-12-13 15:32:35 -0800844 int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
Jason Sams5476b452010-12-08 16:14:36 -0800845 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800846 throw new RSRuntimeException("Allocation creation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700847 }
Jason Sams5476b452010-12-08 16:14:36 -0800848 return new Allocation(id, rs, t, usage);
849 }
850
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800851 /**
852 * Creates a renderscript allocation with a specified number of
853 * given elements
854 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800855 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800856 * @param e describes what each element of an allocation is
857 * @param count specifies the number of element in the allocation
858 *
859 * @return allocation
860 */
Jason Sams5476b452010-12-08 16:14:36 -0800861 static public Allocation createSized(RenderScript rs, Element e, int count) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800862 return createSized(rs, e, count, USAGE_SCRIPT);
Jason Samsb8c5a842009-07-31 20:40:47 -0700863 }
864
Jason Sams49a05d72010-12-29 14:31:29 -0800865 static Element elementFromBitmap(RenderScript rs, Bitmap b) {
Jason Sams8a647432010-03-01 15:31:04 -0800866 final Bitmap.Config bc = b.getConfig();
867 if (bc == Bitmap.Config.ALPHA_8) {
868 return Element.A_8(rs);
869 }
870 if (bc == Bitmap.Config.ARGB_4444) {
871 return Element.RGBA_4444(rs);
872 }
873 if (bc == Bitmap.Config.ARGB_8888) {
874 return Element.RGBA_8888(rs);
875 }
876 if (bc == Bitmap.Config.RGB_565) {
877 return Element.RGB_565(rs);
878 }
Jeff Sharkey4bd1a3d2010-11-16 13:46:34 -0800879 throw new RSInvalidStateException("Bad bitmap type: " + bc);
Jason Sams8a647432010-03-01 15:31:04 -0800880 }
881
Jason Sams49a05d72010-12-29 14:31:29 -0800882 static Type typeFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800883 MipmapControl mip) {
Jason Sams8a647432010-03-01 15:31:04 -0800884 Element e = elementFromBitmap(rs, b);
885 Type.Builder tb = new Type.Builder(rs, e);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800886 tb.setX(b.getWidth());
887 tb.setY(b.getHeight());
Jason Sams4ef66502010-12-10 16:03:15 -0800888 tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
Jason Sams8a647432010-03-01 15:31:04 -0800889 return tb.create();
890 }
891
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800892 /**
893 * Creates a renderscript allocation from a bitmap
894 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800895 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800896 * @param b bitmap source for the allocation data
897 * @param mips specifies desired mipmap behaviour for the
898 * allocation
899 * @param usage bit field specifying how the allocation is
900 * utilized
901 *
902 * @return renderscript allocation containing bitmap data
903 *
904 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800905 static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800906 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800907 int usage) {
Jason Sams771bebb2009-12-07 12:40:12 -0800908 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800909 Type t = typeFromBitmap(rs, b, mips);
Jason Sams8a647432010-03-01 15:31:04 -0800910
Jason Sams5476b452010-12-08 16:14:36 -0800911 int id = rs.nAllocationCreateFromBitmap(t.getID(), mips.mID, b, usage);
912 if (id == 0) {
Jason Sams06d69de2010-11-09 17:11:40 -0800913 throw new RSRuntimeException("Load failed.");
Jason Sams718cd1f2009-12-23 14:35:29 -0800914 }
Jason Sams5476b452010-12-08 16:14:36 -0800915 return new Allocation(id, rs, t, usage);
916 }
917
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800918 /**
919 * Creates a non-mipmapped renderscript allocation to use as a
920 * graphics texture
921 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800922 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800923 * @param b bitmap source for the allocation data
924 *
925 * @return renderscript allocation containing bitmap data
926 *
927 */
Jason Sams6d8eb262010-12-15 01:41:00 -0800928 static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
929 return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
930 USAGE_GRAPHICS_TEXTURE);
Jason Sams8a647432010-03-01 15:31:04 -0800931 }
932
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800933 /**
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800934 * Creates a cubemap allocation from a bitmap containing the
935 * horizontal list of cube faces. Each individual face must be
936 * the same size and power of 2
937 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800938 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800939 * @param b bitmap with cubemap faces layed out in the following
940 * format: right, left, top, bottom, front, back
941 * @param mips specifies desired mipmap behaviour for the cubemap
942 * @param usage bit field specifying how the cubemap is utilized
943 *
944 * @return allocation containing cubemap data
945 *
946 */
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800947 static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
Jason Sams4ef66502010-12-10 16:03:15 -0800948 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800949 int usage) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800950 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -0800951
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800952 int height = b.getHeight();
953 int width = b.getWidth();
954
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800955 if (width % 6 != 0) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800956 throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
957 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800958 if (width / 6 != height) {
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -0800959 throw new RSIllegalArgumentException("Only square cube map faces supported");
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800960 }
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800961 boolean isPow2 = (height & (height - 1)) == 0;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800962 if (!isPow2) {
963 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
964 }
965
966 Element e = elementFromBitmap(rs, b);
967 Type.Builder tb = new Type.Builder(rs, e);
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800968 tb.setX(height);
969 tb.setY(height);
Jason Samsbf6ef8d72010-12-06 15:59:59 -0800970 tb.setFaces(true);
Jason Sams4ef66502010-12-10 16:03:15 -0800971 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800972 Type t = tb.create();
973
Jason Sams5476b452010-12-08 16:14:36 -0800974 int id = rs.nAllocationCubeCreateFromBitmap(t.getID(), mips.mID, b, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800975 if(id == 0) {
976 throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
977 }
Jason Sams5476b452010-12-08 16:14:36 -0800978 return new Allocation(id, rs, t, usage);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800979 }
980
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800981 /**
982 * Creates a non-mipmapped cubemap allocation for use as a
983 * graphics texture from a bitmap containing the horizontal list
984 * of cube faces. Each individual face must be the same size and
985 * power of 2
986 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -0800987 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -0800988 * @param b bitmap with cubemap faces layed out in the following
989 * format: right, left, top, bottom, front, back
990 *
991 * @return allocation containing cubemap data
992 *
993 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -0800994 static public Allocation createCubemapFromBitmap(RenderScript rs,
995 Bitmap b) {
Jason Sams6d8eb262010-12-15 01:41:00 -0800996 return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
Alex Sakhartchoukfe852e22011-01-10 15:57:57 -0800997 USAGE_GRAPHICS_TEXTURE);
Jason Sams5476b452010-12-08 16:14:36 -0800998 }
999
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001000 /**
1001 * Creates a cubemap allocation from 6 bitmaps containing
1002 * the cube faces. All the faces must be the same size and
1003 * power of 2
1004 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001005 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001006 * @param xpos cubemap face in the positive x direction
1007 * @param xneg cubemap face in the negative x direction
1008 * @param ypos cubemap face in the positive y direction
1009 * @param yneg cubemap face in the negative y direction
1010 * @param zpos cubemap face in the positive z direction
1011 * @param zneg cubemap face in the negative z direction
1012 * @param mips specifies desired mipmap behaviour for the cubemap
1013 * @param usage bit field specifying how the cubemap is utilized
1014 *
1015 * @return allocation containing cubemap data
1016 *
1017 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001018 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1019 Bitmap xpos,
1020 Bitmap xneg,
1021 Bitmap ypos,
1022 Bitmap yneg,
1023 Bitmap zpos,
1024 Bitmap zneg,
1025 MipmapControl mips,
1026 int usage) {
1027 int height = xpos.getHeight();
1028 if (xpos.getWidth() != height ||
1029 xneg.getWidth() != height || xneg.getHeight() != height ||
1030 ypos.getWidth() != height || ypos.getHeight() != height ||
1031 yneg.getWidth() != height || yneg.getHeight() != height ||
1032 zpos.getWidth() != height || zpos.getHeight() != height ||
1033 zneg.getWidth() != height || zneg.getHeight() != height) {
1034 throw new RSIllegalArgumentException("Only square cube map faces supported");
1035 }
1036 boolean isPow2 = (height & (height - 1)) == 0;
1037 if (!isPow2) {
1038 throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
1039 }
1040
1041 Element e = elementFromBitmap(rs, xpos);
1042 Type.Builder tb = new Type.Builder(rs, e);
1043 tb.setX(height);
1044 tb.setY(height);
1045 tb.setFaces(true);
1046 tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
1047 Type t = tb.create();
1048 Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
1049
1050 AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
1051 adapter.setFace(Type.CubemapFace.POSITVE_X);
1052 adapter.copyFrom(xpos);
1053 adapter.setFace(Type.CubemapFace.NEGATIVE_X);
1054 adapter.copyFrom(xneg);
1055 adapter.setFace(Type.CubemapFace.POSITVE_Y);
1056 adapter.copyFrom(ypos);
1057 adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
1058 adapter.copyFrom(yneg);
1059 adapter.setFace(Type.CubemapFace.POSITVE_Z);
1060 adapter.copyFrom(zpos);
1061 adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
1062 adapter.copyFrom(zneg);
1063
1064 return cubemap;
1065 }
1066
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001067 /**
1068 * Creates a non-mipmapped cubemap allocation for use as a
1069 * graphics texture from 6 bitmaps containing
1070 * the cube faces. All the faces must be the same size and
1071 * power of 2
1072 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001073 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001074 * @param xpos cubemap face in the positive x direction
1075 * @param xneg cubemap face in the negative x direction
1076 * @param ypos cubemap face in the positive y direction
1077 * @param yneg cubemap face in the negative y direction
1078 * @param zpos cubemap face in the positive z direction
1079 * @param zneg cubemap face in the negative z direction
1080 *
1081 * @return allocation containing cubemap data
1082 *
1083 */
Alex Sakhartchoukdcc23192011-01-11 14:47:44 -08001084 static public Allocation createCubemapFromCubeFaces(RenderScript rs,
1085 Bitmap xpos,
1086 Bitmap xneg,
1087 Bitmap ypos,
1088 Bitmap yneg,
1089 Bitmap zpos,
1090 Bitmap zneg) {
1091 return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
1092 zpos, zneg, MipmapControl.MIPMAP_NONE,
1093 USAGE_GRAPHICS_TEXTURE);
1094 }
1095
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001096 /**
1097 * Creates a renderscript allocation from the bitmap referenced
1098 * by resource id
1099 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001100 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001101 * @param res application resources
1102 * @param id resource id to load the data from
1103 * @param mips specifies desired mipmap behaviour for the
1104 * allocation
1105 * @param usage bit field specifying how the allocation is
1106 * utilized
1107 *
1108 * @return renderscript allocation containing resource data
1109 *
1110 */
Jason Sams5476b452010-12-08 16:14:36 -08001111 static public Allocation createFromBitmapResource(RenderScript rs,
1112 Resources res,
1113 int id,
Jason Sams4ef66502010-12-10 16:03:15 -08001114 MipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -08001115 int usage) {
Jason Samsb8c5a842009-07-31 20:40:47 -07001116
Jason Sams771bebb2009-12-07 12:40:12 -08001117 rs.validate();
Jason Sams5476b452010-12-08 16:14:36 -08001118 Bitmap b = BitmapFactory.decodeResource(res, id);
1119 Allocation alloc = createFromBitmap(rs, b, mips, usage);
1120 b.recycle();
1121 return alloc;
Jason Samsb8c5a842009-07-31 20:40:47 -07001122 }
1123
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001124 /**
1125 * Creates a non-mipmapped renderscript allocation to use as a
1126 * graphics texture from the bitmap referenced by resource id
1127 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001128 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001129 * @param res application resources
1130 * @param id resource id to load the data from
1131 *
1132 * @return renderscript allocation containing resource data
1133 *
1134 */
Jason Sams5476b452010-12-08 16:14:36 -08001135 static public Allocation createFromBitmapResource(RenderScript rs,
1136 Resources res,
Jason Sams6d8eb262010-12-15 01:41:00 -08001137 int id) {
1138 return createFromBitmapResource(rs, res, id,
1139 MipmapControl.MIPMAP_NONE,
1140 USAGE_GRAPHICS_TEXTURE);
1141 }
1142
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001143 /**
1144 * Creates a renderscript allocation containing string data
1145 * encoded in UTF-8 format
1146 *
Alex Sakhartchoukf5c876e2011-01-13 14:53:43 -08001147 * @param rs Context to which the allocation will belong.
Alex Sakhartchouk623c54d2011-01-12 17:32:36 -08001148 * @param str string to create the allocation from
1149 * @param usage bit field specifying how the allocaiton is
1150 * utilized
1151 *
1152 */
Jason Sams5476b452010-12-08 16:14:36 -08001153 static public Allocation createFromString(RenderScript rs,
1154 String str,
1155 int usage) {
1156 rs.validate();
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001157 byte[] allocArray = null;
1158 try {
1159 allocArray = str.getBytes("UTF-8");
Jason Sams5476b452010-12-08 16:14:36 -08001160 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
Jason Samsbf6ef8d72010-12-06 15:59:59 -08001161 alloc.copyFrom(allocArray);
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001162 return alloc;
1163 }
1164 catch (Exception e) {
Jason Sams06d69de2010-11-09 17:11:40 -08001165 throw new RSRuntimeException("Could not convert string to utf-8.");
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001166 }
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -07001167 }
Jason Samsb8c5a842009-07-31 20:40:47 -07001168}
1169
1170