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