RenderScript.java revision d176abf6992ea9b34a01ba1e8b232ac4ac08db31
1/*
2 * Copyright (C) 2013 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.support.v8.renderscript;
18
19import java.io.File;
20import java.lang.reflect.Field;
21import java.lang.reflect.Method;
22
23import android.content.Context;
24import android.content.pm.ApplicationInfo;
25import android.content.pm.PackageManager;
26import android.content.res.AssetManager;
27import android.graphics.Bitmap;
28import android.graphics.BitmapFactory;
29import android.os.Process;
30import android.util.Log;
31import android.view.Surface;
32
33import android.os.SystemProperties;
34
35/**
36 * This class provides access to a RenderScript context, which controls RenderScript
37 * initialization, resource management, and teardown. An instance of the RenderScript
38 * class must be created before any other RS objects can be created.
39 *
40 * <div class="special reference">
41 * <h3>Developer Guides</h3>
42 * <p>For more information about creating an application that uses RenderScript, read the
43 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
44 * </div>
45 **/
46public class RenderScript {
47    static final String LOG_TAG = "RenderScript_jni";
48    static final boolean DEBUG  = false;
49    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
50    static final boolean LOG_ENABLED = false;
51
52    private Context mApplicationContext;
53
54    /*
55     * We use a class initializer to allow the native code to cache some
56     * field offsets.
57     */
58    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
59    static boolean sInitialized;
60    static boolean sUseGCHooks;
61    static Object sRuntime;
62    static Method registerNativeAllocation;
63    static Method registerNativeFree;
64
65    static Object lock = new Object();
66
67    // Non-threadsafe functions.
68    native int  nDeviceCreate();
69    native void nDeviceDestroy(int dev);
70    native void nDeviceSetConfig(int dev, int param, int value);
71    native int nContextGetUserMessage(int con, int[] data);
72    native String nContextGetErrorMessage(int con);
73    native int  nContextPeekMessage(int con, int[] subID);
74    native void nContextInitToClient(int con);
75    native void nContextDeinitToClient(int con);
76
77    static boolean isNative = false;
78
79    private static int thunk = 0;
80    /**
81     * Determines whether or not we should be thunking into the native
82     * RenderScript layer or actually using the compatibility library.
83     */
84    static boolean shouldThunk() {
85        if (thunk == 0) {
86            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2
87                    && SystemProperties.getInt("debug.rs.forcecompat", 0) == 0) {
88                thunk = 1;
89            } else {
90                thunk = -1;
91            }
92        }
93        if (thunk == 1) {
94            return true;
95        }
96        return false;
97    }
98
99    /**
100     * Name of the file that holds the object cache.
101     */
102    private static final String CACHE_PATH = "com.android.renderscript.cache";
103    static String mCachePath;
104
105     /**
106     * Sets the directory to use as a persistent storage for the
107     * renderscript object file cache.
108     *
109     * @hide
110     * @param cacheDir A directory the current process can write to
111     */
112    public static void setupDiskCache(File cacheDir) {
113        File f = new File(cacheDir, CACHE_PATH);
114        mCachePath = f.getAbsolutePath();
115        f.mkdirs();
116    }
117
118    /**
119     * ContextType specifies the specific type of context to be created.
120     *
121     */
122    public enum ContextType {
123        /**
124         * NORMAL context, this is the default and what shipping apps should
125         * use.
126         */
127        NORMAL (0),
128
129        /**
130         * DEBUG context, perform extra runtime checks to validate the
131         * kernels and APIs are being used as intended.  Get and SetElementAt
132         * will be bounds checked in this mode.
133         */
134        DEBUG (1),
135
136        /**
137         * PROFILE context, Intended to be used once the first time an
138         * application is run on a new device.  This mode allows the runtime to
139         * do additional testing and performance tuning.
140         */
141        PROFILE (2);
142
143        int mID;
144        ContextType(int id) {
145            mID = id;
146        }
147    }
148
149    // Methods below are wrapped to protect the non-threadsafe
150    // lockless fifo.
151    native int  rsnContextCreate(int dev, int ver, int sdkVer, int contextType);
152    synchronized int nContextCreate(int dev, int ver, int sdkVer, int contextType) {
153        return rsnContextCreate(dev, ver, sdkVer, contextType);
154    }
155    native void rsnContextDestroy(int con);
156    synchronized void nContextDestroy() {
157        validate();
158        rsnContextDestroy(mContext);
159    }
160    native void rsnContextSetPriority(int con, int p);
161    synchronized void nContextSetPriority(int p) {
162        validate();
163        rsnContextSetPriority(mContext, p);
164    }
165    native void rsnContextDump(int con, int bits);
166    synchronized void nContextDump(int bits) {
167        validate();
168        rsnContextDump(mContext, bits);
169    }
170    native void rsnContextFinish(int con);
171    synchronized void nContextFinish() {
172        validate();
173        rsnContextFinish(mContext);
174    }
175
176    native void rsnContextSendMessage(int con, int id, int[] data);
177    synchronized void nContextSendMessage(int id, int[] data) {
178        validate();
179        rsnContextSendMessage(mContext, id, data);
180    }
181
182    native void rsnObjDestroy(int con, int id);
183    synchronized void nObjDestroy(int id) {
184        // There is a race condition here.  The calling code may be run
185        // by the gc while teardown is occuring.  This protects againts
186        // deleting dead objects.
187        if (mContext != 0) {
188            rsnObjDestroy(mContext, id);
189        }
190    }
191
192    native int  rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
193    synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
194        validate();
195        return rsnElementCreate(mContext, type, kind, norm, vecSize);
196    }
197    native int  rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
198    synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
199        validate();
200        return rsnElementCreate2(mContext, elements, names, arraySizes);
201    }
202    native void rsnElementGetNativeData(int con, int id, int[] elementData);
203    synchronized void nElementGetNativeData(int id, int[] elementData) {
204        validate();
205        rsnElementGetNativeData(mContext, id, elementData);
206    }
207    native void rsnElementGetSubElements(int con, int id,
208                                         int[] IDs, String[] names, int[] arraySizes);
209    synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) {
210        validate();
211        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
212    }
213
214    native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
215    synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
216        validate();
217        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
218    }
219    native void rsnTypeGetNativeData(int con, int id, int[] typeData);
220    synchronized void nTypeGetNativeData(int id, int[] typeData) {
221        validate();
222        rsnTypeGetNativeData(mContext, id, typeData);
223    }
224
225    native int  rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer);
226    synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) {
227        validate();
228        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
229    }
230    native int  rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
231    synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
232        validate();
233        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
234    }
235
236    native int  rsnAllocationCreateBitmapBackedAllocation(int con, int type, int mip, Bitmap bmp, int usage);
237    synchronized int nAllocationCreateBitmapBackedAllocation(int type, int mip, Bitmap bmp, int usage) {
238        validate();
239        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
240    }
241
242
243    native int  rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
244    synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
245        validate();
246        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
247    }
248    native int  rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
249    synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
250        validate();
251        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
252    }
253    native int  rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage);
254    synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
255        validate();
256        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
257    }
258
259    native void  rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
260    synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
261        validate();
262        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
263    }
264
265
266    native void rsnAllocationSyncAll(int con, int alloc, int src);
267    synchronized void nAllocationSyncAll(int alloc, int src) {
268        validate();
269        rsnAllocationSyncAll(mContext, alloc, src);
270    }
271    native void rsnAllocationIoSend(int con, int alloc);
272    synchronized void nAllocationIoSend(int alloc) {
273        validate();
274        rsnAllocationIoSend(mContext, alloc);
275    }
276    native void rsnAllocationIoReceive(int con, int alloc);
277    synchronized void nAllocationIoReceive(int alloc) {
278        validate();
279        rsnAllocationIoReceive(mContext, alloc);
280    }
281
282
283    native void rsnAllocationGenerateMipmaps(int con, int alloc);
284    synchronized void nAllocationGenerateMipmaps(int alloc) {
285        validate();
286        rsnAllocationGenerateMipmaps(mContext, alloc);
287    }
288    native void  rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
289    synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
290        validate();
291        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
292    }
293
294
295    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes);
296    synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) {
297        validate();
298        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
299    }
300    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes);
301    synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) {
302        validate();
303        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
304    }
305    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes);
306    synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) {
307        validate();
308        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
309    }
310    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes);
311    synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) {
312        validate();
313        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
314    }
315
316    native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
317    synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
318        validate();
319        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
320    }
321
322    native void rsnAllocationData2D(int con,
323                                    int dstAlloc, int dstXoff, int dstYoff,
324                                    int dstMip, int dstFace,
325                                    int width, int height,
326                                    int srcAlloc, int srcXoff, int srcYoff,
327                                    int srcMip, int srcFace);
328    synchronized void nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff,
329                                        int dstMip, int dstFace,
330                                        int width, int height,
331                                        int srcAlloc, int srcXoff, int srcYoff,
332                                        int srcMip, int srcFace) {
333        validate();
334        rsnAllocationData2D(mContext,
335                            dstAlloc, dstXoff, dstYoff,
336                            dstMip, dstFace,
337                            width, height,
338                            srcAlloc, srcXoff, srcYoff,
339                            srcMip, srcFace);
340    }
341
342    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes);
343    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) {
344        validate();
345        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
346    }
347    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes);
348    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) {
349        validate();
350        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
351    }
352    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes);
353    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) {
354        validate();
355        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
356    }
357    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes);
358    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) {
359        validate();
360        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
361    }
362    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b);
363    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) {
364        validate();
365        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
366    }
367
368    native void rsnAllocationData3D(int con,
369                                    int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
370                                    int dstMip,
371                                    int width, int height, int depth,
372                                    int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
373                                    int srcMip);
374    synchronized void nAllocationData3D(int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
375                                        int dstMip,
376                                        int width, int height, int depth,
377                                        int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
378                                        int srcMip) {
379        validate();
380        rsnAllocationData3D(mContext,
381                            dstAlloc, dstXoff, dstYoff, dstZoff,
382                            dstMip, width, height, depth,
383                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
384    }
385
386    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes);
387    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes) {
388        validate();
389        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
390    }
391    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes);
392    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes) {
393        validate();
394        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
395    }
396    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes);
397    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes) {
398        validate();
399        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
400    }
401    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes);
402    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes) {
403        validate();
404        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
405    }
406
407
408    native void rsnAllocationRead(int con, int id, byte[] d);
409    synchronized void nAllocationRead(int id, byte[] d) {
410        validate();
411        rsnAllocationRead(mContext, id, d);
412    }
413    native void rsnAllocationRead(int con, int id, short[] d);
414    synchronized void nAllocationRead(int id, short[] d) {
415        validate();
416        rsnAllocationRead(mContext, id, d);
417    }
418    native void rsnAllocationRead(int con, int id, int[] d);
419    synchronized void nAllocationRead(int id, int[] d) {
420        validate();
421        rsnAllocationRead(mContext, id, d);
422    }
423    native void rsnAllocationRead(int con, int id, float[] d);
424    synchronized void nAllocationRead(int id, float[] d) {
425        validate();
426        rsnAllocationRead(mContext, id, d);
427    }
428    native int  rsnAllocationGetType(int con, int id);
429    synchronized int nAllocationGetType(int id) {
430        validate();
431        return rsnAllocationGetType(mContext, id);
432    }
433
434    native void rsnAllocationResize1D(int con, int id, int dimX);
435    synchronized void nAllocationResize1D(int id, int dimX) {
436        validate();
437        rsnAllocationResize1D(mContext, id, dimX);
438    }
439    native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
440    synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
441        validate();
442        rsnAllocationResize2D(mContext, id, dimX, dimY);
443    }
444
445    native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
446    synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
447        validate();
448        rsnScriptBindAllocation(mContext, script, alloc, slot);
449    }
450    native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
451    synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
452        validate();
453        rsnScriptSetTimeZone(mContext, script, timeZone);
454    }
455    native void rsnScriptInvoke(int con, int id, int slot);
456    synchronized void nScriptInvoke(int id, int slot) {
457        validate();
458        rsnScriptInvoke(mContext, id, slot);
459    }
460    native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params);
461    native void rsnScriptForEach(int con, int id, int slot, int ain, int aout);
462    native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, byte[] params,
463                                        int xstart, int xend, int ystart, int yend, int zstart, int zend);
464    native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout,
465                                        int xstart, int xend, int ystart, int yend, int zstart, int zend);
466    synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) {
467        validate();
468        if (params == null) {
469            rsnScriptForEach(mContext, id, slot, ain, aout);
470        } else {
471            rsnScriptForEach(mContext, id, slot, ain, aout, params);
472        }
473    }
474
475    synchronized void nScriptForEachClipped(int id, int slot, int ain, int aout, byte[] params,
476                                            int xstart, int xend, int ystart, int yend, int zstart, int zend) {
477        validate();
478        if (params == null) {
479            rsnScriptForEachClipped(mContext, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend);
480        } else {
481            rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend);
482        }
483    }
484
485    native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
486    synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
487        validate();
488        rsnScriptInvokeV(mContext, id, slot, params);
489    }
490    native void rsnScriptSetVarI(int con, int id, int slot, int val);
491    synchronized void nScriptSetVarI(int id, int slot, int val) {
492        validate();
493        rsnScriptSetVarI(mContext, id, slot, val);
494    }
495    native void rsnScriptSetVarJ(int con, int id, int slot, long val);
496    synchronized void nScriptSetVarJ(int id, int slot, long val) {
497        validate();
498        rsnScriptSetVarJ(mContext, id, slot, val);
499    }
500    native void rsnScriptSetVarF(int con, int id, int slot, float val);
501    synchronized void nScriptSetVarF(int id, int slot, float val) {
502        validate();
503        rsnScriptSetVarF(mContext, id, slot, val);
504    }
505    native void rsnScriptSetVarD(int con, int id, int slot, double val);
506    synchronized void nScriptSetVarD(int id, int slot, double val) {
507        validate();
508        rsnScriptSetVarD(mContext, id, slot, val);
509    }
510    native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
511    synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
512        validate();
513        rsnScriptSetVarV(mContext, id, slot, val);
514    }
515    native void rsnScriptSetVarVE(int con, int id, int slot, byte[] val,
516                                  int e, int[] dims);
517    synchronized void nScriptSetVarVE(int id, int slot, byte[] val,
518                                      int e, int[] dims) {
519        validate();
520        rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
521    }
522    native void rsnScriptSetVarObj(int con, int id, int slot, int val);
523    synchronized void nScriptSetVarObj(int id, int slot, int val) {
524        validate();
525        rsnScriptSetVarObj(mContext, id, slot, val);
526    }
527
528    native int  rsnScriptCCreate(int con, String resName, String cacheDir,
529                                 byte[] script, int length);
530    synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
531        validate();
532        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
533    }
534
535    native int  rsnScriptIntrinsicCreate(int con, int id, int eid);
536    synchronized int nScriptIntrinsicCreate(int id, int eid) {
537        validate();
538        return rsnScriptIntrinsicCreate(mContext, id, eid);
539    }
540
541    native int  rsnScriptKernelIDCreate(int con, int sid, int slot, int sig);
542    synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) {
543        validate();
544        return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
545    }
546
547    native int  rsnScriptFieldIDCreate(int con, int sid, int slot);
548    synchronized int nScriptFieldIDCreate(int sid, int slot) {
549        validate();
550        return rsnScriptFieldIDCreate(mContext, sid, slot);
551    }
552
553    native int  rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
554    synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
555        validate();
556        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
557    }
558
559    native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc);
560    synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) {
561        validate();
562        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
563    }
564
565    native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc);
566    synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) {
567        validate();
568        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
569    }
570
571    native void rsnScriptGroupExecute(int con, int group);
572    synchronized void nScriptGroupExecute(int group) {
573        validate();
574        rsnScriptGroupExecute(mContext, group);
575    }
576
577    native int  rsnSamplerCreate(int con, int magFilter, int minFilter,
578                                 int wrapS, int wrapT, int wrapR, float aniso);
579    synchronized int nSamplerCreate(int magFilter, int minFilter,
580                                 int wrapS, int wrapT, int wrapR, float aniso) {
581        validate();
582        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
583    }
584
585
586
587    int     mDev;
588    int     mContext;
589    @SuppressWarnings({"FieldCanBeLocal"})
590    MessageThread mMessageThread;
591
592    Element mElement_U8;
593    Element mElement_I8;
594    Element mElement_U16;
595    Element mElement_I16;
596    Element mElement_U32;
597    Element mElement_I32;
598    Element mElement_U64;
599    Element mElement_I64;
600    Element mElement_F32;
601    Element mElement_F64;
602    Element mElement_BOOLEAN;
603
604    Element mElement_ELEMENT;
605    Element mElement_TYPE;
606    Element mElement_ALLOCATION;
607    Element mElement_SAMPLER;
608    Element mElement_SCRIPT;
609
610    Element mElement_A_8;
611    Element mElement_RGB_565;
612    Element mElement_RGB_888;
613    Element mElement_RGBA_5551;
614    Element mElement_RGBA_4444;
615    Element mElement_RGBA_8888;
616
617    Element mElement_FLOAT_2;
618    Element mElement_FLOAT_3;
619    Element mElement_FLOAT_4;
620
621    Element mElement_DOUBLE_2;
622    Element mElement_DOUBLE_3;
623    Element mElement_DOUBLE_4;
624
625    Element mElement_UCHAR_2;
626    Element mElement_UCHAR_3;
627    Element mElement_UCHAR_4;
628
629    Element mElement_CHAR_2;
630    Element mElement_CHAR_3;
631    Element mElement_CHAR_4;
632
633    Element mElement_USHORT_2;
634    Element mElement_USHORT_3;
635    Element mElement_USHORT_4;
636
637    Element mElement_SHORT_2;
638    Element mElement_SHORT_3;
639    Element mElement_SHORT_4;
640
641    Element mElement_UINT_2;
642    Element mElement_UINT_3;
643    Element mElement_UINT_4;
644
645    Element mElement_INT_2;
646    Element mElement_INT_3;
647    Element mElement_INT_4;
648
649    Element mElement_ULONG_2;
650    Element mElement_ULONG_3;
651    Element mElement_ULONG_4;
652
653    Element mElement_LONG_2;
654    Element mElement_LONG_3;
655    Element mElement_LONG_4;
656
657    Element mElement_MATRIX_4X4;
658    Element mElement_MATRIX_3X3;
659    Element mElement_MATRIX_2X2;
660
661    Sampler mSampler_CLAMP_NEAREST;
662    Sampler mSampler_CLAMP_LINEAR;
663    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
664    Sampler mSampler_WRAP_NEAREST;
665    Sampler mSampler_WRAP_LINEAR;
666    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
667    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
668    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
669    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
670
671
672    ///////////////////////////////////////////////////////////////////////////////////
673    //
674
675    /**
676     * The base class from which an application should derive in order
677     * to receive RS messages from scripts. When a script calls {@code
678     * rsSendToClient}, the data fields will be filled, and the run
679     * method will be called on a separate thread.  This will occur
680     * some time after {@code rsSendToClient} completes in the script,
681     * as {@code rsSendToClient} is asynchronous. Message handlers are
682     * not guaranteed to have completed when {@link
683     * android.support.v8.renderscript.RenderScript#finish} returns.
684     *
685     */
686    public static class RSMessageHandler implements Runnable {
687        protected int[] mData;
688        protected int mID;
689        protected int mLength;
690        public void run() {
691        }
692    }
693    /**
694     * If an application is expecting messages, it should set this
695     * field to an instance of {@link RSMessageHandler}.  This
696     * instance will receive all the user messages sent from {@code
697     * sendToClient} by scripts from this context.
698     *
699     */
700    RSMessageHandler mMessageCallback = null;
701
702    public void setMessageHandler(RSMessageHandler msg) {
703        mMessageCallback = msg;
704        if (isNative) {
705            RenderScriptThunker rst = (RenderScriptThunker) this;
706            android.renderscript.RenderScript.RSMessageHandler newmsg =
707                new android.renderscript.RenderScript.RSMessageHandler() {
708                    public void run()  {
709                        mMessageCallback.mData = mData;
710                        mMessageCallback.mID = mID;
711                        mMessageCallback.mLength = mLength;
712                        mMessageCallback.run();
713                    }
714                };
715            rst.mN.setMessageHandler(newmsg);
716        }
717    }
718    public RSMessageHandler getMessageHandler() {
719        return mMessageCallback;
720    }
721
722    /**
723     * Place a message into the message queue to be sent back to the message
724     * handler once all previous commands have been executed.
725     *
726     * @hide
727     *
728     * @param id
729     * @param data
730     */
731    public void sendMessage(int id, int[] data) {
732        nContextSendMessage(id, data);
733    }
734
735    /**
736     * The runtime error handler base class.  An application should derive from this class
737     * if it wishes to install an error handler.  When errors occur at runtime,
738     * the fields in this class will be filled, and the run method will be called.
739     *
740     */
741    public static class RSErrorHandler implements Runnable {
742        protected String mErrorMessage;
743        protected int mErrorNum;
744        public void run() {
745        }
746    }
747
748    /**
749     * Application Error handler.  All runtime errors will be dispatched to the
750     * instance of RSAsyncError set here.  If this field is null a
751     * {@link RSRuntimeException} will instead be thrown with details about the error.
752     * This will cause program termaination.
753     *
754     */
755    RSErrorHandler mErrorCallback = null;
756
757    public void setErrorHandler(RSErrorHandler msg) {
758        mErrorCallback = msg;
759        if (isNative) {
760            RenderScriptThunker rst = (RenderScriptThunker) this;
761            android.renderscript.RenderScript.RSErrorHandler newmsg =
762                new android.renderscript.RenderScript.RSErrorHandler() {
763                    public void run()  {
764                        mErrorCallback.mErrorMessage = mErrorMessage;
765                        mErrorCallback.mErrorNum = mErrorNum;
766                        mErrorCallback.run();
767                    }
768                };
769            rst.mN.setErrorHandler(newmsg);
770        }
771    }
772    public RSErrorHandler getErrorHandler() {
773        return mErrorCallback;
774    }
775
776    /**
777     * RenderScript worker thread priority enumeration.  The default value is
778     * NORMAL.  Applications wishing to do background processing should set
779     * their priority to LOW to avoid starving forground processes.
780     */
781    public enum Priority {
782        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
783        NORMAL (Process.THREAD_PRIORITY_DISPLAY);
784
785        int mID;
786        Priority(int id) {
787            mID = id;
788        }
789    }
790
791    void validate() {
792        if (mContext == 0) {
793            throw new RSInvalidStateException("Calling RS with no Context active.");
794        }
795    }
796
797
798    /**
799     * Change the priority of the worker threads for this context.
800     *
801     * @param p New priority to be set.
802     */
803    public void setPriority(Priority p) {
804        validate();
805        nContextSetPriority(p.mID);
806    }
807
808    static class MessageThread extends Thread {
809        RenderScript mRS;
810        boolean mRun = true;
811        int[] mAuxData = new int[2];
812
813        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
814        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
815        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
816        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
817        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
818
819        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
820
821        MessageThread(RenderScript rs) {
822            super("RSMessageThread");
823            mRS = rs;
824
825        }
826
827        public void run() {
828            // This function is a temporary solution.  The final solution will
829            // used typed allocations where the message id is the type indicator.
830            int[] rbuf = new int[16];
831            mRS.nContextInitToClient(mRS.mContext);
832            while(mRun) {
833                rbuf[0] = 0;
834                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
835                int size = mAuxData[1];
836                int subID = mAuxData[0];
837
838                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
839                    if ((size>>2) >= rbuf.length) {
840                        rbuf = new int[(size + 3) >> 2];
841                    }
842                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
843                        RS_MESSAGE_TO_CLIENT_USER) {
844                        throw new RSDriverException("Error processing message from RenderScript.");
845                    }
846
847                    if(mRS.mMessageCallback != null) {
848                        mRS.mMessageCallback.mData = rbuf;
849                        mRS.mMessageCallback.mID = subID;
850                        mRS.mMessageCallback.mLength = size;
851                        mRS.mMessageCallback.run();
852                    } else {
853                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
854                    }
855                    continue;
856                }
857
858                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
859                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
860
861                    if (subID >= RS_ERROR_FATAL_UNKNOWN) {
862                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
863                    }
864
865                    if(mRS.mErrorCallback != null) {
866                        mRS.mErrorCallback.mErrorMessage = e;
867                        mRS.mErrorCallback.mErrorNum = subID;
868                        mRS.mErrorCallback.run();
869                    } else {
870                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
871                        // Do not throw here. In these cases, we do not have
872                        // a fatal error.
873                    }
874                    continue;
875                }
876
877                // 2: teardown.
878                // But we want to avoid starving other threads during
879                // teardown by yielding until the next line in the destructor
880                // can execute to set mRun = false
881                try {
882                    sleep(1, 0);
883                } catch(InterruptedException e) {
884                }
885            }
886            //Log.d(LOG_TAG, "MessageThread exiting.");
887        }
888    }
889
890    RenderScript(Context ctx) {
891        if (ctx != null) {
892            mApplicationContext = ctx.getApplicationContext();
893        }
894    }
895
896    /**
897     * Gets the application context associated with the RenderScript context.
898     *
899     * @return The application context.
900     */
901    public final Context getApplicationContext() {
902        return mApplicationContext;
903    }
904
905    /**
906     * @hide
907     */
908    public static RenderScript create(Context ctx, int sdkVersion) {
909        return create(ctx, sdkVersion, ContextType.NORMAL);
910    }
911
912    /**
913     * Create a RenderScript context.
914     *
915     * @hide
916     * @param ctx The context.
917     * @return RenderScript
918     */
919    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
920        RenderScript rs = new RenderScript(ctx);
921
922        if (shouldThunk()) {
923            android.util.Log.v(LOG_TAG, "RS native mode");
924            return RenderScriptThunker.create(ctx, sdkVersion);
925        }
926        synchronized(lock) {
927            if (sInitialized == false) {
928                try {
929                    Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
930                    Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
931                    sRuntime = get_runtime.invoke(null);
932                    registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
933                    registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
934                    sUseGCHooks = true;
935                } catch (Exception e) {
936                    Log.e(LOG_TAG, "No GC methods");
937                    sUseGCHooks = false;
938                }
939                try {
940                    System.loadLibrary("RSSupport");
941                    System.loadLibrary("rsjni");
942                    sInitialized = true;
943                } catch (UnsatisfiedLinkError e) {
944                    Log.e(LOG_TAG, "Error loading RS jni library: " + e);
945                    throw new RSRuntimeException("Error loading RS jni library: " + e);
946                }
947            }
948        }
949
950        android.util.Log.v(LOG_TAG, "RS compat mode");
951        rs.mDev = rs.nDeviceCreate();
952        rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID);
953        if (rs.mContext == 0) {
954            throw new RSDriverException("Failed to create RS context.");
955        }
956        rs.mMessageThread = new MessageThread(rs);
957        rs.mMessageThread.start();
958        return rs;
959    }
960
961    /**
962     * Create a RenderScript context.
963     *
964     * @param ctx The context.
965     * @return RenderScript
966     */
967    public static RenderScript create(Context ctx) {
968        return create(ctx, ContextType.NORMAL);
969    }
970
971    /**
972     * Create a RenderScript context.
973     *
974     * @hide
975     *
976     * @param ctx The context.
977     * @param ct The type of context to be created.
978     * @return RenderScript
979     */
980    public static RenderScript create(Context ctx, ContextType ct) {
981        int v = ctx.getApplicationInfo().targetSdkVersion;
982        return create(ctx, v, ct);
983    }
984
985    /**
986     * Print the currently available debugging information about the state of
987     * the RS context to the log.
988     *
989     */
990    public void contextDump() {
991        validate();
992        nContextDump(0);
993    }
994
995    /**
996     * Wait for any pending asynchronous opeations (such as copies to a RS
997     * allocation or RS script executions) to complete.
998     *
999     */
1000    public void finish() {
1001        nContextFinish();
1002    }
1003
1004    /**
1005     * Destroys this RenderScript context.  Once this function is called,
1006     * using this context or any objects belonging to this context is
1007     * illegal.
1008     *
1009     */
1010    public void destroy() {
1011        validate();
1012        nContextDeinitToClient(mContext);
1013        mMessageThread.mRun = false;
1014        try {
1015            mMessageThread.join();
1016        } catch(InterruptedException e) {
1017        }
1018
1019        nContextDestroy();
1020        mContext = 0;
1021
1022        nDeviceDestroy(mDev);
1023        mDev = 0;
1024    }
1025
1026    boolean isAlive() {
1027        return mContext != 0;
1028    }
1029
1030    int safeID(BaseObj o) {
1031        if(o != null) {
1032            return o.getID(this);
1033        }
1034        return 0;
1035    }
1036}
1037