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