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 that specifies a normal context.
68    */
69    public static final int 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 int 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 int 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    /**
634     * Multi-input code.
635     *
636     */
637
638    // @hide
639    native void rsnScriptForEachMultiClipped(long con, long id, int slot, long[] ains, long aout, byte[] params,
640                                             int xstart, int xend, int ystart, int yend, int zstart, int zend);
641    // @hide
642    native void rsnScriptForEachMultiClipped(long con, long id, int slot, long[] ains, long aout,
643                                             int xstart, int xend, int ystart, int yend, int zstart, int zend);
644
645    // @hide
646    synchronized void nScriptForEachMultiClipped(long id, int slot, long[] ains, long aout, byte[] params,
647                                                 int xstart, int xend, int ystart, int yend, int zstart, int zend) {
648        validate();
649        if (params == null) {
650            rsnScriptForEachMultiClipped(mContext, id, slot, ains, aout, xstart, xend, ystart, yend, zstart, zend);
651        } else {
652            rsnScriptForEachMultiClipped(mContext, id, slot, ains, aout, params, xstart, xend, ystart, yend, zstart, zend);
653        }
654    }
655
656    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
657    synchronized void nScriptInvokeV(long id, int slot, byte[] params) {
658        validate();
659        rsnScriptInvokeV(mContext, id, slot, params);
660    }
661
662    native void rsnScriptSetVarI(long con, long id, int slot, int val);
663    synchronized void nScriptSetVarI(long id, int slot, int val) {
664        validate();
665        rsnScriptSetVarI(mContext, id, slot, val);
666    }
667    native int rsnScriptGetVarI(long con, long id, int slot);
668    synchronized int nScriptGetVarI(long id, int slot) {
669        validate();
670        return rsnScriptGetVarI(mContext, id, slot);
671    }
672
673    native void rsnScriptSetVarJ(long con, long id, int slot, long val);
674    synchronized void nScriptSetVarJ(long id, int slot, long val) {
675        validate();
676        rsnScriptSetVarJ(mContext, id, slot, val);
677    }
678    native long rsnScriptGetVarJ(long con, long id, int slot);
679    synchronized long nScriptGetVarJ(long id, int slot) {
680        validate();
681        return rsnScriptGetVarJ(mContext, id, slot);
682    }
683
684    native void rsnScriptSetVarF(long con, long id, int slot, float val);
685    synchronized void nScriptSetVarF(long id, int slot, float val) {
686        validate();
687        rsnScriptSetVarF(mContext, id, slot, val);
688    }
689    native float rsnScriptGetVarF(long con, long id, int slot);
690    synchronized float nScriptGetVarF(long id, int slot) {
691        validate();
692        return rsnScriptGetVarF(mContext, id, slot);
693    }
694    native void rsnScriptSetVarD(long con, long id, int slot, double val);
695    synchronized void nScriptSetVarD(long id, int slot, double val) {
696        validate();
697        rsnScriptSetVarD(mContext, id, slot, val);
698    }
699    native double rsnScriptGetVarD(long con, long id, int slot);
700    synchronized double nScriptGetVarD(long id, int slot) {
701        validate();
702        return rsnScriptGetVarD(mContext, id, slot);
703    }
704    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val);
705    synchronized void nScriptSetVarV(long id, int slot, byte[] val) {
706        validate();
707        rsnScriptSetVarV(mContext, id, slot, val);
708    }
709    native void rsnScriptGetVarV(long con, long id, int slot, byte[] val);
710    synchronized void nScriptGetVarV(long id, int slot, byte[] val) {
711        validate();
712        rsnScriptGetVarV(mContext, id, slot, val);
713    }
714    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
715                                  long e, int[] dims);
716    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
717                                      long e, int[] dims) {
718        validate();
719        rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
720    }
721    native void rsnScriptSetVarObj(long con, long id, int slot, long val);
722    synchronized void nScriptSetVarObj(long id, int slot, long val) {
723        validate();
724        rsnScriptSetVarObj(mContext, id, slot, val);
725    }
726
727    native long rsnScriptCCreate(long con, String resName, String cacheDir,
728                                 byte[] script, int length);
729    synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
730        validate();
731        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
732    }
733
734    native long rsnScriptIntrinsicCreate(long con, int id, long eid);
735    synchronized long nScriptIntrinsicCreate(int id, long eid) {
736        validate();
737        return rsnScriptIntrinsicCreate(mContext, id, eid);
738    }
739
740    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig);
741    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig) {
742        validate();
743        return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
744    }
745
746    native long  rsnScriptFieldIDCreate(long con, long sid, int slot);
747    synchronized long nScriptFieldIDCreate(long sid, int slot) {
748        validate();
749        return rsnScriptFieldIDCreate(mContext, sid, slot);
750    }
751
752    native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
753    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
754        validate();
755        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
756    }
757
758    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
759    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
760        validate();
761        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
762    }
763
764    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
765    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
766        validate();
767        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
768    }
769
770    native void rsnScriptGroupExecute(long con, long group);
771    synchronized void nScriptGroupExecute(long group) {
772        validate();
773        rsnScriptGroupExecute(mContext, group);
774    }
775
776    native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
777                                 int wrapS, int wrapT, int wrapR, float aniso);
778    synchronized long nSamplerCreate(int magFilter, int minFilter,
779                                 int wrapS, int wrapT, int wrapR, float aniso) {
780        validate();
781        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
782    }
783
784    native long rsnProgramStoreCreate(long con, boolean r, boolean g, boolean b, boolean a,
785                                      boolean depthMask, boolean dither,
786                                      int srcMode, int dstMode, int depthFunc);
787    synchronized long nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
788                                         boolean depthMask, boolean dither,
789                                         int srcMode, int dstMode, int depthFunc) {
790        validate();
791        return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode,
792                                     dstMode, depthFunc);
793    }
794
795    native long rsnProgramRasterCreate(long con, boolean pointSprite, int cullMode);
796    synchronized long nProgramRasterCreate(boolean pointSprite, int cullMode) {
797        validate();
798        return rsnProgramRasterCreate(mContext, pointSprite, cullMode);
799    }
800
801    native void rsnProgramBindConstants(long con, long pv, int slot, long mID);
802    synchronized void nProgramBindConstants(long pv, int slot, long mID) {
803        validate();
804        rsnProgramBindConstants(mContext, pv, slot, mID);
805    }
806    native void rsnProgramBindTexture(long con, long vpf, int slot, long a);
807    synchronized void nProgramBindTexture(long vpf, int slot, long a) {
808        validate();
809        rsnProgramBindTexture(mContext, vpf, slot, a);
810    }
811    native void rsnProgramBindSampler(long con, long vpf, int slot, long s);
812    synchronized void nProgramBindSampler(long vpf, int slot, long s) {
813        validate();
814        rsnProgramBindSampler(mContext, vpf, slot, s);
815    }
816    native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, long[] params);
817    synchronized long nProgramFragmentCreate(String shader, String[] texNames, long[] params) {
818        validate();
819        return rsnProgramFragmentCreate(mContext, shader, texNames, params);
820    }
821    native long rsnProgramVertexCreate(long con, String shader, String[] texNames, long[] params);
822    synchronized long nProgramVertexCreate(String shader, String[] texNames, long[] params) {
823        validate();
824        return rsnProgramVertexCreate(mContext, shader, texNames, params);
825    }
826
827    native long rsnMeshCreate(long con, long[] vtx, long[] idx, int[] prim);
828    synchronized long nMeshCreate(long[] vtx, long[] idx, int[] prim) {
829        validate();
830        return rsnMeshCreate(mContext, vtx, idx, prim);
831    }
832    native int  rsnMeshGetVertexBufferCount(long con, long id);
833    synchronized int nMeshGetVertexBufferCount(long id) {
834        validate();
835        return rsnMeshGetVertexBufferCount(mContext, id);
836    }
837    native int  rsnMeshGetIndexCount(long con, long id);
838    synchronized int nMeshGetIndexCount(long id) {
839        validate();
840        return rsnMeshGetIndexCount(mContext, id);
841    }
842    native void rsnMeshGetVertices(long con, long id, long[] vtxIds, int vtxIdCount);
843    synchronized void nMeshGetVertices(long id, long[] vtxIds, int vtxIdCount) {
844        validate();
845        rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
846    }
847    native void rsnMeshGetIndices(long con, long id, long[] idxIds, int[] primitives, int vtxIdCount);
848    synchronized void nMeshGetIndices(long id, long[] idxIds, int[] primitives, int vtxIdCount) {
849        validate();
850        rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
851    }
852
853    native long rsnPathCreate(long con, int prim, boolean isStatic, long vtx, long loop, float q);
854    synchronized long nPathCreate(int prim, boolean isStatic, long vtx, long loop, float q) {
855        validate();
856        return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q);
857    }
858
859    long     mDev;
860    long     mContext;
861    @SuppressWarnings({"FieldCanBeLocal"})
862    MessageThread mMessageThread;
863
864    Element mElement_U8;
865    Element mElement_I8;
866    Element mElement_U16;
867    Element mElement_I16;
868    Element mElement_U32;
869    Element mElement_I32;
870    Element mElement_U64;
871    Element mElement_I64;
872    Element mElement_F32;
873    Element mElement_F64;
874    Element mElement_BOOLEAN;
875
876    Element mElement_ELEMENT;
877    Element mElement_TYPE;
878    Element mElement_ALLOCATION;
879    Element mElement_SAMPLER;
880    Element mElement_SCRIPT;
881    Element mElement_MESH;
882    Element mElement_PROGRAM_FRAGMENT;
883    Element mElement_PROGRAM_VERTEX;
884    Element mElement_PROGRAM_RASTER;
885    Element mElement_PROGRAM_STORE;
886    Element mElement_FONT;
887
888    Element mElement_A_8;
889    Element mElement_RGB_565;
890    Element mElement_RGB_888;
891    Element mElement_RGBA_5551;
892    Element mElement_RGBA_4444;
893    Element mElement_RGBA_8888;
894
895    Element mElement_FLOAT_2;
896    Element mElement_FLOAT_3;
897    Element mElement_FLOAT_4;
898
899    Element mElement_DOUBLE_2;
900    Element mElement_DOUBLE_3;
901    Element mElement_DOUBLE_4;
902
903    Element mElement_UCHAR_2;
904    Element mElement_UCHAR_3;
905    Element mElement_UCHAR_4;
906
907    Element mElement_CHAR_2;
908    Element mElement_CHAR_3;
909    Element mElement_CHAR_4;
910
911    Element mElement_USHORT_2;
912    Element mElement_USHORT_3;
913    Element mElement_USHORT_4;
914
915    Element mElement_SHORT_2;
916    Element mElement_SHORT_3;
917    Element mElement_SHORT_4;
918
919    Element mElement_UINT_2;
920    Element mElement_UINT_3;
921    Element mElement_UINT_4;
922
923    Element mElement_INT_2;
924    Element mElement_INT_3;
925    Element mElement_INT_4;
926
927    Element mElement_ULONG_2;
928    Element mElement_ULONG_3;
929    Element mElement_ULONG_4;
930
931    Element mElement_LONG_2;
932    Element mElement_LONG_3;
933    Element mElement_LONG_4;
934
935    Element mElement_YUV;
936
937    Element mElement_MATRIX_4X4;
938    Element mElement_MATRIX_3X3;
939    Element mElement_MATRIX_2X2;
940
941    Sampler mSampler_CLAMP_NEAREST;
942    Sampler mSampler_CLAMP_LINEAR;
943    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
944    Sampler mSampler_WRAP_NEAREST;
945    Sampler mSampler_WRAP_LINEAR;
946    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
947    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
948    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
949    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
950
951    ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
952    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
953    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
954    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
955
956    ProgramRaster mProgramRaster_CULL_BACK;
957    ProgramRaster mProgramRaster_CULL_FRONT;
958    ProgramRaster mProgramRaster_CULL_NONE;
959
960    ///////////////////////////////////////////////////////////////////////////////////
961    //
962
963    /**
964     * The base class from which an application should derive in order
965     * to receive RS messages from scripts. When a script calls {@code
966     * rsSendToClient}, the data fields will be filled, and the run
967     * method will be called on a separate thread.  This will occur
968     * some time after {@code rsSendToClient} completes in the script,
969     * as {@code rsSendToClient} is asynchronous. Message handlers are
970     * not guaranteed to have completed when {@link
971     * android.renderscript.RenderScript#finish} returns.
972     *
973     */
974    public static class RSMessageHandler implements Runnable {
975        protected int[] mData;
976        protected int mID;
977        protected int mLength;
978        public void run() {
979        }
980    }
981    /**
982     * If an application is expecting messages, it should set this
983     * field to an instance of {@link RSMessageHandler}.  This
984     * instance will receive all the user messages sent from {@code
985     * sendToClient} by scripts from this context.
986     *
987     */
988    RSMessageHandler mMessageCallback = null;
989
990    public void setMessageHandler(RSMessageHandler msg) {
991        mMessageCallback = msg;
992    }
993    public RSMessageHandler getMessageHandler() {
994        return mMessageCallback;
995    }
996
997    /**
998     * Place a message into the message queue to be sent back to the message
999     * handler once all previous commands have been executed.
1000     *
1001     * @param id
1002     * @param data
1003     */
1004    public void sendMessage(int id, int[] data) {
1005        nContextSendMessage(id, data);
1006    }
1007
1008    /**
1009     * The runtime error handler base class.  An application should derive from this class
1010     * if it wishes to install an error handler.  When errors occur at runtime,
1011     * the fields in this class will be filled, and the run method will be called.
1012     *
1013     */
1014    public static class RSErrorHandler implements Runnable {
1015        protected String mErrorMessage;
1016        protected int mErrorNum;
1017        public void run() {
1018        }
1019    }
1020
1021    /**
1022     * Application Error handler.  All runtime errors will be dispatched to the
1023     * instance of RSAsyncError set here.  If this field is null a
1024     * {@link RSRuntimeException} will instead be thrown with details about the error.
1025     * This will cause program termaination.
1026     *
1027     */
1028    RSErrorHandler mErrorCallback = null;
1029
1030    public void setErrorHandler(RSErrorHandler msg) {
1031        mErrorCallback = msg;
1032    }
1033    public RSErrorHandler getErrorHandler() {
1034        return mErrorCallback;
1035    }
1036
1037    /**
1038     * RenderScript worker thread priority enumeration.  The default value is
1039     * NORMAL.  Applications wishing to do background processing should set
1040     * their priority to LOW to avoid starving forground processes.
1041     */
1042    public enum Priority {
1043        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
1044        NORMAL (Process.THREAD_PRIORITY_DISPLAY);
1045
1046        int mID;
1047        Priority(int id) {
1048            mID = id;
1049        }
1050    }
1051
1052    void validateObject(BaseObj o) {
1053        if (o != null) {
1054            if (o.mRS != this) {
1055                throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
1056            }
1057        }
1058    }
1059
1060    void validate() {
1061        if (mContext == 0) {
1062            throw new RSInvalidStateException("Calling RS with no Context active.");
1063        }
1064    }
1065
1066
1067    /**
1068     * Change the priority of the worker threads for this context.
1069     *
1070     * @param p New priority to be set.
1071     */
1072    public void setPriority(Priority p) {
1073        validate();
1074        nContextSetPriority(p.mID);
1075    }
1076
1077    static class MessageThread extends Thread {
1078        RenderScript mRS;
1079        boolean mRun = true;
1080        int[] mAuxData = new int[2];
1081
1082        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
1083        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
1084        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
1085        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
1086        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
1087        static final int RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5;
1088
1089        static final int RS_ERROR_FATAL_DEBUG = 0x0800;
1090        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
1091
1092        MessageThread(RenderScript rs) {
1093            super("RSMessageThread");
1094            mRS = rs;
1095
1096        }
1097
1098        public void run() {
1099            // This function is a temporary solution.  The final solution will
1100            // used typed allocations where the message id is the type indicator.
1101            int[] rbuf = new int[16];
1102            mRS.nContextInitToClient(mRS.mContext);
1103            while(mRun) {
1104                rbuf[0] = 0;
1105                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
1106                int size = mAuxData[1];
1107                int subID = mAuxData[0];
1108
1109                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
1110                    if ((size>>2) >= rbuf.length) {
1111                        rbuf = new int[(size + 3) >> 2];
1112                    }
1113                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1114                        RS_MESSAGE_TO_CLIENT_USER) {
1115                        throw new RSDriverException("Error processing message from RenderScript.");
1116                    }
1117
1118                    if(mRS.mMessageCallback != null) {
1119                        mRS.mMessageCallback.mData = rbuf;
1120                        mRS.mMessageCallback.mID = subID;
1121                        mRS.mMessageCallback.mLength = size;
1122                        mRS.mMessageCallback.run();
1123                    } else {
1124                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
1125                    }
1126                    continue;
1127                }
1128
1129                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
1130                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
1131
1132                    // Throw RSRuntimeException under the following conditions:
1133                    //
1134                    // 1) It is an unknown fatal error.
1135                    // 2) It is a debug fatal error, and we are not in a
1136                    //    debug context.
1137                    // 3) It is a debug fatal error, and we do not have an
1138                    //    error callback.
1139                    if (subID >= RS_ERROR_FATAL_UNKNOWN ||
1140                        (subID >= RS_ERROR_FATAL_DEBUG &&
1141                         (mRS.mContextType != ContextType.DEBUG ||
1142                          mRS.mErrorCallback == null))) {
1143                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
1144                    }
1145
1146                    if(mRS.mErrorCallback != null) {
1147                        mRS.mErrorCallback.mErrorMessage = e;
1148                        mRS.mErrorCallback.mErrorNum = subID;
1149                        mRS.mErrorCallback.run();
1150                    } else {
1151                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
1152                        // Do not throw here. In these cases, we do not have
1153                        // a fatal error.
1154                    }
1155                    continue;
1156                }
1157
1158                if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
1159                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1160                        RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
1161                        throw new RSDriverException("Error processing message from RenderScript.");
1162                    }
1163                    long bufferID = ((long)rbuf[1] << 32L) + ((long)rbuf[0] & 0xffffffffL);
1164                    Allocation.sendBufferNotification(bufferID);
1165                    continue;
1166                }
1167
1168                // 2: teardown.
1169                // But we want to avoid starving other threads during
1170                // teardown by yielding until the next line in the destructor
1171                // can execute to set mRun = false
1172                try {
1173                    sleep(1, 0);
1174                } catch(InterruptedException e) {
1175                }
1176            }
1177            //Log.d(LOG_TAG, "MessageThread exiting.");
1178        }
1179    }
1180
1181    RenderScript(Context ctx) {
1182        mContextType = ContextType.NORMAL;
1183        if (ctx != null) {
1184            mApplicationContext = ctx.getApplicationContext();
1185        }
1186        mRWLock = new ReentrantReadWriteLock();
1187        try {
1188            registerNativeAllocation.invoke(sRuntime, 4 * 1024 * 1024); // 4MB for GC sake
1189        } catch (Exception e) {
1190            Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
1191            throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
1192        }
1193
1194    }
1195
1196    /**
1197     * Gets the application context associated with the RenderScript context.
1198     *
1199     * @return The application context.
1200     */
1201    public final Context getApplicationContext() {
1202        return mApplicationContext;
1203    }
1204
1205    /**
1206     * @hide
1207     */
1208    public static RenderScript create(Context ctx, int sdkVersion) {
1209        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
1210    }
1211
1212    /**
1213     * Create a RenderScript context.
1214     *
1215     * @hide
1216     * @param ctx The context.
1217     * @return RenderScript
1218     */
1219    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
1220        if (!sInitialized) {
1221            Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
1222            return null;
1223        }
1224
1225        if ((flags & ~(CREATE_FLAG_LOW_LATENCY | CREATE_FLAG_LOW_POWER)) != 0) {
1226            throw new RSIllegalArgumentException("Invalid flags passed.");
1227        }
1228
1229        RenderScript rs = new RenderScript(ctx);
1230
1231        rs.mDev = rs.nDeviceCreate();
1232        rs.mContext = rs.nContextCreate(rs.mDev, flags, sdkVersion, ct.mID);
1233        rs.mContextType = ct;
1234        if (rs.mContext == 0) {
1235            throw new RSDriverException("Failed to create RS context.");
1236        }
1237        rs.mMessageThread = new MessageThread(rs);
1238        rs.mMessageThread.start();
1239        return rs;
1240    }
1241
1242    /**
1243     * Create a RenderScript context.
1244     *
1245     * @param ctx The context.
1246     * @return RenderScript
1247     */
1248    public static RenderScript create(Context ctx) {
1249        return create(ctx, ContextType.NORMAL);
1250    }
1251
1252    /**
1253     * Create a RenderScript context.
1254     *
1255     *
1256     * @param ctx The context.
1257     * @param ct The type of context to be created.
1258     * @return RenderScript
1259     */
1260    public static RenderScript create(Context ctx, ContextType ct) {
1261        int v = ctx.getApplicationInfo().targetSdkVersion;
1262        return create(ctx, v, ct, CREATE_FLAG_NONE);
1263    }
1264
1265     /**
1266     * Create a RenderScript context.
1267     *
1268     *
1269     * @param ctx The context.
1270     * @param ct The type of context to be created.
1271     * @param flags The OR of the CREATE_FLAG_* options desired
1272     * @return RenderScript
1273     */
1274    public static RenderScript create(Context ctx, ContextType ct, int flags) {
1275        int v = ctx.getApplicationInfo().targetSdkVersion;
1276        return create(ctx, v, ct, flags);
1277    }
1278
1279    /**
1280     * Print the currently available debugging information about the state of
1281     * the RS context to the log.
1282     *
1283     */
1284    public void contextDump() {
1285        validate();
1286        nContextDump(0);
1287    }
1288
1289    /**
1290     * Wait for any pending asynchronous opeations (such as copies to a RS
1291     * allocation or RS script executions) to complete.
1292     *
1293     */
1294    public void finish() {
1295        nContextFinish();
1296    }
1297
1298    /**
1299     * Destroys this RenderScript context.  Once this function is called,
1300     * using this context or any objects belonging to this context is
1301     * illegal.
1302     *
1303     */
1304    public void destroy() {
1305        validate();
1306        nContextFinish();
1307
1308        nContextDeinitToClient(mContext);
1309        mMessageThread.mRun = false;
1310        try {
1311            mMessageThread.join();
1312        } catch(InterruptedException e) {
1313        }
1314
1315        nContextDestroy();
1316
1317        nDeviceDestroy(mDev);
1318        mDev = 0;
1319    }
1320
1321    boolean isAlive() {
1322        return mContext != 0;
1323    }
1324
1325    long safeID(BaseObj o) {
1326        if(o != null) {
1327            return o.getID(this);
1328        }
1329        return 0;
1330    }
1331}
1332