RenderScript.java revision 6f5555db1af436bb5aad430e6e00aa5b69d5ca6c
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;
22import java.util.concurrent.locks.ReentrantReadWriteLock;
23
24import android.content.Context;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.PackageManager;
27import android.content.res.AssetManager;
28import android.graphics.Bitmap;
29import android.graphics.BitmapFactory;
30import android.os.Process;
31import android.util.Log;
32import android.view.Surface;
33
34/**
35 * This class provides access to a RenderScript context, which controls RenderScript
36 * initialization, resource management, and teardown. An instance of the RenderScript
37 * class must be created before any other RS objects can be created.
38 *
39 * <div class="special reference">
40 * <h3>Developer Guides</h3>
41 * <p>For more information about creating an application that uses RenderScript, read the
42 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
43 * </div>
44 **/
45public class RenderScript {
46    static final String LOG_TAG = "RenderScript_jni";
47    static final boolean DEBUG  = false;
48    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
49    static final boolean LOG_ENABLED = false;
50
51    private Context mApplicationContext;
52    private String mNativeLibDir;
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 boolean nLoadSO(boolean useNative);
69    native boolean nLoadIOSO();
70    native long nDeviceCreate();
71    native void nDeviceDestroy(long dev);
72    native void nDeviceSetConfig(long dev, int param, int value);
73    native int nContextGetUserMessage(long con, int[] data);
74    native String nContextGetErrorMessage(long con);
75    native int  nContextPeekMessage(long con, int[] subID);
76    native void nContextInitToClient(long con);
77    native void nContextDeinitToClient(long con);
78
79    static private int sNative = -1;
80    static private int sSdkVersion = -1;
81    static private boolean useIOlib = false;
82    static private boolean useNative;
83
84    boolean isUseNative() {
85        return useNative;
86    }
87    /*
88     * Detect the bitness of the VM to allow FieldPacker to do the right thing.
89     */
90    static native int rsnSystemGetPointerSize();
91    static int sPointerSize;
92
93    /**
94     * Determines whether or not we should be thunking into the native
95     * RenderScript layer or actually using the compatibility library.
96     */
97    static private boolean setupNative(int sdkVersion, Context ctx) {
98        if (sNative == -1) {
99
100            // get the value of the debug.rs.forcecompat property
101            int forcecompat = 0;
102            try {
103                Class<?> sysprop = Class.forName("android.os.SystemProperties");
104                Class[] signature = {String.class, Integer.TYPE};
105                Method getint = sysprop.getDeclaredMethod("getInt", signature);
106                Object[] args = {"debug.rs.forcecompat", new Integer(0)};
107                forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue();
108            } catch (Exception e) {
109
110            }
111
112            if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
113                     && forcecompat == 0) {
114                sNative = 1;
115            } else {
116                sNative = 0;
117            }
118
119
120            if (sNative == 1) {
121                // Workarounds that may disable thunking go here
122                ApplicationInfo info;
123                try {
124                    info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
125                                                                      PackageManager.GET_META_DATA);
126                } catch (PackageManager.NameNotFoundException e) {
127                    // assume no workarounds needed
128                    return true;
129                }
130                long minorVersion = 0;
131
132                // load minorID from reflection
133                try {
134                    Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
135                    Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
136                    minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
137                } catch (Exception e) {
138                    // minor version remains 0 on devices with no possible WARs
139                }
140
141                if (info.metaData != null) {
142                    // asynchronous teardown: minor version 1+
143                    if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableAsyncTeardown") == true) {
144                        if (minorVersion == 0) {
145                            sNative = 0;
146                        }
147                    }
148
149                    // blur issues on some drivers with 4.4
150                    if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableBlurWorkaround") == true) {
151                        if (android.os.Build.VERSION.SDK_INT <= 19) {
152                            //android.util.Log.e("rs", "war on");
153                            sNative = 0;
154                        }
155                    }
156                }
157                // end of workarounds
158            }
159        }
160
161        if (sNative == 1) {
162            return true;
163        }
164        return false;
165    }
166
167    /**
168     * Name of the file that holds the object cache.
169     */
170    private static final String CACHE_PATH = "com.android.renderscript.cache";
171    static String mCachePath;
172
173     /**
174     * Sets the directory to use as a persistent storage for the
175     * renderscript object file cache.
176     *
177     * @hide
178     * @param cacheDir A directory the current process can write to
179     */
180    public static void setupDiskCache(File cacheDir) {
181        File f = new File(cacheDir, CACHE_PATH);
182        mCachePath = f.getAbsolutePath();
183        f.mkdirs();
184    }
185
186    /**
187     * ContextType specifies the specific type of context to be created.
188     *
189     */
190    public enum ContextType {
191        /**
192         * NORMAL context, this is the default and what shipping apps should
193         * use.
194         */
195        NORMAL (0),
196
197        /**
198         * DEBUG context, perform extra runtime checks to validate the
199         * kernels and APIs are being used as intended.  Get and SetElementAt
200         * will be bounds checked in this mode.
201         */
202        DEBUG (1),
203
204        /**
205         * PROFILE context, Intended to be used once the first time an
206         * application is run on a new device.  This mode allows the runtime to
207         * do additional testing and performance tuning.
208         */
209        PROFILE (2);
210
211        int mID;
212        ContextType(int id) {
213            mID = id;
214        }
215    }
216
217    // Methods below are wrapped to protect the non-threadsafe
218    // lockless fifo.
219
220    native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir);
221    synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir) {
222        return rsnContextCreate(dev, ver, sdkVer, contextType, nativeLibDir);
223    }
224    native void rsnContextDestroy(long con);
225    synchronized void nContextDestroy() {
226        validate();
227
228        // take teardown lock
229        // teardown lock can only be taken when no objects are being destroyed
230        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
231        wlock.lock();
232
233        long curCon = mContext;
234        // context is considered dead as of this point
235        mContext = 0;
236
237        wlock.unlock();
238        rsnContextDestroy(curCon);
239    }
240    native void rsnContextSetPriority(long con, int p);
241    synchronized void nContextSetPriority(int p) {
242        validate();
243        rsnContextSetPriority(mContext, p);
244    }
245    native void rsnContextDump(long con, int bits);
246    synchronized void nContextDump(int bits) {
247        validate();
248        rsnContextDump(mContext, bits);
249    }
250    native void rsnContextFinish(long con);
251    synchronized void nContextFinish() {
252        validate();
253        rsnContextFinish(mContext);
254    }
255
256    native void rsnContextSendMessage(long con, int id, int[] data);
257    synchronized void nContextSendMessage(int id, int[] data) {
258        validate();
259        rsnContextSendMessage(mContext, id, data);
260    }
261
262    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
263    native void rsnObjDestroy(long con, long id);
264    void nObjDestroy(long id) {
265        // There is a race condition here.  The calling code may be run
266        // by the gc while teardown is occuring.  This protects againts
267        // deleting dead objects.
268        if (mContext != 0) {
269            rsnObjDestroy(mContext, id);
270        }
271    }
272
273    native long  rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
274    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
275        validate();
276        return rsnElementCreate(mContext, type, kind, norm, vecSize);
277    }
278    native long  rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
279    synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
280        validate();
281        return rsnElementCreate2(mContext, elements, names, arraySizes);
282    }
283    native void rsnElementGetNativeData(long con, long id, int[] elementData);
284    synchronized void nElementGetNativeData(long id, int[] elementData) {
285        validate();
286        rsnElementGetNativeData(mContext, id, elementData);
287    }
288    native void rsnElementGetSubElements(long con, long id,
289                                         long[] IDs, String[] names, int[] arraySizes);
290    synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
291        validate();
292        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
293    }
294
295    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
296    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
297        validate();
298        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
299    }
300
301    native void rsnTypeGetNativeData(long con, long id, long[] typeData);
302    synchronized void nTypeGetNativeData(long id, long[] typeData) {
303        validate();
304        rsnTypeGetNativeData(mContext, id, typeData);
305    }
306
307    native long  rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
308    synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
309        validate();
310        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
311    }
312    native long  rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
313    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
314        validate();
315        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
316    }
317
318    native long  rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
319    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
320        validate();
321        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
322    }
323
324
325    native long  rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
326    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
327        validate();
328        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
329    }
330    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
331    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
332        validate();
333        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
334    }
335    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
336    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
337        validate();
338        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
339    }
340
341    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
342    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
343        validate();
344        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
345    }
346
347
348    native void rsnAllocationSyncAll(long con, long alloc, int src);
349    synchronized void nAllocationSyncAll(long alloc, int src) {
350        validate();
351        rsnAllocationSyncAll(mContext, alloc, src);
352    }
353
354    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
355    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
356        validate();
357        rsnAllocationSetSurface(mContext, alloc, sur);
358    }
359
360    native void rsnAllocationIoSend(long con, long alloc);
361    synchronized void nAllocationIoSend(long alloc) {
362        validate();
363        rsnAllocationIoSend(mContext, alloc);
364    }
365    native void rsnAllocationIoReceive(long con, long alloc);
366    synchronized void nAllocationIoReceive(long alloc) {
367        validate();
368        rsnAllocationIoReceive(mContext, alloc);
369    }
370
371
372    native void rsnAllocationGenerateMipmaps(long con, long alloc);
373    synchronized void nAllocationGenerateMipmaps(long alloc) {
374        validate();
375        rsnAllocationGenerateMipmaps(mContext, alloc);
376    }
377    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
378    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
379        validate();
380        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
381    }
382
383
384    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt,
385                                    int mSize, boolean usePadding);
386    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt,
387                                        int mSize, boolean usePadding) {
388        validate();
389        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
390    }
391
392    native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
393    synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
394        validate();
395        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
396    }
397    /*
398    native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes);
399    synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) {
400        validate();
401        rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
402    }
403    */
404
405    native void rsnAllocationData2D(long con,
406                                    long dstAlloc, int dstXoff, int dstYoff,
407                                    int dstMip, int dstFace,
408                                    int width, int height,
409                                    long srcAlloc, int srcXoff, int srcYoff,
410                                    int srcMip, int srcFace);
411    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
412                                        int dstMip, int dstFace,
413                                        int width, int height,
414                                        long srcAlloc, int srcXoff, int srcYoff,
415                                        int srcMip, int srcFace) {
416        validate();
417        rsnAllocationData2D(mContext,
418                            dstAlloc, dstXoff, dstYoff,
419                            dstMip, dstFace,
420                            width, height,
421                            srcAlloc, srcXoff, srcYoff,
422                            srcMip, srcFace);
423    }
424
425    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
426                                    int w, int h, Object d, int sizeBytes, int dt,
427                                    int mSize, boolean usePadding);
428    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
429                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
430                                        int mSize, boolean usePadding) {
431        validate();
432        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
433    }
434
435    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
436    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
437        validate();
438        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
439    }
440
441    native void rsnAllocationData3D(long con,
442                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
443                                    int dstMip,
444                                    int width, int height, int depth,
445                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
446                                    int srcMip);
447    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
448                                        int dstMip,
449                                        int width, int height, int depth,
450                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
451                                        int srcMip) {
452        validate();
453        rsnAllocationData3D(mContext,
454                            dstAlloc, dstXoff, dstYoff, dstZoff,
455                            dstMip, width, height, depth,
456                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
457    }
458
459
460    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
461                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
462                                    int mSize, boolean usePadding);
463    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
464                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
465                                        int mSize, boolean usePadding) {
466        validate();
467        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes,
468                            dt.mID, mSize, usePadding);
469    }
470
471    native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding);
472    synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) {
473        validate();
474        rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding);
475    }
476
477    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
478                                    int sizeBytes, int dt, int mSize, boolean usePadding);
479    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
480                                        int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) {
481        validate();
482        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
483    }
484
485    /*
486    native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff,
487                                         int mip, int compIdx, Object d, int sizeBytes, int dt);
488    synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff,
489                                             int mip, int compIdx, Object d, int sizeBytes,
490                                             Element.DataType dt) {
491        validate();
492        rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes, dt.mID);
493    }
494    */
495
496    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
497                                    int w, int h, Object d, int sizeBytes, int dt,
498                                    int mSize, boolean usePadding);
499    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
500                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
501                                        int mSize, boolean usePadding) {
502        validate();
503        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
504    }
505
506    /*
507    native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip,
508                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
509                                    int mSize, boolean usePadding);
510    synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip,
511                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
512                                        int mSize, boolean usePadding) {
513        validate();
514        rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding);
515    }
516    */
517
518    native long  rsnAllocationGetType(long con, long id);
519    synchronized long nAllocationGetType(long id) {
520        validate();
521        return rsnAllocationGetType(mContext, id);
522    }
523
524    native void rsnAllocationResize1D(long con, long id, int dimX);
525    synchronized void nAllocationResize1D(long id, int dimX) {
526        validate();
527        rsnAllocationResize1D(mContext, id, dimX);
528    }
529    native void rsnAllocationResize2D(long con, long id, int dimX, int dimY);
530    synchronized void nAllocationResize2D(long id, int dimX, int dimY) {
531        validate();
532        rsnAllocationResize2D(mContext, id, dimX, dimY);
533    }
534
535    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc);
536    synchronized void nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc) {
537        validate();
538        long curCon = mContext;
539        if (mUseInc) {
540            curCon = mIncCon;
541        }
542        rsnScriptBindAllocation(curCon, script, alloc, slot, mUseInc);
543    }
544    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc);
545    synchronized void nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc) {
546        validate();
547        long curCon = mContext;
548        if (mUseInc) {
549            curCon = mIncCon;
550        }
551        rsnScriptSetTimeZone(curCon, script, timeZone, mUseInc);
552    }
553    native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc);
554    synchronized void nScriptInvoke(long id, int slot, boolean mUseInc) {
555        validate();
556        long curCon = mContext;
557        if (mUseInc) {
558            curCon = mIncCon;
559        }
560        rsnScriptInvoke(curCon, id, slot, mUseInc);
561    }
562    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc);
563    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc);
564    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params,
565                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
566    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout,
567                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
568    synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc) {
569        validate();
570        if (params == null) {
571            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, mUseInc);
572        } else {
573            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, params, mUseInc);
574        }
575    }
576
577    synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
578                                            int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc) {
579        validate();
580        if (params == null) {
581            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend, mUseInc);
582        } else {
583            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend, mUseInc);
584        }
585    }
586
587    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc);
588    synchronized void nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc) {
589        validate();
590        long curCon = mContext;
591        if (mUseInc) {
592            curCon = mIncCon;
593        }
594        rsnScriptInvokeV(curCon, id, slot, params, mUseInc);
595    }
596    native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc);
597    synchronized void nScriptSetVarI(long id, int slot, int val, boolean mUseInc) {
598        validate();
599        long curCon = mContext;
600        if (mUseInc) {
601            curCon = mIncCon;
602        }
603        rsnScriptSetVarI(curCon, id, slot, val, mUseInc);
604    }
605    native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc);
606    synchronized void nScriptSetVarJ(long id, int slot, long val, boolean mUseInc) {
607        validate();
608        long curCon = mContext;
609        if (mUseInc) {
610            curCon = mIncCon;
611        }
612        rsnScriptSetVarJ(curCon, id, slot, val, mUseInc);
613    }
614    native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc);
615    synchronized void nScriptSetVarF(long id, int slot, float val, boolean mUseInc) {
616        validate();
617        long curCon = mContext;
618        if (mUseInc) {
619            curCon = mIncCon;
620        }
621        rsnScriptSetVarF(curCon, id, slot, val, mUseInc);
622    }
623    native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc);
624    synchronized void nScriptSetVarD(long id, int slot, double val, boolean mUseInc) {
625        validate();
626        long curCon = mContext;
627        if (mUseInc) {
628            curCon = mIncCon;
629        }
630        rsnScriptSetVarD(curCon, id, slot, val, mUseInc);
631    }
632    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc);
633    synchronized void nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc) {
634        validate();
635        long curCon = mContext;
636        if (mUseInc) {
637            curCon = mIncCon;
638        }
639        rsnScriptSetVarV(curCon, id, slot, val, mUseInc);
640    }
641    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
642                                  long e, int[] dims, boolean mUseInc);
643    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
644                                      long e, int[] dims, boolean mUseInc) {
645        validate();
646        long curCon = mContext;
647        if (mUseInc) {
648            curCon = mIncCon;
649        }
650        rsnScriptSetVarVE(curCon, id, slot, val, e, dims, mUseInc);
651    }
652    native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc);
653    synchronized void nScriptSetVarObj(long id, int slot, long val, boolean mUseInc) {
654        validate();
655        long curCon = mContext;
656        if (mUseInc) {
657            curCon = mIncCon;
658        }
659        rsnScriptSetVarObj(curCon, id, slot, val, mUseInc);
660    }
661
662    native long  rsnScriptCCreate(long con, String resName, String cacheDir,
663                                 byte[] script, int length);
664    synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
665        validate();
666        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
667    }
668
669    native long  rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc);
670    synchronized long nScriptIntrinsicCreate(int id, long eid, boolean mUseInc) {
671        validate();
672        if (mUseInc) {
673            if (!mIncLoaded) {
674                try {
675                    System.loadLibrary("RSSupport");
676                } catch (UnsatisfiedLinkError e) {
677                    Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e);
678                    throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e);
679                }
680                if (!nIncLoadSO()) {
681                    throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support");
682                }
683                mIncLoaded = true;
684            }
685            if (mIncDev == 0) {
686                mIncDev = nIncDeviceCreate();
687            }
688            if (mIncCon == 0) {
689                //Create a dummy compat context (synchronous).
690                mIncCon = nIncContextCreate(mIncDev, 0, 0, 0);
691            }
692            return rsnScriptIntrinsicCreate(mIncCon, id, eid, mUseInc);
693        } else {
694            return rsnScriptIntrinsicCreate(mContext, id, eid, mUseInc);
695        }
696    }
697
698    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc);
699    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc) {
700        validate();
701        long curCon = mContext;
702        if (mUseInc) {
703            curCon = mIncCon;
704        }
705        return rsnScriptKernelIDCreate(curCon, sid, slot, sig, mUseInc);
706    }
707
708    native long  rsnScriptInvokeIDCreate(long con, long sid, int slot);
709    synchronized long nScriptInvokeIDCreate(long sid, int slot) {
710        validate();
711        return rsnScriptInvokeIDCreate(mContext, sid, slot);
712    }
713
714    native long  rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc);
715    synchronized long nScriptFieldIDCreate(long sid, int slot, boolean mUseInc) {
716        validate();
717        long curCon = mContext;
718        if (mUseInc) {
719            curCon = mIncCon;
720        }
721        return rsnScriptFieldIDCreate(curCon, sid, slot, mUseInc);
722    }
723
724    native long  rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
725    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
726        validate();
727        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
728    }
729
730    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
731    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
732        validate();
733        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
734    }
735
736    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
737    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
738        validate();
739        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
740    }
741
742    native void rsnScriptGroupExecute(long con, long group);
743    synchronized void nScriptGroupExecute(long group) {
744        validate();
745        rsnScriptGroupExecute(mContext, group);
746    }
747
748    native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
749                                 int wrapS, int wrapT, int wrapR, float aniso);
750    synchronized long nSamplerCreate(int magFilter, int minFilter,
751                                 int wrapS, int wrapT, int wrapR, float aniso) {
752        validate();
753        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
754    }
755
756// Additional Entry points For inc libRSSupport
757
758    native boolean nIncLoadSO();
759    native long nIncDeviceCreate();
760    native void nIncDeviceDestroy(long dev);
761    // Methods below are wrapped to protect the non-threadsafe
762    // lockless fifo.
763    native long  rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType);
764    synchronized long nIncContextCreate(long dev, int ver, int sdkVer, int contextType) {
765        return rsnIncContextCreate(dev, ver, sdkVer, contextType);
766    }
767    native void rsnIncContextDestroy(long con);
768    synchronized void nIncContextDestroy() {
769        validate();
770
771        // take teardown lock
772        // teardown lock can only be taken when no objects are being destroyed
773        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
774        wlock.lock();
775
776        long curCon = mIncCon;
777        // context is considered dead as of this point
778        mIncCon = 0;
779
780        wlock.unlock();
781        rsnIncContextDestroy(curCon);
782    }
783
784    native void rsnIncContextFinish(long con);
785    synchronized void nIncContextFinish() {
786        validate();
787        rsnIncContextFinish(mIncCon);
788    }
789
790    native void rsnIncObjDestroy(long con, long id);
791    void nIncObjDestroy(long id) {
792        // There is a race condition here.  The calling code may be run
793        // by the gc while teardown is occuring.  This protects againts
794        // deleting dead objects.
795        if (mIncCon != 0) {
796            rsnIncObjDestroy(mIncCon, id);
797        }
798    }
799    native long  rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize);
800    synchronized long nIncElementCreate(long type, int kind, boolean norm, int vecSize) {
801        validate();
802        return rsnIncElementCreate(mIncCon, type, kind, norm, vecSize);
803    }
804    native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
805    synchronized long nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
806        validate();
807        return rsnIncTypeCreate(mIncCon, eid, x, y, z, mips, faces, yuv);
808    }
809    native long  rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type);
810    synchronized long nIncAllocationCreateTyped(long alloc, long type) {
811        validate();
812        return rsnIncAllocationCreateTyped(mContext, mIncCon, alloc, type);
813    }
814
815    long     mDev;
816    long     mContext;
817    //Dummy device & context for Inc Support Lib
818    long     mIncDev;
819    long     mIncCon;
820    //indicator of whether inc support lib has been loaded or not.
821    boolean  mIncLoaded;
822    ReentrantReadWriteLock mRWLock;
823    @SuppressWarnings({"FieldCanBeLocal"})
824    MessageThread mMessageThread;
825
826    Element mElement_U8;
827    Element mElement_I8;
828    Element mElement_U16;
829    Element mElement_I16;
830    Element mElement_U32;
831    Element mElement_I32;
832    Element mElement_U64;
833    Element mElement_I64;
834    Element mElement_F32;
835    Element mElement_F64;
836    Element mElement_BOOLEAN;
837
838    Element mElement_ELEMENT;
839    Element mElement_TYPE;
840    Element mElement_ALLOCATION;
841    Element mElement_SAMPLER;
842    Element mElement_SCRIPT;
843
844    Element mElement_A_8;
845    Element mElement_RGB_565;
846    Element mElement_RGB_888;
847    Element mElement_RGBA_5551;
848    Element mElement_RGBA_4444;
849    Element mElement_RGBA_8888;
850
851    Element mElement_FLOAT_2;
852    Element mElement_FLOAT_3;
853    Element mElement_FLOAT_4;
854
855    Element mElement_DOUBLE_2;
856    Element mElement_DOUBLE_3;
857    Element mElement_DOUBLE_4;
858
859    Element mElement_UCHAR_2;
860    Element mElement_UCHAR_3;
861    Element mElement_UCHAR_4;
862
863    Element mElement_CHAR_2;
864    Element mElement_CHAR_3;
865    Element mElement_CHAR_4;
866
867    Element mElement_USHORT_2;
868    Element mElement_USHORT_3;
869    Element mElement_USHORT_4;
870
871    Element mElement_SHORT_2;
872    Element mElement_SHORT_3;
873    Element mElement_SHORT_4;
874
875    Element mElement_UINT_2;
876    Element mElement_UINT_3;
877    Element mElement_UINT_4;
878
879    Element mElement_INT_2;
880    Element mElement_INT_3;
881    Element mElement_INT_4;
882
883    Element mElement_ULONG_2;
884    Element mElement_ULONG_3;
885    Element mElement_ULONG_4;
886
887    Element mElement_LONG_2;
888    Element mElement_LONG_3;
889    Element mElement_LONG_4;
890
891    Element mElement_MATRIX_4X4;
892    Element mElement_MATRIX_3X3;
893    Element mElement_MATRIX_2X2;
894
895    Sampler mSampler_CLAMP_NEAREST;
896    Sampler mSampler_CLAMP_LINEAR;
897    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
898    Sampler mSampler_WRAP_NEAREST;
899    Sampler mSampler_WRAP_LINEAR;
900    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
901    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
902    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
903    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
904
905
906    ///////////////////////////////////////////////////////////////////////////////////
907    //
908
909    /**
910     * The base class from which an application should derive in order
911     * to receive RS messages from scripts. When a script calls {@code
912     * rsSendToClient}, the data fields will be filled, and the run
913     * method will be called on a separate thread.  This will occur
914     * some time after {@code rsSendToClient} completes in the script,
915     * as {@code rsSendToClient} is asynchronous. Message handlers are
916     * not guaranteed to have completed when {@link
917     * android.support.v8.renderscript.RenderScript#finish} returns.
918     *
919     */
920    public static class RSMessageHandler implements Runnable {
921        protected int[] mData;
922        protected int mID;
923        protected int mLength;
924        public void run() {
925        }
926    }
927    /**
928     * If an application is expecting messages, it should set this
929     * field to an instance of {@link RSMessageHandler}.  This
930     * instance will receive all the user messages sent from {@code
931     * sendToClient} by scripts from this context.
932     *
933     */
934    RSMessageHandler mMessageCallback = null;
935
936    public void setMessageHandler(RSMessageHandler msg) {
937        mMessageCallback = msg;
938    }
939    public RSMessageHandler getMessageHandler() {
940        return mMessageCallback;
941    }
942
943    /**
944     * Place a message into the message queue to be sent back to the message
945     * handler once all previous commands have been executed.
946     *
947     * @hide
948     *
949     * @param id
950     * @param data
951     */
952    public void sendMessage(int id, int[] data) {
953        nContextSendMessage(id, data);
954    }
955
956    /**
957     * The runtime error handler base class.  An application should derive from this class
958     * if it wishes to install an error handler.  When errors occur at runtime,
959     * the fields in this class will be filled, and the run method will be called.
960     *
961     */
962    public static class RSErrorHandler implements Runnable {
963        protected String mErrorMessage;
964        protected int mErrorNum;
965        public void run() {
966        }
967    }
968
969    /**
970     * Application Error handler.  All runtime errors will be dispatched to the
971     * instance of RSAsyncError set here.  If this field is null a
972     * {@link RSRuntimeException} will instead be thrown with details about the error.
973     * This will cause program termaination.
974     *
975     */
976    RSErrorHandler mErrorCallback = null;
977
978    public void setErrorHandler(RSErrorHandler msg) {
979        mErrorCallback = msg;
980    }
981    public RSErrorHandler getErrorHandler() {
982        return mErrorCallback;
983    }
984
985    /**
986     * RenderScript worker thread priority enumeration.  The default value is
987     * NORMAL.  Applications wishing to do background processing should set
988     * their priority to LOW to avoid starving forground processes.
989     */
990    public enum Priority {
991        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
992        NORMAL (Process.THREAD_PRIORITY_DISPLAY);
993
994        int mID;
995        Priority(int id) {
996            mID = id;
997        }
998    }
999
1000    void validate() {
1001        if (mContext == 0) {
1002            throw new RSInvalidStateException("Calling RS with no Context active.");
1003        }
1004    }
1005
1006    /**
1007     * check if IO support lib is available.
1008     */
1009    boolean usingIO() {
1010        return useIOlib;
1011    }
1012    /**
1013     * Change the priority of the worker threads for this context.
1014     *
1015     * @param p New priority to be set.
1016     */
1017    public void setPriority(Priority p) {
1018        validate();
1019        nContextSetPriority(p.mID);
1020    }
1021
1022    static class MessageThread extends Thread {
1023        RenderScript mRS;
1024        boolean mRun = true;
1025        int[] mAuxData = new int[2];
1026
1027        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
1028        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
1029        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
1030        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
1031
1032        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
1033        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
1034
1035        MessageThread(RenderScript rs) {
1036            super("RSMessageThread");
1037            mRS = rs;
1038
1039        }
1040
1041        public void run() {
1042            // This function is a temporary solution.  The final solution will
1043            // used typed allocations where the message id is the type indicator.
1044            int[] rbuf = new int[16];
1045            mRS.nContextInitToClient(mRS.mContext);
1046            while(mRun) {
1047                rbuf[0] = 0;
1048                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
1049                int size = mAuxData[1];
1050                int subID = mAuxData[0];
1051
1052                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
1053                    if ((size>>2) >= rbuf.length) {
1054                        rbuf = new int[(size + 3) >> 2];
1055                    }
1056                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1057                        RS_MESSAGE_TO_CLIENT_USER) {
1058                        throw new RSDriverException("Error processing message from RenderScript.");
1059                    }
1060
1061                    if(mRS.mMessageCallback != null) {
1062                        mRS.mMessageCallback.mData = rbuf;
1063                        mRS.mMessageCallback.mID = subID;
1064                        mRS.mMessageCallback.mLength = size;
1065                        mRS.mMessageCallback.run();
1066                    } else {
1067                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
1068                    }
1069                    continue;
1070                }
1071
1072                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
1073                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
1074
1075                    if (subID >= RS_ERROR_FATAL_UNKNOWN) {
1076                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
1077                    }
1078
1079                    if(mRS.mErrorCallback != null) {
1080                        mRS.mErrorCallback.mErrorMessage = e;
1081                        mRS.mErrorCallback.mErrorNum = subID;
1082                        mRS.mErrorCallback.run();
1083                    } else {
1084                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
1085                        // Do not throw here. In these cases, we do not have
1086                        // a fatal error.
1087                    }
1088                    continue;
1089                }
1090
1091                // 2: teardown.
1092                // But we want to avoid starving other threads during
1093                // teardown by yielding until the next line in the destructor
1094                // can execute to set mRun = false
1095                try {
1096                    sleep(1, 0);
1097                } catch(InterruptedException e) {
1098                }
1099            }
1100            //Log.d(LOG_TAG, "MessageThread exiting.");
1101        }
1102    }
1103
1104    RenderScript(Context ctx) {
1105        if (ctx != null) {
1106            mApplicationContext = ctx.getApplicationContext();
1107            mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
1108        }
1109        mIncDev = 0;
1110        mIncCon = 0;
1111        mIncLoaded = false;
1112        mRWLock = new ReentrantReadWriteLock();
1113    }
1114
1115    /**
1116     * Gets the application context associated with the RenderScript context.
1117     *
1118     * @return The application context.
1119     */
1120    public final Context getApplicationContext() {
1121        return mApplicationContext;
1122    }
1123
1124    /**
1125     * @hide
1126     */
1127    public static RenderScript create(Context ctx, int sdkVersion) {
1128        return create(ctx, sdkVersion, ContextType.NORMAL);
1129    }
1130
1131    /**
1132     * Create a RenderScript context.
1133     *
1134     * @hide
1135     * @param ctx The context.
1136     * @return RenderScript
1137     */
1138    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
1139        RenderScript rs = new RenderScript(ctx);
1140
1141        if (sSdkVersion == -1) {
1142            sSdkVersion = sdkVersion;
1143        } else if (sSdkVersion != sdkVersion) {
1144            throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
1145        }
1146        useNative = setupNative(sSdkVersion, ctx);
1147        synchronized(lock) {
1148            if (sInitialized == false) {
1149                try {
1150                    Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
1151                    Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
1152                    sRuntime = get_runtime.invoke(null);
1153                    registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
1154                    registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
1155                    sUseGCHooks = true;
1156                } catch (Exception e) {
1157                    Log.e(LOG_TAG, "No GC methods");
1158                    sUseGCHooks = false;
1159                }
1160                try {
1161                    System.loadLibrary("rsjni");
1162                    sInitialized = true;
1163                    sPointerSize = rsnSystemGetPointerSize();
1164                } catch (UnsatisfiedLinkError e) {
1165                    Log.e(LOG_TAG, "Error loading RS jni library: " + e);
1166                    throw new RSRuntimeException("Error loading RS jni library: " + e);
1167                }
1168            }
1169        }
1170
1171        if (useNative) {
1172            android.util.Log.v(LOG_TAG, "RS native mode");
1173        } else {
1174            android.util.Log.v(LOG_TAG, "RS compat mode");
1175        }
1176
1177        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1178            useIOlib = true;
1179        }
1180        if (!rs.nLoadSO(useNative)) {
1181            if (useNative) {
1182                android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode");
1183                useNative = false;
1184            }
1185            try {
1186                System.loadLibrary("RSSupport");
1187            } catch (UnsatisfiedLinkError e) {
1188                Log.e(LOG_TAG, "Error loading RS Compat library: " + e);
1189                throw new RSRuntimeException("Error loading RS Compat library: " + e);
1190            }
1191            if (!rs.nLoadSO(false)) {
1192                throw new RSRuntimeException("Error loading libRSSupport library");
1193            }
1194        }
1195
1196        if (useIOlib) {
1197            try {
1198                System.loadLibrary("RSSupportIO");
1199            } catch (UnsatisfiedLinkError e) {
1200                useIOlib = false;
1201            }
1202            if (!useIOlib || !rs.nLoadIOSO()) {
1203                android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported");
1204                useIOlib = false;
1205            }
1206        }
1207
1208        rs.mDev = rs.nDeviceCreate();
1209        rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID, rs.mNativeLibDir);
1210        if (rs.mContext == 0) {
1211            throw new RSDriverException("Failed to create RS context.");
1212        }
1213        rs.mMessageThread = new MessageThread(rs);
1214        rs.mMessageThread.start();
1215        return rs;
1216    }
1217
1218    /**
1219     * Create a RenderScript context.
1220     *
1221     * @param ctx The context.
1222     * @return RenderScript
1223     */
1224    public static RenderScript create(Context ctx) {
1225        return create(ctx, ContextType.NORMAL);
1226    }
1227
1228    /**
1229     * Create a RenderScript context.
1230     *
1231     * @hide
1232     *
1233     * @param ctx The context.
1234     * @param ct The type of context to be created.
1235     * @return RenderScript
1236     */
1237    public static RenderScript create(Context ctx, ContextType ct) {
1238        int v = ctx.getApplicationInfo().targetSdkVersion;
1239        return create(ctx, v, ct);
1240    }
1241
1242    /**
1243     * Print the currently available debugging information about the state of
1244     * the RS context to the log.
1245     *
1246     */
1247    public void contextDump() {
1248        validate();
1249        nContextDump(0);
1250    }
1251
1252    /**
1253     * Wait for any pending asynchronous opeations (such as copies to a RS
1254     * allocation or RS script executions) to complete.
1255     *
1256     */
1257    public void finish() {
1258        nContextFinish();
1259    }
1260
1261    /**
1262     * Destroys this RenderScript context.  Once this function is called,
1263     * using this context or any objects belonging to this context is
1264     * illegal.
1265     *
1266     */
1267    public void destroy() {
1268        validate();
1269        nContextFinish();
1270        if (mIncCon != 0) {
1271            nIncContextFinish();
1272            nIncContextDestroy();
1273            mIncCon = 0;
1274        }
1275        nContextDeinitToClient(mContext);
1276        mMessageThread.mRun = false;
1277        try {
1278            mMessageThread.join();
1279        } catch(InterruptedException e) {
1280        }
1281
1282        nContextDestroy();
1283        nDeviceDestroy(mDev);
1284        if (mIncDev != 0) {
1285            nIncDeviceDestroy(mIncDev);
1286            mIncDev = 0;
1287        }
1288        mDev = 0;
1289    }
1290
1291    boolean isAlive() {
1292        return mContext != 0;
1293    }
1294
1295    long safeID(BaseObj o) {
1296        if(o != null) {
1297            return o.getID(this);
1298        }
1299        return 0;
1300    }
1301}
1302