[go: nahoru, domu]

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