Allocation.java revision 49bdaf0293408159df18a1d8540360f9623c40f7
1/*
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
19import java.io.IOException;
20import java.io.InputStream;
21
22import android.content.res.Resources;
23import android.content.res.AssetManager;
24import android.graphics.Bitmap;
25import android.graphics.BitmapFactory;
26import android.util.Log;
27import android.util.TypedValue;
28
29/**
30 * @hide
31 *
32 **/
33public class Allocation extends BaseObj {
34    Type mType;
35    Bitmap mBitmap;
36
37    Allocation(int id, RenderScript rs, Type t) {
38        super(id, rs);
39        mType = t;
40    }
41
42    Allocation(int id, RenderScript rs) {
43        super(id, rs);
44    }
45
46    @Override
47    void updateFromNative() {
48        mRS.validate();
49        mName = mRS.nGetName(mID);
50        int typeID = mRS.nAllocationGetType(mID);
51        if(typeID != 0) {
52            mType = new Type(typeID, mRS);
53            mType.updateFromNative();
54        }
55    }
56
57    public Type getType() {
58        return mType;
59    }
60
61    public void uploadToTexture(int baseMipLevel) {
62        mRS.validate();
63        mRS.nAllocationUploadToTexture(mID, false, baseMipLevel);
64    }
65
66    public void uploadToTexture(boolean genMips, int baseMipLevel) {
67        mRS.validate();
68        mRS.nAllocationUploadToTexture(mID, genMips, baseMipLevel);
69    }
70
71    public void uploadToBufferObject() {
72        mRS.validate();
73        mRS.nAllocationUploadToBufferObject(mID);
74    }
75
76    public void data(int[] d) {
77        mRS.validate();
78        subData1D(0, mType.getElementCount(), d);
79    }
80    public void data(short[] d) {
81        mRS.validate();
82        subData1D(0, mType.getElementCount(), d);
83    }
84    public void data(byte[] d) {
85        mRS.validate();
86        subData1D(0, mType.getElementCount(), d);
87    }
88    public void data(float[] d) {
89        mRS.validate();
90        subData1D(0, mType.getElementCount(), d);
91    }
92
93    public void subData(int xoff, FieldPacker fp) {
94        int eSize = mType.mElement.getSizeBytes();
95        final byte[] data = fp.getData();
96
97        int count = data.length / eSize;
98        if ((eSize * count) != data.length) {
99            throw new IllegalArgumentException("Field packer length " + data.length +
100                                               " not divisible by element size " + eSize + ".");
101        }
102        data1DChecks(xoff, count, data.length, data.length);
103        mRS.nAllocationSubData1D(mID, xoff, count, data, data.length);
104    }
105
106
107    public void subElementData(int xoff, int component_number, FieldPacker fp) {
108        if (component_number >= mType.mElement.mElements.length) {
109            throw new IllegalArgumentException("Component_number " + component_number + " out of range.");
110        }
111        if(xoff < 0) {
112            throw new IllegalArgumentException("Offset must be >= 0.");
113        }
114
115        final byte[] data = fp.getData();
116        int eSize = mType.mElement.mElements[component_number].getSizeBytes();
117
118        if (data.length != eSize) {
119            throw new IllegalArgumentException("Field packer sizelength " + data.length +
120                                               " does not match component size " + eSize + ".");
121        }
122
123        mRS.nAllocationSubElementData1D(mID, xoff, component_number, data, data.length);
124    }
125
126    private void data1DChecks(int off, int count, int len, int dataSize) {
127        mRS.validate();
128        if(off < 0) {
129            throw new IllegalArgumentException("Offset must be >= 0.");
130        }
131        if(count < 1) {
132            throw new IllegalArgumentException("Count must be >= 1.");
133        }
134        if((off + count) > mType.getElementCount()) {
135            throw new IllegalArgumentException("Overflow, Available count " + mType.getElementCount() +
136                                               ", got " + count + " at offset " + off + ".");
137        }
138        if((len) < dataSize) {
139            throw new IllegalArgumentException("Array too small for allocation type.");
140        }
141    }
142
143    public void subData1D(int off, int count, int[] d) {
144        int dataSize = mType.mElement.getSizeBytes() * count;
145        data1DChecks(off, count, d.length * 4, dataSize);
146        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
147    }
148    public void subData1D(int off, int count, short[] d) {
149        int dataSize = mType.mElement.getSizeBytes() * count;
150        data1DChecks(off, count, d.length * 2, dataSize);
151        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
152    }
153    public void subData1D(int off, int count, byte[] d) {
154        int dataSize = mType.mElement.getSizeBytes() * count;
155        data1DChecks(off, count, d.length, dataSize);
156        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
157    }
158    public void subData1D(int off, int count, float[] d) {
159        int dataSize = mType.mElement.getSizeBytes() * count;
160        data1DChecks(off, count, d.length * 4, dataSize);
161        mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
162    }
163
164
165
166    public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
167        mRS.validate();
168        mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
169    }
170
171    public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
172        mRS.validate();
173        mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
174    }
175
176    public void readData(int[] d) {
177        mRS.validate();
178        mRS.nAllocationRead(mID, d);
179    }
180
181    public void readData(float[] d) {
182        mRS.validate();
183        mRS.nAllocationRead(mID, d);
184    }
185
186    public void data(Object o) {
187        mRS.validate();
188        mRS.nAllocationSubDataFromObject(mID, mType, 0, o);
189    }
190
191    public void read(Object o) {
192        mRS.validate();
193        mRS.nAllocationSubReadFromObject(mID, mType, 0, o);
194    }
195
196    public void subData(int offset, Object o) {
197        mRS.validate();
198        mRS.nAllocationSubDataFromObject(mID, mType, offset, o);
199    }
200
201    public class Adapter1D extends BaseObj {
202        Adapter1D(int id, RenderScript rs) {
203            super(id, rs);
204        }
205
206        public void setConstraint(Dimension dim, int value) {
207            mRS.validate();
208            mRS.nAdapter1DSetConstraint(mID, dim.mID, value);
209        }
210
211        public void data(int[] d) {
212            mRS.validate();
213            mRS.nAdapter1DData(mID, d);
214        }
215
216        public void data(float[] d) {
217            mRS.validate();
218            mRS.nAdapter1DData(mID, d);
219        }
220
221        public void subData(int off, int count, int[] d) {
222            mRS.validate();
223            mRS.nAdapter1DSubData(mID, off, count, d);
224        }
225
226        public void subData(int off, int count, float[] d) {
227            mRS.validate();
228            mRS.nAdapter1DSubData(mID, off, count, d);
229        }
230    }
231
232    public Adapter1D createAdapter1D() {
233        mRS.validate();
234        int id = mRS.nAdapter1DCreate();
235        if(id == 0) {
236            throw new IllegalStateException("allocation failed.");
237        }
238        mRS.nAdapter1DBindAllocation(id, mID);
239        return new Adapter1D(id, mRS);
240    }
241
242
243    public class Adapter2D extends BaseObj {
244        Adapter2D(int id, RenderScript rs) {
245            super(id, rs);
246        }
247
248        public void setConstraint(Dimension dim, int value) {
249            mRS.validate();
250            mRS.nAdapter2DSetConstraint(mID, dim.mID, value);
251        }
252
253        public void data(int[] d) {
254            mRS.validate();
255            mRS.nAdapter2DData(mID, d);
256        }
257
258        public void data(float[] d) {
259            mRS.validate();
260            mRS.nAdapter2DData(mID, d);
261        }
262
263        public void subData(int xoff, int yoff, int w, int h, int[] d) {
264            mRS.validate();
265            mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
266        }
267
268        public void subData(int xoff, int yoff, int w, int h, float[] d) {
269            mRS.validate();
270            mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
271        }
272    }
273
274    public Adapter2D createAdapter2D() {
275        mRS.validate();
276        int id = mRS.nAdapter2DCreate();
277        if(id == 0) {
278            throw new IllegalStateException("allocation failed.");
279        }
280        mRS.nAdapter2DBindAllocation(id, mID);
281        return new Adapter2D(id, mRS);
282    }
283
284
285    // creation
286
287    private static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
288    static {
289        mBitmapOptions.inScaled = false;
290    }
291
292    static public Allocation createTyped(RenderScript rs, Type type)
293        throws IllegalArgumentException {
294
295        rs.validate();
296        if(type.mID == 0) {
297            throw new IllegalStateException("Bad Type");
298        }
299        int id = rs.nAllocationCreateTyped(type.mID);
300        return new Allocation(id, rs, type);
301    }
302
303    static public Allocation createSized(RenderScript rs, Element e, int count)
304        throws IllegalArgumentException {
305
306        rs.validate();
307        Type.Builder b = new Type.Builder(rs, e);
308        b.add(Dimension.X, count);
309        Type t = b.create();
310
311        int id = rs.nAllocationCreateTyped(t.mID);
312        if(id == 0) {
313            throw new IllegalStateException("Bad element.");
314        }
315        return new Allocation(id, rs, t);
316    }
317
318    static private Element elementFromBitmap(RenderScript rs, Bitmap b) {
319        final Bitmap.Config bc = b.getConfig();
320        if (bc == Bitmap.Config.ALPHA_8) {
321            return Element.A_8(rs);
322        }
323        if (bc == Bitmap.Config.ARGB_4444) {
324            return Element.RGBA_4444(rs);
325        }
326        if (bc == Bitmap.Config.ARGB_8888) {
327            return Element.RGBA_8888(rs);
328        }
329        if (bc == Bitmap.Config.RGB_565) {
330            return Element.RGB_565(rs);
331        }
332        throw new IllegalStateException("Bad bitmap type.");
333    }
334
335    static private Type typeFromBitmap(RenderScript rs, Bitmap b) {
336        Element e = elementFromBitmap(rs, b);
337        Type.Builder tb = new Type.Builder(rs, e);
338        tb.add(Dimension.X, b.getWidth());
339        tb.add(Dimension.Y, b.getHeight());
340        return tb.create();
341    }
342
343    static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
344        throws IllegalArgumentException {
345
346        rs.validate();
347        Type t = typeFromBitmap(rs, b);
348
349        int id = rs.nAllocationCreateFromBitmap(dstFmt.mID, genMips, b);
350        if(id == 0) {
351            throw new IllegalStateException("Load failed.");
352        }
353        return new Allocation(id, rs, t);
354    }
355
356    static public Allocation createBitmapRef(RenderScript rs, Bitmap b)
357        throws IllegalArgumentException {
358
359        rs.validate();
360        Type t = typeFromBitmap(rs, b);
361
362        int id = rs.nAllocationCreateBitmapRef(t.getID(), b);
363        if(id == 0) {
364            throw new IllegalStateException("Load failed.");
365        }
366
367        Allocation a = new Allocation(id, rs, t);
368        a.mBitmap = b;
369        return a;
370    }
371
372    static Allocation createFromBitmapBoxed(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
373        throws IllegalArgumentException {
374
375        rs.validate();
376        int id = rs.nAllocationCreateFromBitmapBoxed(dstFmt.mID, genMips, b);
377        if(id == 0) {
378            throw new IllegalStateException("Load failed.");
379        }
380        return new Allocation(id, rs, null);
381    }
382
383    static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
384        throws IllegalArgumentException {
385
386        rs.validate();
387        InputStream is = null;
388        try {
389            final TypedValue value = new TypedValue();
390            is = res.openRawResource(id, value);
391
392            int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
393            int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mID, genMips,
394                    asset);
395
396            if(allocationId == 0) {
397                throw new IllegalStateException("Load failed.");
398            }
399            return new Allocation(allocationId, rs, null);
400        } catch (Exception e) {
401            // Ignore
402        } finally {
403            if (is != null) {
404                try {
405                    is.close();
406                } catch (IOException e) {
407                    // Ignore
408                }
409            }
410        }
411
412        return null;
413    }
414
415    static public Allocation createFromBitmapResourceBoxed(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
416        throws IllegalArgumentException {
417
418        mBitmapOptions.inPreferredConfig = null;
419        if (dstFmt == rs.mElement_RGBA_8888) {
420            mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
421        } else if (dstFmt == rs.mElement_RGB_888) {
422            mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
423        } else if (dstFmt == rs.mElement_RGBA_4444) {
424            mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
425        } else if (dstFmt == rs.mElement_RGB_565) {
426            mBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
427        }
428
429        Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions);
430        return createFromBitmapBoxed(rs, b, dstFmt, genMips);
431    }
432
433    static public Allocation createFromString(RenderScript rs, String str)
434        throws IllegalArgumentException {
435        byte[] allocArray = null;
436        try {
437            allocArray = str.getBytes("UTF-8");
438            Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length);
439            alloc.data(allocArray);
440            return alloc;
441        }
442        catch (Exception e) {
443            Log.e("rs", "could not convert string to utf-8");
444        }
445        return null;
446    }
447}
448
449
450