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