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