[go: nahoru, domu]

RenderScript.java revision 504abb362660f87239103be182a2e717a98ff32a
1/*
2 * Copyright (C) 2008-2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.renderscript;
18
19import java.io.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.graphics.SurfaceTexture;
31import android.os.Process;
32import android.util.Log;
33import android.view.Surface;
34import android.os.SystemProperties;
35import android.os.Trace;
36
37/**
38 * This class provides access to a RenderScript context, which controls RenderScript
39 * initialization, resource management, and teardown. An instance of the RenderScript
40 * class must be created before any other RS objects can be created.
41 *
42 * <div class="special reference">
43 * <h3>Developer Guides</h3>
44 * <p>For more information about creating an application that uses RenderScript, read the
45 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
46 * </div>
47 **/
48public class RenderScript {
49    static final long TRACE_TAG = Trace.TRACE_TAG_RS;
50
51    static final String LOG_TAG = "RenderScript_jni";
52    static final boolean DEBUG  = false;
53    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
54    static final boolean LOG_ENABLED = false;
55
56    private Context mApplicationContext;
57
58    /*
59     * We use a class initializer to allow the native code to cache some
60     * field offsets.
61     */
62    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // TODO: now used locally; remove?
63    static boolean sInitialized;
64    native static void _nInit();
65
66    static Object sRuntime;
67    static Method registerNativeAllocation;
68    static Method registerNativeFree;
69
70    static {
71        sInitialized = false;
72        if (!SystemProperties.getBoolean("config.disable_renderscript", false)) {
73            try {
74                Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
75                Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
76                sRuntime = get_runtime.invoke(null);
77                registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
78                registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
79            } catch (Exception e) {
80                Log.e(LOG_TAG, "Error loading GC methods: " + e);
81                throw new RSRuntimeException("Error loading GC methods: " + e);
82            }
83            try {
84                System.loadLibrary("rs_jni");
85                _nInit();
86                sInitialized = true;
87            } catch (UnsatisfiedLinkError e) {
88                Log.e(LOG_TAG, "Error loading RS jni library: " + e);
89                throw new RSRuntimeException("Error loading RS jni library: " + e);
90            }
91        }
92    }
93
94    // Non-threadsafe functions.
95    native long  nDeviceCreate();
96    native void nDeviceDestroy(long dev);
97    native void nDeviceSetConfig(long dev, int param, int value);
98    native int nContextGetUserMessage(long con, int[] data);
99    native String nContextGetErrorMessage(long con);
100    native int  nContextPeekMessage(long con, int[] subID);
101    native void nContextInitToClient(long con);
102    native void nContextDeinitToClient(long con);
103
104    static File mCacheDir;
105
106     /**
107     * Sets the directory to use as a persistent storage for the
108     * renderscript object file cache.
109     *
110     * @hide
111     * @param cacheDir A directory the current process can write to
112     */
113    public static void setupDiskCache(File cacheDir) {
114        if (!sInitialized) {
115            Log.e(LOG_TAG, "RenderScript.setupDiskCache() called when disabled");
116            return;
117        }
118
119        // Defer creation of cache path to nScriptCCreate().
120        mCacheDir = cacheDir;
121    }
122
123    /**
124     * ContextType specifies the specific type of context to be created.
125     *
126     */
127    public enum ContextType {
128        /**
129         * NORMAL context, this is the default and what shipping apps should
130         * use.
131         */
132        NORMAL (0),
133
134        /**
135         * DEBUG context, perform extra runtime checks to validate the
136         * kernels and APIs are being used as intended.  Get and SetElementAt
137         * will be bounds checked in this mode.
138         */
139        DEBUG (1),
140
141        /**
142         * PROFILE context, Intended to be used once the first time an
143         * application is run on a new device.  This mode allows the runtime to
144         * do additional testing and performance tuning.
145         */
146        PROFILE (2);
147
148        int mID;
149        ContextType(int id) {
150            mID = id;
151        }
152    }
153
154    ContextType mContextType;
155    ReentrantReadWriteLock mRWLock;
156
157    // Methods below are wrapped to protect the non-threadsafe
158    // lockless fifo.
159    native long  rsnContextCreateGL(long dev, int ver, int sdkVer,
160                 int colorMin, int colorPref,
161                 int alphaMin, int alphaPref,
162                 int depthMin, int depthPref,
163                 int stencilMin, int stencilPref,
164                 int samplesMin, int samplesPref, float samplesQ, int dpi);
165    synchronized long nContextCreateGL(long dev, int ver, int sdkVer,
166                 int colorMin, int colorPref,
167                 int alphaMin, int alphaPref,
168                 int depthMin, int depthPref,
169                 int stencilMin, int stencilPref,
170                 int samplesMin, int samplesPref, float samplesQ, int dpi) {
171        return rsnContextCreateGL(dev, ver, sdkVer, colorMin, colorPref,
172                                  alphaMin, alphaPref, depthMin, depthPref,
173                                  stencilMin, stencilPref,
174                                  samplesMin, samplesPref, samplesQ, dpi);
175    }
176    native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType);
177    synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType) {
178        return rsnContextCreate(dev, ver, sdkVer, contextType);
179    }
180    native void rsnContextDestroy(long con);
181    synchronized void nContextDestroy() {
182        validate();
183
184        // take teardown lock
185        // teardown lock can only be taken when no objects are being destroyed
186        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
187        wlock.lock();
188
189        long curCon = mContext;
190        // context is considered dead as of this point
191        mContext = 0;
192
193        wlock.unlock();
194        rsnContextDestroy(curCon);
195    }
196    native void rsnContextSetSurface(long con, int w, int h, Surface sur);
197    synchronized void nContextSetSurface(int w, int h, Surface sur) {
198        validate();
199        rsnContextSetSurface(mContext, w, h, sur);
200    }
201    native void rsnContextSetSurfaceTexture(long con, int w, int h, SurfaceTexture sur);
202    synchronized void nContextSetSurfaceTexture(int w, int h, SurfaceTexture sur) {
203        validate();
204        rsnContextSetSurfaceTexture(mContext, w, h, sur);
205    }
206    native void rsnContextSetPriority(long con, int p);
207    synchronized void nContextSetPriority(int p) {
208        validate();
209        rsnContextSetPriority(mContext, p);
210    }
211    native void rsnContextDump(long con, int bits);
212    synchronized void nContextDump(int bits) {
213        validate();
214        rsnContextDump(mContext, bits);
215    }
216    native void rsnContextFinish(long con);
217    synchronized void nContextFinish() {
218        validate();
219        rsnContextFinish(mContext);
220    }
221
222    native void rsnContextSendMessage(long con, int id, int[] data);
223    synchronized void nContextSendMessage(int id, int[] data) {
224        validate();
225        rsnContextSendMessage(mContext, id, data);
226    }
227
228    native void rsnContextBindRootScript(long con, int script);
229    synchronized void nContextBindRootScript(int script) {
230        validate();
231        rsnContextBindRootScript(mContext, script);
232    }
233    native void rsnContextBindSampler(long con, int sampler, int slot);
234    synchronized void nContextBindSampler(int sampler, int slot) {
235        validate();
236        rsnContextBindSampler(mContext, sampler, slot);
237    }
238    native void rsnContextBindProgramStore(long con, int pfs);
239    synchronized void nContextBindProgramStore(int pfs) {
240        validate();
241        rsnContextBindProgramStore(mContext, pfs);
242    }
243    native void rsnContextBindProgramFragment(long con, int pf);
244    synchronized void nContextBindProgramFragment(int pf) {
245        validate();
246        rsnContextBindProgramFragment(mContext, pf);
247    }
248    native void rsnContextBindProgramVertex(long con, int pv);
249    synchronized void nContextBindProgramVertex(int pv) {
250        validate();
251        rsnContextBindProgramVertex(mContext, pv);
252    }
253    native void rsnContextBindProgramRaster(long con, int pr);
254    synchronized void nContextBindProgramRaster(int pr) {
255        validate();
256        rsnContextBindProgramRaster(mContext, pr);
257    }
258    native void rsnContextPause(long con);
259    synchronized void nContextPause() {
260        validate();
261        rsnContextPause(mContext);
262    }
263    native void rsnContextResume(long con);
264    synchronized void nContextResume() {
265        validate();
266        rsnContextResume(mContext);
267    }
268
269    native void rsnAssignName(long con, long obj, byte[] name);
270    synchronized void nAssignName(long obj, byte[] name) {
271        validate();
272        rsnAssignName(mContext, obj, name);
273    }
274    native String rsnGetName(long con, long obj);
275    synchronized String nGetName(long obj) {
276        validate();
277        return rsnGetName(mContext, obj);
278    }
279
280    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
281    native void rsnObjDestroy(long con, long id);
282    void nObjDestroy(long id) {
283        // There is a race condition here.  The calling code may be run
284        // by the gc while teardown is occuring.  This protects againts
285        // deleting dead objects.
286        if (mContext != 0) {
287            rsnObjDestroy(mContext, id);
288        }
289    }
290
291    native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
292    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
293        validate();
294        return rsnElementCreate(mContext, type, kind, norm, vecSize);
295    }
296    native long rsnElementCreate2(long con, int[]elements, String[] names, int[] arraySizes);
297    synchronized long nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
298        validate();
299        return rsnElementCreate2(mContext, elements, names, arraySizes);
300    }
301    native void rsnElementGetNativeData(long con, long id, int[] elementData);
302    synchronized void nElementGetNativeData(long id, int[] elementData) {
303        validate();
304        rsnElementGetNativeData(mContext, id, elementData);
305    }
306    native void rsnElementGetSubElements(long con, long id,
307                                         int[] IDs, String[] names, int[] arraySizes);
308    synchronized void nElementGetSubElements(long id, int[] IDs, String[] names, int[] arraySizes) {
309        validate();
310        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
311    }
312
313    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
314    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
315        validate();
316        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
317    }
318    native void rsnTypeGetNativeData(long con, long id, int[] typeData);
319    synchronized void nTypeGetNativeData(long id, int[] typeData) {
320        validate();
321        rsnTypeGetNativeData(mContext, id, typeData);
322    }
323
324    native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, int pointer);
325    synchronized long nAllocationCreateTyped(long type, int mip, int usage, int pointer) {
326        validate();
327        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
328    }
329    native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
330    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
331        validate();
332        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
333    }
334
335    native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
336    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
337        validate();
338        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
339    }
340
341    native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
342    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
343        validate();
344        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
345    }
346    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
347    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
348        validate();
349        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
350    }
351    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
352    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
353        validate();
354        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
355    }
356
357    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
358    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
359        validate();
360        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
361    }
362
363
364    native void rsnAllocationSyncAll(long con, long alloc, int src);
365    synchronized void nAllocationSyncAll(long alloc, int src) {
366        validate();
367        rsnAllocationSyncAll(mContext, alloc, src);
368    }
369    native Surface rsnAllocationGetSurface(long con, long alloc);
370    synchronized Surface nAllocationGetSurface(long alloc) {
371        validate();
372        return rsnAllocationGetSurface(mContext, alloc);
373    }
374    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
375    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
376        validate();
377        rsnAllocationSetSurface(mContext, alloc, sur);
378    }
379    native void rsnAllocationIoSend(long con, long alloc);
380    synchronized void nAllocationIoSend(long alloc) {
381        validate();
382        rsnAllocationIoSend(mContext, alloc);
383    }
384    native void rsnAllocationIoReceive(long con, long alloc);
385    synchronized void nAllocationIoReceive(long alloc) {
386        validate();
387        rsnAllocationIoReceive(mContext, alloc);
388    }
389
390
391    native void rsnAllocationGenerateMipmaps(long con, long alloc);
392    synchronized void nAllocationGenerateMipmaps(long alloc) {
393        validate();
394        rsnAllocationGenerateMipmaps(mContext, alloc);
395    }
396    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
397    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
398        validate();
399        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
400    }
401
402
403    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt);
404    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt) {
405        validate();
406        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID);
407    }
408
409    native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
410    synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
411        validate();
412        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
413    }
414
415    native void rsnAllocationData2D(long con,
416                                    long dstAlloc, int dstXoff, int dstYoff,
417                                    int dstMip, int dstFace,
418                                    int width, int height,
419                                    long srcAlloc, int srcXoff, int srcYoff,
420                                    int srcMip, int srcFace);
421    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
422                                        int dstMip, int dstFace,
423                                        int width, int height,
424                                        long srcAlloc, int srcXoff, int srcYoff,
425                                        int srcMip, int srcFace) {
426        validate();
427        rsnAllocationData2D(mContext,
428                            dstAlloc, dstXoff, dstYoff,
429                            dstMip, dstFace,
430                            width, height,
431                            srcAlloc, srcXoff, srcYoff,
432                            srcMip, srcFace);
433    }
434
435    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
436                                    int w, int h, Object d, int sizeBytes, int dt);
437    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
438                                        int w, int h, Object d, int sizeBytes, Element.DataType dt) {
439        validate();
440        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID);
441    }
442
443    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
444    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
445        validate();
446        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
447    }
448
449    native void rsnAllocationData3D(long con,
450                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
451                                    int dstMip,
452                                    int width, int height, int depth,
453                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
454                                    int srcMip);
455    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
456                                        int dstMip,
457                                        int width, int height, int depth,
458                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
459                                        int srcMip) {
460        validate();
461        rsnAllocationData3D(mContext,
462                            dstAlloc, dstXoff, dstYoff, dstZoff,
463                            dstMip, width, height, depth,
464                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
465    }
466
467    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
468                                    int w, int h, int depth, Object d, int sizeBytes, int dt);
469    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
470                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt) {
471        validate();
472        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID);
473    }
474
475    native void rsnAllocationRead(long con, long id, Object d, int dt);
476    synchronized void nAllocationRead(long id, Object d, Element.DataType dt) {
477        validate();
478        rsnAllocationRead(mContext, id, d, dt.mID);
479    }
480
481    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
482                                    int sizeBytes, int dt);
483    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
484                                        int sizeBytes, Element.DataType dt) {
485        validate();
486        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID);
487    }
488
489    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
490                                    int w, int h, Object d, int sizeBytes, int dt);
491    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
492                                        int w, int h, Object d, int sizeBytes, Element.DataType dt) {
493        validate();
494        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID);
495    }
496
497    native long  rsnAllocationGetType(long con, long id);
498    synchronized long nAllocationGetType(long id) {
499        validate();
500        return rsnAllocationGetType(mContext, id);
501    }
502
503    native void rsnAllocationResize1D(long con, long id, int dimX);
504    synchronized void nAllocationResize1D(long id, int dimX) {
505        validate();
506        rsnAllocationResize1D(mContext, id, dimX);
507    }
508
509    native long rsnFileA3DCreateFromAssetStream(long con, int assetStream);
510    synchronized long nFileA3DCreateFromAssetStream(int assetStream) {
511        validate();
512        return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
513    }
514    native long rsnFileA3DCreateFromFile(long con, String path);
515    synchronized long nFileA3DCreateFromFile(String path) {
516        validate();
517        return rsnFileA3DCreateFromFile(mContext, path);
518    }
519    native long rsnFileA3DCreateFromAsset(long con, AssetManager mgr, String path);
520    synchronized long nFileA3DCreateFromAsset(AssetManager mgr, String path) {
521        validate();
522        return rsnFileA3DCreateFromAsset(mContext, mgr, path);
523    }
524    native int  rsnFileA3DGetNumIndexEntries(long con, long fileA3D);
525    synchronized int nFileA3DGetNumIndexEntries(long fileA3D) {
526        validate();
527        return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
528    }
529    native void rsnFileA3DGetIndexEntries(long con, long fileA3D, int numEntries, int[] IDs, String[] names);
530    synchronized void nFileA3DGetIndexEntries(long fileA3D, int numEntries, int[] IDs, String[] names) {
531        validate();
532        rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
533    }
534    native int  rsnFileA3DGetEntryByIndex(long con, long fileA3D, int index);
535    synchronized int nFileA3DGetEntryByIndex(long fileA3D, int index) {
536        validate();
537        return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
538    }
539
540    native int  rsnFontCreateFromFile(long con, String fileName, float size, int dpi);
541    synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
542        validate();
543        return rsnFontCreateFromFile(mContext, fileName, size, dpi);
544    }
545    native int  rsnFontCreateFromAssetStream(long con, String name, float size, int dpi, int assetStream);
546    synchronized int nFontCreateFromAssetStream(String name, float size, int dpi, int assetStream) {
547        validate();
548        return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
549    }
550    native int  rsnFontCreateFromAsset(long con, AssetManager mgr, String path, float size, int dpi);
551    synchronized int nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
552        validate();
553        return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
554    }
555
556
557    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot);
558    synchronized void nScriptBindAllocation(long script, long alloc, int slot) {
559        validate();
560        rsnScriptBindAllocation(mContext, script, alloc, slot);
561    }
562    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone);
563    synchronized void nScriptSetTimeZone(long script, byte[] timeZone) {
564        validate();
565        rsnScriptSetTimeZone(mContext, script, timeZone);
566    }
567    native void rsnScriptInvoke(long con, long id, int slot);
568    synchronized void nScriptInvoke(long id, int slot) {
569        validate();
570        rsnScriptInvoke(mContext, id, slot);
571    }
572    native void rsnScriptForEach(long con, long id, int slot, long ain, long aout, byte[] params);
573    native void rsnScriptForEach(long con, long id, int slot, long ain, long aout);
574    native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout, byte[] params,
575                                        int xstart, int xend, int ystart, int yend, int zstart, int zend);
576    native void rsnScriptForEachClipped(long con, long id, int slot, long ain, long aout,
577                                        int xstart, int xend, int ystart, int yend, int zstart, int zend);
578    synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params) {
579        validate();
580        if (params == null) {
581            rsnScriptForEach(mContext, id, slot, ain, aout);
582        } else {
583            rsnScriptForEach(mContext, id, slot, ain, aout, params);
584        }
585    }
586
587    synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
588                                            int xstart, int xend, int ystart, int yend, int zstart, int zend) {
589        validate();
590        if (params == null) {
591            rsnScriptForEachClipped(mContext, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend);
592        } else {
593            rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend);
594        }
595    }
596
597    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
598    synchronized void nScriptInvokeV(long id, int slot, byte[] params) {
599        validate();
600        rsnScriptInvokeV(mContext, id, slot, params);
601    }
602
603    native void rsnScriptSetVarI(long con, long id, int slot, int val);
604    synchronized void nScriptSetVarI(long id, int slot, int val) {
605        validate();
606        rsnScriptSetVarI(mContext, id, slot, val);
607    }
608    native int rsnScriptGetVarI(long con, long id, int slot);
609    synchronized int nScriptGetVarI(long id, int slot) {
610        validate();
611        return rsnScriptGetVarI(mContext, id, slot);
612    }
613
614    native void rsnScriptSetVarJ(long con, long id, int slot, long val);
615    synchronized void nScriptSetVarJ(long id, int slot, long val) {
616        validate();
617        rsnScriptSetVarJ(mContext, id, slot, val);
618    }
619    native long rsnScriptGetVarJ(long con, long id, int slot);
620    synchronized long nScriptGetVarJ(long id, int slot) {
621        validate();
622        return rsnScriptGetVarJ(mContext, id, slot);
623    }
624
625    native void rsnScriptSetVarF(long con, long id, int slot, float val);
626    synchronized void nScriptSetVarF(long id, int slot, float val) {
627        validate();
628        rsnScriptSetVarF(mContext, id, slot, val);
629    }
630    native float rsnScriptGetVarF(long con, long id, int slot);
631    synchronized float nScriptGetVarF(long id, int slot) {
632        validate();
633        return rsnScriptGetVarF(mContext, id, slot);
634    }
635    native void rsnScriptSetVarD(long con, long id, int slot, double val);
636    synchronized void nScriptSetVarD(long id, int slot, double val) {
637        validate();
638        rsnScriptSetVarD(mContext, id, slot, val);
639    }
640    native double rsnScriptGetVarD(long con, long id, int slot);
641    synchronized double nScriptGetVarD(long id, int slot) {
642        validate();
643        return rsnScriptGetVarD(mContext, id, slot);
644    }
645    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val);
646    synchronized void nScriptSetVarV(long id, int slot, byte[] val) {
647        validate();
648        rsnScriptSetVarV(mContext, id, slot, val);
649    }
650    native void rsnScriptGetVarV(long con, long id, int slot, byte[] val);
651    synchronized void nScriptGetVarV(long id, int slot, byte[] val) {
652        validate();
653        rsnScriptGetVarV(mContext, id, slot, val);
654    }
655    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
656                                  long e, int[] dims);
657    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
658                                      long e, int[] dims) {
659        validate();
660        rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
661    }
662    native void rsnScriptSetVarObj(long con, long id, int slot, long val);
663    synchronized void nScriptSetVarObj(long id, int slot, long val) {
664        validate();
665        rsnScriptSetVarObj(mContext, id, slot, val);
666    }
667
668    native int  rsnScriptCCreate(long con, String resName, String cacheDir,
669                                 byte[] script, int length);
670    synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
671        validate();
672        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
673    }
674
675    native long rsnScriptIntrinsicCreate(long con, int id, long eid);
676    synchronized long nScriptIntrinsicCreate(int id, long eid) {
677        validate();
678        return rsnScriptIntrinsicCreate(mContext, id, eid);
679    }
680
681    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig);
682    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig) {
683        validate();
684        return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
685    }
686
687    native long  rsnScriptFieldIDCreate(long con, long sid, int slot);
688    synchronized long nScriptFieldIDCreate(long sid, int slot) {
689        validate();
690        return rsnScriptFieldIDCreate(mContext, sid, slot);
691    }
692
693    native long rsnScriptGroupCreate(long con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
694    synchronized long nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
695        validate();
696        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
697    }
698
699    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
700    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
701        validate();
702        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
703    }
704
705    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
706    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
707        validate();
708        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
709    }
710
711    native void rsnScriptGroupExecute(long con, long group);
712    synchronized void nScriptGroupExecute(long group) {
713        validate();
714        rsnScriptGroupExecute(mContext, group);
715    }
716
717    native int  rsnSamplerCreate(long con, int magFilter, int minFilter,
718                                 int wrapS, int wrapT, int wrapR, float aniso);
719    synchronized int nSamplerCreate(int magFilter, int minFilter,
720                                 int wrapS, int wrapT, int wrapR, float aniso) {
721        validate();
722        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
723    }
724
725    native int  rsnProgramStoreCreate(long con, boolean r, boolean g, boolean b, boolean a,
726                                      boolean depthMask, boolean dither,
727                                      int srcMode, int dstMode, int depthFunc);
728    synchronized int nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
729                                         boolean depthMask, boolean dither,
730                                         int srcMode, int dstMode, int depthFunc) {
731        validate();
732        return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode,
733                                     dstMode, depthFunc);
734    }
735
736    native long rsnProgramRasterCreate(long con, boolean pointSprite, int cullMode);
737    synchronized long nProgramRasterCreate(boolean pointSprite, int cullMode) {
738        validate();
739        return rsnProgramRasterCreate(mContext, pointSprite, cullMode);
740    }
741
742    native void rsnProgramBindConstants(long con, long pv, int slot, long mID);
743    synchronized void nProgramBindConstants(long pv, int slot, long mID) {
744        validate();
745        rsnProgramBindConstants(mContext, pv, slot, mID);
746    }
747    native void rsnProgramBindTexture(long con, long vpf, int slot, long a);
748    synchronized void nProgramBindTexture(long vpf, int slot, long a) {
749        validate();
750        rsnProgramBindTexture(mContext, vpf, slot, a);
751    }
752    native void rsnProgramBindSampler(long con, long vpf, int slot, long s);
753    synchronized void nProgramBindSampler(long vpf, int slot, long s) {
754        validate();
755        rsnProgramBindSampler(mContext, vpf, slot, s);
756    }
757    native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, int[] params);
758    synchronized long nProgramFragmentCreate(String shader, String[] texNames, int[] params) {
759        validate();
760        return rsnProgramFragmentCreate(mContext, shader, texNames, params);
761    }
762    native long rsnProgramVertexCreate(long con, String shader, String[] texNames, int[] params);
763    synchronized long nProgramVertexCreate(String shader, String[] texNames, int[] params) {
764        validate();
765        return rsnProgramVertexCreate(mContext, shader, texNames, params);
766    }
767
768    native long rsnMeshCreate(long con, int[] vtx, int[] idx, int[] prim);
769    synchronized long nMeshCreate(int[] vtx, int[] idx, int[] prim) {
770        validate();
771        return rsnMeshCreate(mContext, vtx, idx, prim);
772    }
773    native int  rsnMeshGetVertexBufferCount(long con, long id);
774    synchronized int nMeshGetVertexBufferCount(long id) {
775        validate();
776        return rsnMeshGetVertexBufferCount(mContext, id);
777    }
778    native int  rsnMeshGetIndexCount(long con, long id);
779    synchronized int nMeshGetIndexCount(long id) {
780        validate();
781        return rsnMeshGetIndexCount(mContext, id);
782    }
783    native void rsnMeshGetVertices(long con, long id, int[] vtxIds, int vtxIdCount);
784    synchronized void nMeshGetVertices(long id, int[] vtxIds, int vtxIdCount) {
785        validate();
786        rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
787    }
788    native void rsnMeshGetIndices(long con, long id, int[] idxIds, int[] primitives, int vtxIdCount);
789    synchronized void nMeshGetIndices(long id, int[] idxIds, int[] primitives, int vtxIdCount) {
790        validate();
791        rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
792    }
793
794    native long rsnPathCreate(long con, int prim, boolean isStatic, long vtx, int loop, float q);
795    synchronized long nPathCreate(int prim, boolean isStatic, long vtx, int loop, float q) {
796        validate();
797        return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q);
798    }
799
800    long     mDev;
801    long     mContext;
802    @SuppressWarnings({"FieldCanBeLocal"})
803    MessageThread mMessageThread;
804
805    Element mElement_U8;
806    Element mElement_I8;
807    Element mElement_U16;
808    Element mElement_I16;
809    Element mElement_U32;
810    Element mElement_I32;
811    Element mElement_U64;
812    Element mElement_I64;
813    Element mElement_F32;
814    Element mElement_F64;
815    Element mElement_BOOLEAN;
816
817    Element mElement_ELEMENT;
818    Element mElement_TYPE;
819    Element mElement_ALLOCATION;
820    Element mElement_SAMPLER;
821    Element mElement_SCRIPT;
822    Element mElement_MESH;
823    Element mElement_PROGRAM_FRAGMENT;
824    Element mElement_PROGRAM_VERTEX;
825    Element mElement_PROGRAM_RASTER;
826    Element mElement_PROGRAM_STORE;
827    Element mElement_FONT;
828
829    Element mElement_A_8;
830    Element mElement_RGB_565;
831    Element mElement_RGB_888;
832    Element mElement_RGBA_5551;
833    Element mElement_RGBA_4444;
834    Element mElement_RGBA_8888;
835
836    Element mElement_FLOAT_2;
837    Element mElement_FLOAT_3;
838    Element mElement_FLOAT_4;
839
840    Element mElement_DOUBLE_2;
841    Element mElement_DOUBLE_3;
842    Element mElement_DOUBLE_4;
843
844    Element mElement_UCHAR_2;
845    Element mElement_UCHAR_3;
846    Element mElement_UCHAR_4;
847
848    Element mElement_CHAR_2;
849    Element mElement_CHAR_3;
850    Element mElement_CHAR_4;
851
852    Element mElement_USHORT_2;
853    Element mElement_USHORT_3;
854    Element mElement_USHORT_4;
855
856    Element mElement_SHORT_2;
857    Element mElement_SHORT_3;
858    Element mElement_SHORT_4;
859
860    Element mElement_UINT_2;
861    Element mElement_UINT_3;
862    Element mElement_UINT_4;
863
864    Element mElement_INT_2;
865    Element mElement_INT_3;
866    Element mElement_INT_4;
867
868    Element mElement_ULONG_2;
869    Element mElement_ULONG_3;
870    Element mElement_ULONG_4;
871
872    Element mElement_LONG_2;
873    Element mElement_LONG_3;
874    Element mElement_LONG_4;
875
876    Element mElement_YUV;
877
878    Element mElement_MATRIX_4X4;
879    Element mElement_MATRIX_3X3;
880    Element mElement_MATRIX_2X2;
881
882    Sampler mSampler_CLAMP_NEAREST;
883    Sampler mSampler_CLAMP_LINEAR;
884    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
885    Sampler mSampler_WRAP_NEAREST;
886    Sampler mSampler_WRAP_LINEAR;
887    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
888    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
889    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
890    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
891
892    ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
893    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
894    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
895    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
896
897    ProgramRaster mProgramRaster_CULL_BACK;
898    ProgramRaster mProgramRaster_CULL_FRONT;
899    ProgramRaster mProgramRaster_CULL_NONE;
900
901    ///////////////////////////////////////////////////////////////////////////////////
902    //
903
904    /**
905     * The base class from which an application should derive in order
906     * to receive RS messages from scripts. When a script calls {@code
907     * rsSendToClient}, the data fields will be filled, and the run
908     * method will be called on a separate thread.  This will occur
909     * some time after {@code rsSendToClient} completes in the script,
910     * as {@code rsSendToClient} is asynchronous. Message handlers are
911     * not guaranteed to have completed when {@link
912     * android.renderscript.RenderScript#finish} returns.
913     *
914     */
915    public static class RSMessageHandler implements Runnable {
916        protected int[] mData;
917        protected int mID;
918        protected int mLength;
919        public void run() {
920        }
921    }
922    /**
923     * If an application is expecting messages, it should set this
924     * field to an instance of {@link RSMessageHandler}.  This
925     * instance will receive all the user messages sent from {@code
926     * sendToClient} by scripts from this context.
927     *
928     */
929    RSMessageHandler mMessageCallback = null;
930
931    public void setMessageHandler(RSMessageHandler msg) {
932        mMessageCallback = msg;
933    }
934    public RSMessageHandler getMessageHandler() {
935        return mMessageCallback;
936    }
937
938    /**
939     * Place a message into the message queue to be sent back to the message
940     * handler once all previous commands have been executed.
941     *
942     * @param id
943     * @param data
944     */
945    public void sendMessage(int id, int[] data) {
946        nContextSendMessage(id, data);
947    }
948
949    /**
950     * The runtime error handler base class.  An application should derive from this class
951     * if it wishes to install an error handler.  When errors occur at runtime,
952     * the fields in this class will be filled, and the run method will be called.
953     *
954     */
955    public static class RSErrorHandler implements Runnable {
956        protected String mErrorMessage;
957        protected int mErrorNum;
958        public void run() {
959        }
960    }
961
962    /**
963     * Application Error handler.  All runtime errors will be dispatched to the
964     * instance of RSAsyncError set here.  If this field is null a
965     * {@link RSRuntimeException} will instead be thrown with details about the error.
966     * This will cause program termaination.
967     *
968     */
969    RSErrorHandler mErrorCallback = null;
970
971    public void setErrorHandler(RSErrorHandler msg) {
972        mErrorCallback = msg;
973    }
974    public RSErrorHandler getErrorHandler() {
975        return mErrorCallback;
976    }
977
978    /**
979     * RenderScript worker thread priority enumeration.  The default value is
980     * NORMAL.  Applications wishing to do background processing should set
981     * their priority to LOW to avoid starving forground processes.
982     */
983    public enum Priority {
984        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
985        NORMAL (Process.THREAD_PRIORITY_DISPLAY);
986
987        int mID;
988        Priority(int id) {
989            mID = id;
990        }
991    }
992
993    void validate() {
994        if (mContext == 0) {
995            throw new RSInvalidStateException("Calling RS with no Context active.");
996        }
997    }
998
999
1000    /**
1001     * Change the priority of the worker threads for this context.
1002     *
1003     * @param p New priority to be set.
1004     */
1005    public void setPriority(Priority p) {
1006        validate();
1007        nContextSetPriority(p.mID);
1008    }
1009
1010    static class MessageThread extends Thread {
1011        RenderScript mRS;
1012        boolean mRun = true;
1013        int[] mAuxData = new int[2];
1014
1015        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
1016        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
1017        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
1018        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
1019        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
1020        static final int RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5;
1021
1022        static final int RS_ERROR_FATAL_DEBUG = 0x0800;
1023        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
1024
1025        MessageThread(RenderScript rs) {
1026            super("RSMessageThread");
1027            mRS = rs;
1028
1029        }
1030
1031        public void run() {
1032            // This function is a temporary solution.  The final solution will
1033            // used typed allocations where the message id is the type indicator.
1034            int[] rbuf = new int[16];
1035            mRS.nContextInitToClient(mRS.mContext);
1036            while(mRun) {
1037                rbuf[0] = 0;
1038                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
1039                int size = mAuxData[1];
1040                int subID = mAuxData[0];
1041
1042                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
1043                    if ((size>>2) >= rbuf.length) {
1044                        rbuf = new int[(size + 3) >> 2];
1045                    }
1046                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1047                        RS_MESSAGE_TO_CLIENT_USER) {
1048                        throw new RSDriverException("Error processing message from RenderScript.");
1049                    }
1050
1051                    if(mRS.mMessageCallback != null) {
1052                        mRS.mMessageCallback.mData = rbuf;
1053                        mRS.mMessageCallback.mID = subID;
1054                        mRS.mMessageCallback.mLength = size;
1055                        mRS.mMessageCallback.run();
1056                    } else {
1057                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
1058                    }
1059                    continue;
1060                }
1061
1062                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
1063                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
1064
1065                    // Throw RSRuntimeException under the following conditions:
1066                    //
1067                    // 1) It is an unknown fatal error.
1068                    // 2) It is a debug fatal error, and we are not in a
1069                    //    debug context.
1070                    // 3) It is a debug fatal error, and we do not have an
1071                    //    error callback.
1072                    if (subID >= RS_ERROR_FATAL_UNKNOWN ||
1073                        (subID >= RS_ERROR_FATAL_DEBUG &&
1074                         (mRS.mContextType != ContextType.DEBUG ||
1075                          mRS.mErrorCallback == null))) {
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                if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
1092                    Allocation.sendBufferNotification(subID);
1093                    continue;
1094                }
1095
1096                // 2: teardown.
1097                // But we want to avoid starving other threads during
1098                // teardown by yielding until the next line in the destructor
1099                // can execute to set mRun = false
1100                try {
1101                    sleep(1, 0);
1102                } catch(InterruptedException e) {
1103                }
1104            }
1105            //Log.d(LOG_TAG, "MessageThread exiting.");
1106        }
1107    }
1108
1109    RenderScript(Context ctx) {
1110        mContextType = ContextType.NORMAL;
1111        if (ctx != null) {
1112            mApplicationContext = ctx.getApplicationContext();
1113        }
1114        mRWLock = new ReentrantReadWriteLock();
1115    }
1116
1117    /**
1118     * Gets the application context associated with the RenderScript context.
1119     *
1120     * @return The application context.
1121     */
1122    public final Context getApplicationContext() {
1123        return mApplicationContext;
1124    }
1125
1126    /**
1127     * @hide
1128     */
1129    public static RenderScript create(Context ctx, int sdkVersion) {
1130        return create(ctx, sdkVersion, ContextType.NORMAL);
1131    }
1132
1133    /**
1134     * Create a RenderScript context.
1135     *
1136     * @hide
1137     * @param ctx The context.
1138     * @return RenderScript
1139     */
1140    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
1141        if (!sInitialized) {
1142            Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
1143            return null;
1144        }
1145
1146        RenderScript rs = new RenderScript(ctx);
1147
1148        rs.mDev = rs.nDeviceCreate();
1149        rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID);
1150        rs.mContextType = ct;
1151        if (rs.mContext == 0) {
1152            throw new RSDriverException("Failed to create RS context.");
1153        }
1154        rs.mMessageThread = new MessageThread(rs);
1155        rs.mMessageThread.start();
1156        return rs;
1157    }
1158
1159    /**
1160     * Create a RenderScript context.
1161     *
1162     * @param ctx The context.
1163     * @return RenderScript
1164     */
1165    public static RenderScript create(Context ctx) {
1166        return create(ctx, ContextType.NORMAL);
1167    }
1168
1169    /**
1170     * Create a RenderScript context.
1171     *
1172     *
1173     * @param ctx The context.
1174     * @param ct The type of context to be created.
1175     * @return RenderScript
1176     */
1177    public static RenderScript create(Context ctx, ContextType ct) {
1178        int v = ctx.getApplicationInfo().targetSdkVersion;
1179        return create(ctx, v, ct);
1180    }
1181
1182    /**
1183     * Print the currently available debugging information about the state of
1184     * the RS context to the log.
1185     *
1186     */
1187    public void contextDump() {
1188        validate();
1189        nContextDump(0);
1190    }
1191
1192    /**
1193     * Wait for any pending asynchronous opeations (such as copies to a RS
1194     * allocation or RS script executions) to complete.
1195     *
1196     */
1197    public void finish() {
1198        nContextFinish();
1199    }
1200
1201    /**
1202     * Destroys this RenderScript context.  Once this function is called,
1203     * using this context or any objects belonging to this context is
1204     * illegal.
1205     *
1206     */
1207    public void destroy() {
1208        validate();
1209        nContextFinish();
1210
1211        nContextDeinitToClient(mContext);
1212        mMessageThread.mRun = false;
1213        try {
1214            mMessageThread.join();
1215        } catch(InterruptedException e) {
1216        }
1217
1218        nContextDestroy();
1219
1220        nDeviceDestroy(mDev);
1221        mDev = 0;
1222    }
1223
1224    boolean isAlive() {
1225        return mContext != 0;
1226    }
1227
1228    long safeID(BaseObj o) {
1229        if(o != null) {
1230            return o.getID(this);
1231        }
1232        return 0;
1233    }
1234}
1235