[go: nahoru, domu]

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