blob: dfd6ac8a660556adcdb4405616f1a9a4d429ef92 [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;
21
22import android.content.res.Resources;
Romain Guy650a3eb2009-08-31 14:06:43 -070023import android.content.res.AssetManager;
Jason Samsb8c5a842009-07-31 20:40:47 -070024import android.graphics.Bitmap;
25import android.graphics.BitmapFactory;
Jason Samsb8c5a842009-07-31 20:40:47 -070026import android.util.Log;
Romain Guy650a3eb2009-08-31 14:06:43 -070027import android.util.TypedValue;
Jason Samsb8c5a842009-07-31 20:40:47 -070028
29/**
30 * @hide
31 *
32 **/
33public class Allocation extends BaseObj {
Jason Sams43ee06852009-08-12 17:54:11 -070034 Type mType;
Jason Sams8a647432010-03-01 15:31:04 -080035 Bitmap mBitmap;
Jason Sams43ee06852009-08-12 17:54:11 -070036
37 Allocation(int id, RenderScript rs, Type t) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -070038 super(id, rs);
Jason Sams43ee06852009-08-12 17:54:11 -070039 mType = t;
Jason Samsb8c5a842009-07-31 20:40:47 -070040 }
41
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -070042 Allocation(int id, RenderScript rs) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -070043 super(id, rs);
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -070044 }
45
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -070046 @Override
47 void updateFromNative() {
48 mRS.validate();
Alex Sakhartchoukfb10c162010-08-04 14:45:48 -070049 mName = mRS.nGetName(mID);
Alex Sakhartchoukdfac8142010-07-15 11:33:03 -070050 int typeID = mRS.nAllocationGetType(mID);
51 if(typeID != 0) {
52 mType = new Type(typeID, mRS);
53 mType.updateFromNative();
54 }
55 }
56
Jason Samsea87e962010-01-12 12:12:28 -080057 public Type getType() {
58 return mType;
59 }
60
Jason Samsb8c5a842009-07-31 20:40:47 -070061 public void uploadToTexture(int baseMipLevel) {
Jason Sams771bebb2009-12-07 12:40:12 -080062 mRS.validate();
Jason Samsc2908e62010-02-23 17:44:28 -080063 mRS.nAllocationUploadToTexture(mID, false, baseMipLevel);
64 }
65
66 public void uploadToTexture(boolean genMips, int baseMipLevel) {
67 mRS.validate();
68 mRS.nAllocationUploadToTexture(mID, genMips, baseMipLevel);
Jason Samsb8c5a842009-07-31 20:40:47 -070069 }
70
Jason Sams07ae4062009-08-27 20:23:34 -070071 public void uploadToBufferObject() {
Jason Sams771bebb2009-12-07 12:40:12 -080072 mRS.validate();
Jason Sams07ae4062009-08-27 20:23:34 -070073 mRS.nAllocationUploadToBufferObject(mID);
74 }
75
Jason Samsb8c5a842009-07-31 20:40:47 -070076 public void data(int[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -080077 mRS.validate();
Jason Sams768bc022009-09-21 19:41:04 -070078 subData1D(0, mType.getElementCount(), d);
79 }
80 public void data(short[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -080081 mRS.validate();
Jason Sams768bc022009-09-21 19:41:04 -070082 subData1D(0, mType.getElementCount(), d);
83 }
84 public void data(byte[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -080085 mRS.validate();
Jason Sams768bc022009-09-21 19:41:04 -070086 subData1D(0, mType.getElementCount(), d);
87 }
88 public void data(float[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -080089 mRS.validate();
Jason Sams768bc022009-09-21 19:41:04 -070090 subData1D(0, mType.getElementCount(), d);
Jason Samsb8c5a842009-07-31 20:40:47 -070091 }
92
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -070093 public void updateFromBitmap(Bitmap b)
94 throws IllegalArgumentException {
95
96 mRS.validate();
97 if(mType.getX() != b.getWidth() ||
98 mType.getY() != b.getHeight()) {
99 throw new IllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
100 }
101
102 mRS.nAllocationUpdateFromBitmap(mID, b);
103 }
104
Jason Sams49bdaf02010-08-31 13:50:42 -0700105 public void subData(int xoff, FieldPacker fp) {
Jason Samsa70f4162010-03-26 15:33:42 -0700106 int eSize = mType.mElement.getSizeBytes();
107 final byte[] data = fp.getData();
108
109 int count = data.length / eSize;
110 if ((eSize * count) != data.length) {
111 throw new IllegalArgumentException("Field packer length " + data.length +
112 " not divisible by element size " + eSize + ".");
113 }
Jason Sams49bdaf02010-08-31 13:50:42 -0700114 data1DChecks(xoff, count, data.length, data.length);
115 mRS.nAllocationSubData1D(mID, xoff, count, data, data.length);
116 }
117
118
119 public void subElementData(int xoff, int component_number, FieldPacker fp) {
120 if (component_number >= mType.mElement.mElements.length) {
121 throw new IllegalArgumentException("Component_number " + component_number + " out of range.");
122 }
123 if(xoff < 0) {
124 throw new IllegalArgumentException("Offset must be >= 0.");
125 }
126
127 final byte[] data = fp.getData();
128 int eSize = mType.mElement.mElements[component_number].getSizeBytes();
129
130 if (data.length != eSize) {
131 throw new IllegalArgumentException("Field packer sizelength " + data.length +
132 " does not match component size " + eSize + ".");
133 }
134
135 mRS.nAllocationSubElementData1D(mID, xoff, component_number, data, data.length);
Jason Samsa70f4162010-03-26 15:33:42 -0700136 }
137
Jason Sams768bc022009-09-21 19:41:04 -0700138 private void data1DChecks(int off, int count, int len, int dataSize) {
Jason Sams771bebb2009-12-07 12:40:12 -0800139 mRS.validate();
Jason Samsa70f4162010-03-26 15:33:42 -0700140 if(off < 0) {
141 throw new IllegalArgumentException("Offset must be >= 0.");
142 }
143 if(count < 1) {
144 throw new IllegalArgumentException("Count must be >= 1.");
145 }
146 if((off + count) > mType.getElementCount()) {
147 throw new IllegalArgumentException("Overflow, Available count " + mType.getElementCount() +
148 ", got " + count + " at offset " + off + ".");
Jason Sams07ae4062009-08-27 20:23:34 -0700149 }
Jason Sams768bc022009-09-21 19:41:04 -0700150 if((len) < dataSize) {
151 throw new IllegalArgumentException("Array too small for allocation type.");
152 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700153 }
154
155 public void subData1D(int off, int count, int[] d) {
Jason Sams768bc022009-09-21 19:41:04 -0700156 int dataSize = mType.mElement.getSizeBytes() * count;
157 data1DChecks(off, count, d.length * 4, dataSize);
158 mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
159 }
160 public void subData1D(int off, int count, short[] d) {
161 int dataSize = mType.mElement.getSizeBytes() * count;
162 data1DChecks(off, count, d.length * 2, dataSize);
163 mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
164 }
165 public void subData1D(int off, int count, byte[] d) {
166 int dataSize = mType.mElement.getSizeBytes() * count;
167 data1DChecks(off, count, d.length, dataSize);
168 mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
169 }
170 public void subData1D(int off, int count, float[] d) {
171 int dataSize = mType.mElement.getSizeBytes() * count;
172 data1DChecks(off, count, d.length * 4, dataSize);
173 mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
Jason Samsb8c5a842009-07-31 20:40:47 -0700174 }
175
Jason Sams768bc022009-09-21 19:41:04 -0700176
Jason Samsb8c5a842009-07-31 20:40:47 -0700177 public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800178 mRS.validate();
Jason Sams07ae4062009-08-27 20:23:34 -0700179 mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700180 }
181
182 public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800183 mRS.validate();
Jason Sams07ae4062009-08-27 20:23:34 -0700184 mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
Jason Samsb8c5a842009-07-31 20:40:47 -0700185 }
186
Jason Sams40a29e82009-08-10 14:55:26 -0700187 public void readData(int[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800188 mRS.validate();
Jason Sams40a29e82009-08-10 14:55:26 -0700189 mRS.nAllocationRead(mID, d);
190 }
191
192 public void readData(float[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800193 mRS.validate();
Jason Sams40a29e82009-08-10 14:55:26 -0700194 mRS.nAllocationRead(mID, d);
195 }
196
Jason Sams31a7e422010-10-26 13:09:17 -0700197 public synchronized void resize(int dimX) {
Jason Sams5edc6082010-10-05 13:32:49 -0700198 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
199 throw new IllegalStateException("Resize only support for 1D allocations at this time.");
200 }
201 mRS.nAllocationResize1D(mID, dimX);
Jason Samsd26297f2010-11-01 16:08:59 -0700202 mRS.finish(); // Necessary because resize is fifoed and update is async.
Jason Sams31a7e422010-10-26 13:09:17 -0700203
204 int typeID = mRS.nAllocationGetType(mID);
205 mType = new Type(typeID, mRS);
206 mType.updateFromNative();
Jason Sams5edc6082010-10-05 13:32:49 -0700207 }
208
209 /*
210 public void resize(int dimX, int dimY) {
211 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
212 throw new IllegalStateException("Resize only support for 2D allocations at this time.");
213 }
214 if (mType.getY() == 0) {
215 throw new IllegalStateException("Resize only support for 2D allocations at this time.");
216 }
217 mRS.nAllocationResize2D(mID, dimX, dimY);
218 }
219 */
Jason Sams40a29e82009-08-10 14:55:26 -0700220
Jason Samsb8c5a842009-07-31 20:40:47 -0700221 public class Adapter1D extends BaseObj {
222 Adapter1D(int id, RenderScript rs) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700223 super(id, rs);
Jason Samsb8c5a842009-07-31 20:40:47 -0700224 }
225
Jason Samsb8c5a842009-07-31 20:40:47 -0700226 public void setConstraint(Dimension dim, int value) {
Jason Sams771bebb2009-12-07 12:40:12 -0800227 mRS.validate();
Jason Samsb8c5a842009-07-31 20:40:47 -0700228 mRS.nAdapter1DSetConstraint(mID, dim.mID, value);
229 }
230
231 public void data(int[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800232 mRS.validate();
Jason Samsb8c5a842009-07-31 20:40:47 -0700233 mRS.nAdapter1DData(mID, d);
234 }
235
Jason Samsb8c5a842009-07-31 20:40:47 -0700236 public void data(float[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800237 mRS.validate();
Jason Samsb8c5a842009-07-31 20:40:47 -0700238 mRS.nAdapter1DData(mID, d);
239 }
240
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700241 public void subData(int off, int count, int[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800242 mRS.validate();
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700243 mRS.nAdapter1DSubData(mID, off, count, d);
244 }
245
Jason Samsb8c5a842009-07-31 20:40:47 -0700246 public void subData(int off, int count, float[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800247 mRS.validate();
Jason Samsb8c5a842009-07-31 20:40:47 -0700248 mRS.nAdapter1DSubData(mID, off, count, d);
249 }
250 }
251
252 public Adapter1D createAdapter1D() {
Jason Sams771bebb2009-12-07 12:40:12 -0800253 mRS.validate();
Jason Samsb8c5a842009-07-31 20:40:47 -0700254 int id = mRS.nAdapter1DCreate();
Jason Sams718cd1f2009-12-23 14:35:29 -0800255 if(id == 0) {
256 throw new IllegalStateException("allocation failed.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700257 }
Jason Sams718cd1f2009-12-23 14:35:29 -0800258 mRS.nAdapter1DBindAllocation(id, mID);
Jason Samsb8c5a842009-07-31 20:40:47 -0700259 return new Adapter1D(id, mRS);
260 }
261
262
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700263 public class Adapter2D extends BaseObj {
264 Adapter2D(int id, RenderScript rs) {
Alex Sakhartchouk0de94442010-08-11 14:41:28 -0700265 super(id, rs);
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700266 }
267
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700268 public void setConstraint(Dimension dim, int value) {
Jason Sams771bebb2009-12-07 12:40:12 -0800269 mRS.validate();
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700270 mRS.nAdapter2DSetConstraint(mID, dim.mID, value);
271 }
272
273 public void data(int[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800274 mRS.validate();
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700275 mRS.nAdapter2DData(mID, d);
276 }
277
278 public void data(float[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800279 mRS.validate();
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700280 mRS.nAdapter2DData(mID, d);
281 }
282
283 public void subData(int xoff, int yoff, int w, int h, int[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800284 mRS.validate();
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700285 mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
286 }
287
288 public void subData(int xoff, int yoff, int w, int h, float[] d) {
Jason Sams771bebb2009-12-07 12:40:12 -0800289 mRS.validate();
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700290 mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
291 }
292 }
293
294 public Adapter2D createAdapter2D() {
Jason Sams771bebb2009-12-07 12:40:12 -0800295 mRS.validate();
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700296 int id = mRS.nAdapter2DCreate();
Jason Sams718cd1f2009-12-23 14:35:29 -0800297 if(id == 0) {
298 throw new IllegalStateException("allocation failed.");
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700299 }
Jason Sams718cd1f2009-12-23 14:35:29 -0800300 mRS.nAdapter2DBindAllocation(id, mID);
Jason Samsbd1c3ad2009-08-03 16:03:08 -0700301 return new Adapter2D(id, mRS);
302 }
303
Jason Samsb8c5a842009-07-31 20:40:47 -0700304
305 // creation
306
307 private static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
308 static {
309 mBitmapOptions.inScaled = false;
310 }
311
Jason Sams1bada8c2009-08-09 17:01:55 -0700312 static public Allocation createTyped(RenderScript rs, Type type)
313 throws IllegalArgumentException {
314
Jason Sams771bebb2009-12-07 12:40:12 -0800315 rs.validate();
Jason Sams1bada8c2009-08-09 17:01:55 -0700316 if(type.mID == 0) {
317 throw new IllegalStateException("Bad Type");
318 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700319 int id = rs.nAllocationCreateTyped(type.mID);
Jason Sams43ee06852009-08-12 17:54:11 -0700320 return new Allocation(id, rs, type);
Jason Samsb8c5a842009-07-31 20:40:47 -0700321 }
322
Jason Sams1bada8c2009-08-09 17:01:55 -0700323 static public Allocation createSized(RenderScript rs, Element e, int count)
324 throws IllegalArgumentException {
325
Jason Sams771bebb2009-12-07 12:40:12 -0800326 rs.validate();
Jason Sams768bc022009-09-21 19:41:04 -0700327 Type.Builder b = new Type.Builder(rs, e);
328 b.add(Dimension.X, count);
329 Type t = b.create();
330
331 int id = rs.nAllocationCreateTyped(t.mID);
Jason Samsea84a7c2009-09-04 14:42:41 -0700332 if(id == 0) {
333 throw new IllegalStateException("Bad element.");
Jason Samsb8c5a842009-07-31 20:40:47 -0700334 }
Jason Sams768bc022009-09-21 19:41:04 -0700335 return new Allocation(id, rs, t);
Jason Samsb8c5a842009-07-31 20:40:47 -0700336 }
337
Jason Sams8a647432010-03-01 15:31:04 -0800338 static private Element elementFromBitmap(RenderScript rs, Bitmap b) {
339 final Bitmap.Config bc = b.getConfig();
340 if (bc == Bitmap.Config.ALPHA_8) {
341 return Element.A_8(rs);
342 }
343 if (bc == Bitmap.Config.ARGB_4444) {
344 return Element.RGBA_4444(rs);
345 }
346 if (bc == Bitmap.Config.ARGB_8888) {
347 return Element.RGBA_8888(rs);
348 }
349 if (bc == Bitmap.Config.RGB_565) {
350 return Element.RGB_565(rs);
351 }
352 throw new IllegalStateException("Bad bitmap type.");
353 }
354
355 static private Type typeFromBitmap(RenderScript rs, Bitmap b) {
356 Element e = elementFromBitmap(rs, b);
357 Type.Builder tb = new Type.Builder(rs, e);
358 tb.add(Dimension.X, b.getWidth());
359 tb.add(Dimension.Y, b.getHeight());
360 return tb.create();
361 }
362
Jason Samsb8c5a842009-07-31 20:40:47 -0700363 static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
364 throws IllegalArgumentException {
Jason Samsb8c5a842009-07-31 20:40:47 -0700365
Jason Sams771bebb2009-12-07 12:40:12 -0800366 rs.validate();
Jason Sams8a647432010-03-01 15:31:04 -0800367 Type t = typeFromBitmap(rs, b);
368
Jason Samsea84a7c2009-09-04 14:42:41 -0700369 int id = rs.nAllocationCreateFromBitmap(dstFmt.mID, genMips, b);
Jason Sams718cd1f2009-12-23 14:35:29 -0800370 if(id == 0) {
371 throw new IllegalStateException("Load failed.");
372 }
Jason Sams8a647432010-03-01 15:31:04 -0800373 return new Allocation(id, rs, t);
374 }
375
376 static public Allocation createBitmapRef(RenderScript rs, Bitmap b)
377 throws IllegalArgumentException {
378
379 rs.validate();
380 Type t = typeFromBitmap(rs, b);
381
382 int id = rs.nAllocationCreateBitmapRef(t.getID(), b);
383 if(id == 0) {
384 throw new IllegalStateException("Load failed.");
385 }
386
387 Allocation a = new Allocation(id, rs, t);
388 a.mBitmap = b;
389 return a;
Jason Samsb8c5a842009-07-31 20:40:47 -0700390 }
391
Jason Samsb8c5a842009-07-31 20:40:47 -0700392 static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
393 throws IllegalArgumentException {
394
Jason Sams771bebb2009-12-07 12:40:12 -0800395 rs.validate();
Romain Guy650a3eb2009-08-31 14:06:43 -0700396 InputStream is = null;
397 try {
398 final TypedValue value = new TypedValue();
399 is = res.openRawResource(id, value);
400
401 int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
Jason Samsea84a7c2009-09-04 14:42:41 -0700402 int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mID, genMips,
Romain Guy650a3eb2009-08-31 14:06:43 -0700403 asset);
404
Jason Sams718cd1f2009-12-23 14:35:29 -0800405 if(allocationId == 0) {
406 throw new IllegalStateException("Load failed.");
407 }
Jason Samsea84a7c2009-09-04 14:42:41 -0700408 return new Allocation(allocationId, rs, null);
Romain Guy650a3eb2009-08-31 14:06:43 -0700409 } catch (Exception e) {
410 // Ignore
411 } finally {
412 if (is != null) {
413 try {
414 is.close();
415 } catch (IOException e) {
416 // Ignore
417 }
418 }
419 }
420
421 return null;
Jason Samsb8c5a842009-07-31 20:40:47 -0700422 }
423
Alex Sakhartchouk9b949fc2010-06-24 17:15:34 -0700424 static public Allocation createFromString(RenderScript rs, String str)
425 throws IllegalArgumentException {
426 byte[] allocArray = null;
427 try {
428 allocArray = str.getBytes("UTF-8");
429 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length);
430 alloc.data(allocArray);
431 return alloc;
432 }
433 catch (Exception e) {
434 Log.e("rs", "could not convert string to utf-8");
435 }
436 return null;
437 }
Jason Samsb8c5a842009-07-31 20:40:47 -0700438}
439
440