[go: nahoru, domu]

RenderScript.java revision be392ad35e29b17ed54fdbbbb8dd3e80fc1022b9
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 long rsnClosureCreate(long con, long kernelID, long returnValue,
306        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
307        long[] depFieldIDs);
308    synchronized long nClosureCreate(long kernelID, long returnValue,
309        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
310        long[] depFieldIDs) {
311      validate();
312      return rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
313          sizes, depClosures, depFieldIDs);
314    }
315
316    native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
317        long[] fieldIDs, long[] values, int[] sizes);
318    synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
319        long[] fieldIDs, long[] values, int[] sizes) {
320      validate();
321      return rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
322          values, sizes);
323    }
324
325    native void rsnClosureSetArg(long con, long closureID, int index,
326      long value, int size);
327    synchronized void nClosureSetArg(long closureID, int index, long value,
328        int size) {
329      validate();
330      rsnClosureSetArg(mContext, closureID, index, value, size);
331    }
332
333    native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
334        long value, int size);
335    // Does this have to be synchronized?
336    synchronized void nClosureSetGlobal(long closureID, long fieldID,
337        long value, int size) {
338      validate(); // TODO: is this necessary?
339      rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
340    }
341
342    native long rsnScriptGroup2Create(long con, String cachePath, long[] closures);
343    synchronized long nScriptGroup2Create(String cachePath, long[] closures) {
344      validate();
345      return rsnScriptGroup2Create(mContext, cachePath, closures);
346    }
347
348    native void rsnScriptGroup2Execute(long con, long groupID);
349    synchronized void nScriptGroup2Execute(long groupID) {
350      validate();
351      rsnScriptGroup2Execute(mContext, groupID);
352    }
353
354    native void rsnAssignName(long con, long obj, byte[] name);
355    synchronized void nAssignName(long obj, byte[] name) {
356        validate();
357        rsnAssignName(mContext, obj, name);
358    }
359    native String rsnGetName(long con, long obj);
360    synchronized String nGetName(long obj) {
361        validate();
362        return rsnGetName(mContext, obj);
363    }
364
365    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
366    native void rsnObjDestroy(long con, long id);
367    void nObjDestroy(long id) {
368        // There is a race condition here.  The calling code may be run
369        // by the gc while teardown is occuring.  This protects againts
370        // deleting dead objects.
371        if (mContext != 0) {
372            rsnObjDestroy(mContext, id);
373        }
374    }
375
376    native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
377    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
378        validate();
379        return rsnElementCreate(mContext, type, kind, norm, vecSize);
380    }
381    native long rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
382    synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
383        validate();
384        return rsnElementCreate2(mContext, elements, names, arraySizes);
385    }
386    native void rsnElementGetNativeData(long con, long id, int[] elementData);
387    synchronized void nElementGetNativeData(long id, int[] elementData) {
388        validate();
389        rsnElementGetNativeData(mContext, id, elementData);
390    }
391    native void rsnElementGetSubElements(long con, long id,
392                                         long[] IDs, String[] names, int[] arraySizes);
393    synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
394        validate();
395        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
396    }
397
398    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
399    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
400        validate();
401        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
402    }
403    native void rsnTypeGetNativeData(long con, long id, long[] typeData);
404    synchronized void nTypeGetNativeData(long id, long[] typeData) {
405        validate();
406        rsnTypeGetNativeData(mContext, id, typeData);
407    }
408
409    native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
410    synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
411        validate();
412        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
413    }
414    native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
415    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
416        validate();
417        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
418    }
419
420    native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
421    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
422        validate();
423        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
424    }
425
426    native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
427    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
428        validate();
429        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
430    }
431    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
432    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
433        validate();
434        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
435    }
436    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
437    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
438        validate();
439        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
440    }
441
442    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
443    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
444        validate();
445        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
446    }
447
448
449    native void rsnAllocationSyncAll(long con, long alloc, int src);
450    synchronized void nAllocationSyncAll(long alloc, int src) {
451        validate();
452        rsnAllocationSyncAll(mContext, alloc, src);
453    }
454    native Surface rsnAllocationGetSurface(long con, long alloc);
455    synchronized Surface nAllocationGetSurface(long alloc) {
456        validate();
457        return rsnAllocationGetSurface(mContext, alloc);
458    }
459    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
460    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
461        validate();
462        rsnAllocationSetSurface(mContext, alloc, sur);
463    }
464    native void rsnAllocationIoSend(long con, long alloc);
465    synchronized void nAllocationIoSend(long alloc) {
466        validate();
467        rsnAllocationIoSend(mContext, alloc);
468    }
469    native void rsnAllocationIoReceive(long con, long alloc);
470    synchronized void nAllocationIoReceive(long alloc) {
471        validate();
472        rsnAllocationIoReceive(mContext, alloc);
473    }
474
475
476    native void rsnAllocationGenerateMipmaps(long con, long alloc);
477    synchronized void nAllocationGenerateMipmaps(long alloc) {
478        validate();
479        rsnAllocationGenerateMipmaps(mContext, alloc);
480    }
481    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
482    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
483        validate();
484        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
485    }
486
487
488    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt);
489    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt) {
490        validate();
491        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID);
492    }
493
494    native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
495    synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
496        validate();
497        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
498    }
499
500    native void rsnAllocationData2D(long con,
501                                    long dstAlloc, int dstXoff, int dstYoff,
502                                    int dstMip, int dstFace,
503                                    int width, int height,
504                                    long srcAlloc, int srcXoff, int srcYoff,
505                                    int srcMip, int srcFace);
506    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
507                                        int dstMip, int dstFace,
508                                        int width, int height,
509                                        long srcAlloc, int srcXoff, int srcYoff,
510                                        int srcMip, int srcFace) {
511        validate();
512        rsnAllocationData2D(mContext,
513                            dstAlloc, dstXoff, dstYoff,
514                            dstMip, dstFace,
515                            width, height,
516                            srcAlloc, srcXoff, srcYoff,
517                            srcMip, srcFace);
518    }
519
520    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
521                                    int w, int h, Object d, int sizeBytes, int dt);
522    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
523                                        int w, int h, Object d, int sizeBytes, Element.DataType dt) {
524        validate();
525        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID);
526    }
527
528    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
529    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
530        validate();
531        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
532    }
533
534    native void rsnAllocationData3D(long con,
535                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
536                                    int dstMip,
537                                    int width, int height, int depth,
538                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
539                                    int srcMip);
540    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
541                                        int dstMip,
542                                        int width, int height, int depth,
543                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
544                                        int srcMip) {
545        validate();
546        rsnAllocationData3D(mContext,
547                            dstAlloc, dstXoff, dstYoff, dstZoff,
548                            dstMip, width, height, depth,
549                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
550    }
551
552    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
553                                    int w, int h, int depth, Object d, int sizeBytes, int dt);
554    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
555                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt) {
556        validate();
557        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID);
558    }
559
560    native void rsnAllocationRead(long con, long id, Object d, int dt);
561    synchronized void nAllocationRead(long id, Object d, Element.DataType dt) {
562        validate();
563        rsnAllocationRead(mContext, id, d, dt.mID);
564    }
565
566    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
567                                    int sizeBytes, int dt);
568    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
569                                        int sizeBytes, Element.DataType dt) {
570        validate();
571        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID);
572    }
573
574    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
575                                    int w, int h, Object d, int sizeBytes, int dt);
576    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
577                                        int w, int h, Object d, int sizeBytes, Element.DataType dt) {
578        validate();
579        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID);
580    }
581
582    native long  rsnAllocationGetType(long con, long id);
583    synchronized long nAllocationGetType(long id) {
584        validate();
585        return rsnAllocationGetType(mContext, id);
586    }
587
588    native void rsnAllocationResize1D(long con, long id, int dimX);
589    synchronized void nAllocationResize1D(long id, int dimX) {
590        validate();
591        rsnAllocationResize1D(mContext, id, dimX);
592    }
593
594    native long rsnFileA3DCreateFromAssetStream(long con, long assetStream);
595    synchronized long nFileA3DCreateFromAssetStream(long assetStream) {
596        validate();
597        return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
598    }
599    native long rsnFileA3DCreateFromFile(long con, String path);
600    synchronized long nFileA3DCreateFromFile(String path) {
601        validate();
602        return rsnFileA3DCreateFromFile(mContext, path);
603    }
604    native long rsnFileA3DCreateFromAsset(long con, AssetManager mgr, String path);
605    synchronized long nFileA3DCreateFromAsset(AssetManager mgr, String path) {
606        validate();
607        return rsnFileA3DCreateFromAsset(mContext, mgr, path);
608    }
609    native int  rsnFileA3DGetNumIndexEntries(long con, long fileA3D);
610    synchronized int nFileA3DGetNumIndexEntries(long fileA3D) {
611        validate();
612        return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
613    }
614    native void rsnFileA3DGetIndexEntries(long con, long fileA3D, int numEntries, int[] IDs, String[] names);
615    synchronized void nFileA3DGetIndexEntries(long fileA3D, int numEntries, int[] IDs, String[] names) {
616        validate();
617        rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
618    }
619    native long rsnFileA3DGetEntryByIndex(long con, long fileA3D, int index);
620    synchronized long nFileA3DGetEntryByIndex(long fileA3D, int index) {
621        validate();
622        return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
623    }
624
625    native long rsnFontCreateFromFile(long con, String fileName, float size, int dpi);
626    synchronized long nFontCreateFromFile(String fileName, float size, int dpi) {
627        validate();
628        return rsnFontCreateFromFile(mContext, fileName, size, dpi);
629    }
630    native long rsnFontCreateFromAssetStream(long con, String name, float size, int dpi, long assetStream);
631    synchronized long nFontCreateFromAssetStream(String name, float size, int dpi, long assetStream) {
632        validate();
633        return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
634    }
635    native long rsnFontCreateFromAsset(long con, AssetManager mgr, String path, float size, int dpi);
636    synchronized long nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
637        validate();
638        return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
639    }
640
641
642    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot);
643    synchronized void nScriptBindAllocation(long script, long alloc, int slot) {
644        validate();
645        rsnScriptBindAllocation(mContext, script, alloc, slot);
646    }
647    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone);
648    synchronized void nScriptSetTimeZone(long script, byte[] timeZone) {
649        validate();
650        rsnScriptSetTimeZone(mContext, script, timeZone);
651    }
652    native void rsnScriptInvoke(long con, long id, int slot);
653    synchronized void nScriptInvoke(long id, int slot) {
654        validate();
655        rsnScriptInvoke(mContext, id, slot);
656    }
657
658    native void rsnScriptForEach(long con, long id, int slot, long[] ains,
659                                 long aout, byte[] params, int[] limits);
660
661    synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
662                                     byte[] params, int[] limits) {
663        validate();
664        rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
665    }
666
667    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
668    synchronized void nScriptInvokeV(long id, int slot, byte[] params) {
669        validate();
670        rsnScriptInvokeV(mContext, id, slot, params);
671    }
672
673    native void rsnScriptSetVarI(long con, long id, int slot, int val);
674    synchronized void nScriptSetVarI(long id, int slot, int val) {
675        validate();
676        rsnScriptSetVarI(mContext, id, slot, val);
677    }
678    native int rsnScriptGetVarI(long con, long id, int slot);
679    synchronized int nScriptGetVarI(long id, int slot) {
680        validate();
681        return rsnScriptGetVarI(mContext, id, slot);
682    }
683
684    native void rsnScriptSetVarJ(long con, long id, int slot, long val);
685    synchronized void nScriptSetVarJ(long id, int slot, long val) {
686        validate();
687        rsnScriptSetVarJ(mContext, id, slot, val);
688    }
689    native long rsnScriptGetVarJ(long con, long id, int slot);
690    synchronized long nScriptGetVarJ(long id, int slot) {
691        validate();
692        return rsnScriptGetVarJ(mContext, id, slot);
693    }
694
695    native void rsnScriptSetVarF(long con, long id, int slot, float val);
696    synchronized void nScriptSetVarF(long id, int slot, float val) {
697        validate();
698        rsnScriptSetVarF(mContext, id, slot, val);
699    }
700    native float rsnScriptGetVarF(long con, long id, int slot);
701    synchronized float nScriptGetVarF(long id, int slot) {
702        validate();
703        return rsnScriptGetVarF(mContext, id, slot);
704    }
705    native void rsnScriptSetVarD(long con, long id, int slot, double val);
706    synchronized void nScriptSetVarD(long id, int slot, double val) {
707        validate();
708        rsnScriptSetVarD(mContext, id, slot, val);
709    }
710    native double rsnScriptGetVarD(long con, long id, int slot);
711    synchronized double nScriptGetVarD(long id, int slot) {
712        validate();
713        return rsnScriptGetVarD(mContext, id, slot);
714    }
715    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val);
716    synchronized void nScriptSetVarV(long id, int slot, byte[] val) {
717        validate();
718        rsnScriptSetVarV(mContext, id, slot, val);
719    }
720    native void rsnScriptGetVarV(long con, long id, int slot, byte[] val);
721    synchronized void nScriptGetVarV(long id, int slot, byte[] val) {
722        validate();
723        rsnScriptGetVarV(mContext, id, slot, val);
724    }
725    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
726                                  long e, int[] dims);
727    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
728                                      long e, int[] dims) {
729        validate();
730        rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
731    }
732    native void rsnScriptSetVarObj(long con, long id, int slot, long val);
733    synchronized void nScriptSetVarObj(long id, int slot, long val) {
734        validate();
735        rsnScriptSetVarObj(mContext, id, slot, val);
736    }
737
738    native long rsnScriptCCreate(long con, String resName, String cacheDir,
739                                 byte[] script, int length);
740    synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
741        validate();
742        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
743    }
744
745    native long rsnScriptIntrinsicCreate(long con, int id, long eid);
746    synchronized long nScriptIntrinsicCreate(int id, long eid) {
747        validate();
748        return rsnScriptIntrinsicCreate(mContext, id, eid);
749    }
750
751    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig);
752    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig) {
753        validate();
754        return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
755    }
756
757    native long  rsnScriptInvokeIDCreate(long con, long sid, int slot);
758    synchronized long nScriptInvokeIDCreate(long sid, int slot) {
759        validate();
760        return rsnScriptInvokeIDCreate(mContext, sid, slot);
761    }
762
763    native long  rsnScriptFieldIDCreate(long con, long sid, int slot);
764    synchronized long nScriptFieldIDCreate(long sid, int slot) {
765        validate();
766        return rsnScriptFieldIDCreate(mContext, sid, slot);
767    }
768
769    native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
770    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
771        validate();
772        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
773    }
774
775    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
776    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
777        validate();
778        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
779    }
780
781    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
782    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
783        validate();
784        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
785    }
786
787    native void rsnScriptGroupExecute(long con, long group);
788    synchronized void nScriptGroupExecute(long group) {
789        validate();
790        rsnScriptGroupExecute(mContext, group);
791    }
792
793    native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
794                                 int wrapS, int wrapT, int wrapR, float aniso);
795    synchronized long nSamplerCreate(int magFilter, int minFilter,
796                                 int wrapS, int wrapT, int wrapR, float aniso) {
797        validate();
798        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
799    }
800
801    native long rsnProgramStoreCreate(long con, boolean r, boolean g, boolean b, boolean a,
802                                      boolean depthMask, boolean dither,
803                                      int srcMode, int dstMode, int depthFunc);
804    synchronized long nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
805                                         boolean depthMask, boolean dither,
806                                         int srcMode, int dstMode, int depthFunc) {
807        validate();
808        return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode,
809                                     dstMode, depthFunc);
810    }
811
812    native long rsnProgramRasterCreate(long con, boolean pointSprite, int cullMode);
813    synchronized long nProgramRasterCreate(boolean pointSprite, int cullMode) {
814        validate();
815        return rsnProgramRasterCreate(mContext, pointSprite, cullMode);
816    }
817
818    native void rsnProgramBindConstants(long con, long pv, int slot, long mID);
819    synchronized void nProgramBindConstants(long pv, int slot, long mID) {
820        validate();
821        rsnProgramBindConstants(mContext, pv, slot, mID);
822    }
823    native void rsnProgramBindTexture(long con, long vpf, int slot, long a);
824    synchronized void nProgramBindTexture(long vpf, int slot, long a) {
825        validate();
826        rsnProgramBindTexture(mContext, vpf, slot, a);
827    }
828    native void rsnProgramBindSampler(long con, long vpf, int slot, long s);
829    synchronized void nProgramBindSampler(long vpf, int slot, long s) {
830        validate();
831        rsnProgramBindSampler(mContext, vpf, slot, s);
832    }
833    native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, long[] params);
834    synchronized long nProgramFragmentCreate(String shader, String[] texNames, long[] params) {
835        validate();
836        return rsnProgramFragmentCreate(mContext, shader, texNames, params);
837    }
838    native long rsnProgramVertexCreate(long con, String shader, String[] texNames, long[] params);
839    synchronized long nProgramVertexCreate(String shader, String[] texNames, long[] params) {
840        validate();
841        return rsnProgramVertexCreate(mContext, shader, texNames, params);
842    }
843
844    native long rsnMeshCreate(long con, long[] vtx, long[] idx, int[] prim);
845    synchronized long nMeshCreate(long[] vtx, long[] idx, int[] prim) {
846        validate();
847        return rsnMeshCreate(mContext, vtx, idx, prim);
848    }
849    native int  rsnMeshGetVertexBufferCount(long con, long id);
850    synchronized int nMeshGetVertexBufferCount(long id) {
851        validate();
852        return rsnMeshGetVertexBufferCount(mContext, id);
853    }
854    native int  rsnMeshGetIndexCount(long con, long id);
855    synchronized int nMeshGetIndexCount(long id) {
856        validate();
857        return rsnMeshGetIndexCount(mContext, id);
858    }
859    native void rsnMeshGetVertices(long con, long id, long[] vtxIds, int vtxIdCount);
860    synchronized void nMeshGetVertices(long id, long[] vtxIds, int vtxIdCount) {
861        validate();
862        rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
863    }
864    native void rsnMeshGetIndices(long con, long id, long[] idxIds, int[] primitives, int vtxIdCount);
865    synchronized void nMeshGetIndices(long id, long[] idxIds, int[] primitives, int vtxIdCount) {
866        validate();
867        rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
868    }
869
870    native long rsnPathCreate(long con, int prim, boolean isStatic, long vtx, long loop, float q);
871    synchronized long nPathCreate(int prim, boolean isStatic, long vtx, long loop, float q) {
872        validate();
873        return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q);
874    }
875
876    long     mDev;
877    long     mContext;
878    @SuppressWarnings({"FieldCanBeLocal"})
879    MessageThread mMessageThread;
880
881    Element mElement_U8;
882    Element mElement_I8;
883    Element mElement_U16;
884    Element mElement_I16;
885    Element mElement_U32;
886    Element mElement_I32;
887    Element mElement_U64;
888    Element mElement_I64;
889    Element mElement_F16;
890    Element mElement_F32;
891    Element mElement_F64;
892    Element mElement_BOOLEAN;
893
894    Element mElement_ELEMENT;
895    Element mElement_TYPE;
896    Element mElement_ALLOCATION;
897    Element mElement_SAMPLER;
898    Element mElement_SCRIPT;
899    Element mElement_MESH;
900    Element mElement_PROGRAM_FRAGMENT;
901    Element mElement_PROGRAM_VERTEX;
902    Element mElement_PROGRAM_RASTER;
903    Element mElement_PROGRAM_STORE;
904    Element mElement_FONT;
905
906    Element mElement_A_8;
907    Element mElement_RGB_565;
908    Element mElement_RGB_888;
909    Element mElement_RGBA_5551;
910    Element mElement_RGBA_4444;
911    Element mElement_RGBA_8888;
912
913    Element mElement_HALF_2;
914    Element mElement_HALF_3;
915    Element mElement_HALF_4;
916
917    Element mElement_FLOAT_2;
918    Element mElement_FLOAT_3;
919    Element mElement_FLOAT_4;
920
921    Element mElement_DOUBLE_2;
922    Element mElement_DOUBLE_3;
923    Element mElement_DOUBLE_4;
924
925    Element mElement_UCHAR_2;
926    Element mElement_UCHAR_3;
927    Element mElement_UCHAR_4;
928
929    Element mElement_CHAR_2;
930    Element mElement_CHAR_3;
931    Element mElement_CHAR_4;
932
933    Element mElement_USHORT_2;
934    Element mElement_USHORT_3;
935    Element mElement_USHORT_4;
936
937    Element mElement_SHORT_2;
938    Element mElement_SHORT_3;
939    Element mElement_SHORT_4;
940
941    Element mElement_UINT_2;
942    Element mElement_UINT_3;
943    Element mElement_UINT_4;
944
945    Element mElement_INT_2;
946    Element mElement_INT_3;
947    Element mElement_INT_4;
948
949    Element mElement_ULONG_2;
950    Element mElement_ULONG_3;
951    Element mElement_ULONG_4;
952
953    Element mElement_LONG_2;
954    Element mElement_LONG_3;
955    Element mElement_LONG_4;
956
957    Element mElement_YUV;
958
959    Element mElement_MATRIX_4X4;
960    Element mElement_MATRIX_3X3;
961    Element mElement_MATRIX_2X2;
962
963    Sampler mSampler_CLAMP_NEAREST;
964    Sampler mSampler_CLAMP_LINEAR;
965    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
966    Sampler mSampler_WRAP_NEAREST;
967    Sampler mSampler_WRAP_LINEAR;
968    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
969    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
970    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
971    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
972
973    ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
974    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
975    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
976    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
977
978    ProgramRaster mProgramRaster_CULL_BACK;
979    ProgramRaster mProgramRaster_CULL_FRONT;
980    ProgramRaster mProgramRaster_CULL_NONE;
981
982    ///////////////////////////////////////////////////////////////////////////////////
983    //
984
985    /**
986     * The base class from which an application should derive in order
987     * to receive RS messages from scripts. When a script calls {@code
988     * rsSendToClient}, the data fields will be filled, and the run
989     * method will be called on a separate thread.  This will occur
990     * some time after {@code rsSendToClient} completes in the script,
991     * as {@code rsSendToClient} is asynchronous. Message handlers are
992     * not guaranteed to have completed when {@link
993     * android.renderscript.RenderScript#finish} returns.
994     *
995     */
996    public static class RSMessageHandler implements Runnable {
997        protected int[] mData;
998        protected int mID;
999        protected int mLength;
1000        public void run() {
1001        }
1002    }
1003    /**
1004     * If an application is expecting messages, it should set this
1005     * field to an instance of {@link RSMessageHandler}.  This
1006     * instance will receive all the user messages sent from {@code
1007     * sendToClient} by scripts from this context.
1008     *
1009     */
1010    RSMessageHandler mMessageCallback = null;
1011
1012    public void setMessageHandler(RSMessageHandler msg) {
1013        mMessageCallback = msg;
1014    }
1015    public RSMessageHandler getMessageHandler() {
1016        return mMessageCallback;
1017    }
1018
1019    /**
1020     * Place a message into the message queue to be sent back to the message
1021     * handler once all previous commands have been executed.
1022     *
1023     * @param id
1024     * @param data
1025     */
1026    public void sendMessage(int id, int[] data) {
1027        nContextSendMessage(id, data);
1028    }
1029
1030    /**
1031     * The runtime error handler base class.  An application should derive from this class
1032     * if it wishes to install an error handler.  When errors occur at runtime,
1033     * the fields in this class will be filled, and the run method will be called.
1034     *
1035     */
1036    public static class RSErrorHandler implements Runnable {
1037        protected String mErrorMessage;
1038        protected int mErrorNum;
1039        public void run() {
1040        }
1041    }
1042
1043    /**
1044     * Application Error handler.  All runtime errors will be dispatched to the
1045     * instance of RSAsyncError set here.  If this field is null a
1046     * {@link RSRuntimeException} will instead be thrown with details about the error.
1047     * This will cause program termaination.
1048     *
1049     */
1050    RSErrorHandler mErrorCallback = null;
1051
1052    public void setErrorHandler(RSErrorHandler msg) {
1053        mErrorCallback = msg;
1054    }
1055    public RSErrorHandler getErrorHandler() {
1056        return mErrorCallback;
1057    }
1058
1059    /**
1060     * RenderScript worker thread priority enumeration.  The default value is
1061     * NORMAL.  Applications wishing to do background processing should set
1062     * their priority to LOW to avoid starving forground processes.
1063     */
1064    public enum Priority {
1065        // These values used to represent official thread priority values
1066        // now they are simply enums to be used by the runtime side
1067        LOW (15),
1068        NORMAL (-8);
1069
1070        int mID;
1071        Priority(int id) {
1072            mID = id;
1073        }
1074    }
1075
1076    void validateObject(BaseObj o) {
1077        if (o != null) {
1078            if (o.mRS != this) {
1079                throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
1080            }
1081        }
1082    }
1083
1084    void validate() {
1085        if (mContext == 0) {
1086            throw new RSInvalidStateException("Calling RS with no Context active.");
1087        }
1088    }
1089
1090
1091    /**
1092     * Change the priority of the worker threads for this context.
1093     *
1094     * @param p New priority to be set.
1095     */
1096    public void setPriority(Priority p) {
1097        validate();
1098        nContextSetPriority(p.mID);
1099    }
1100
1101    static class MessageThread extends Thread {
1102        RenderScript mRS;
1103        boolean mRun = true;
1104        int[] mAuxData = new int[2];
1105
1106        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
1107        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
1108        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
1109        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
1110        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
1111        static final int RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5;
1112
1113        static final int RS_ERROR_FATAL_DEBUG = 0x0800;
1114        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
1115
1116        MessageThread(RenderScript rs) {
1117            super("RSMessageThread");
1118            mRS = rs;
1119
1120        }
1121
1122        public void run() {
1123            // This function is a temporary solution.  The final solution will
1124            // used typed allocations where the message id is the type indicator.
1125            int[] rbuf = new int[16];
1126            mRS.nContextInitToClient(mRS.mContext);
1127            while(mRun) {
1128                rbuf[0] = 0;
1129                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
1130                int size = mAuxData[1];
1131                int subID = mAuxData[0];
1132
1133                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
1134                    if ((size>>2) >= rbuf.length) {
1135                        rbuf = new int[(size + 3) >> 2];
1136                    }
1137                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1138                        RS_MESSAGE_TO_CLIENT_USER) {
1139                        throw new RSDriverException("Error processing message from RenderScript.");
1140                    }
1141
1142                    if(mRS.mMessageCallback != null) {
1143                        mRS.mMessageCallback.mData = rbuf;
1144                        mRS.mMessageCallback.mID = subID;
1145                        mRS.mMessageCallback.mLength = size;
1146                        mRS.mMessageCallback.run();
1147                    } else {
1148                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
1149                    }
1150                    continue;
1151                }
1152
1153                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
1154                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
1155
1156                    // Throw RSRuntimeException under the following conditions:
1157                    //
1158                    // 1) It is an unknown fatal error.
1159                    // 2) It is a debug fatal error, and we are not in a
1160                    //    debug context.
1161                    // 3) It is a debug fatal error, and we do not have an
1162                    //    error callback.
1163                    if (subID >= RS_ERROR_FATAL_UNKNOWN ||
1164                        (subID >= RS_ERROR_FATAL_DEBUG &&
1165                         (mRS.mContextType != ContextType.DEBUG ||
1166                          mRS.mErrorCallback == null))) {
1167                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
1168                    }
1169
1170                    if(mRS.mErrorCallback != null) {
1171                        mRS.mErrorCallback.mErrorMessage = e;
1172                        mRS.mErrorCallback.mErrorNum = subID;
1173                        mRS.mErrorCallback.run();
1174                    } else {
1175                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
1176                        // Do not throw here. In these cases, we do not have
1177                        // a fatal error.
1178                    }
1179                    continue;
1180                }
1181
1182                if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
1183                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1184                        RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
1185                        throw new RSDriverException("Error processing message from RenderScript.");
1186                    }
1187                    long bufferID = ((long)rbuf[1] << 32L) + ((long)rbuf[0] & 0xffffffffL);
1188                    Allocation.sendBufferNotification(bufferID);
1189                    continue;
1190                }
1191
1192                // 2: teardown.
1193                // But we want to avoid starving other threads during
1194                // teardown by yielding until the next line in the destructor
1195                // can execute to set mRun = false
1196                try {
1197                    sleep(1, 0);
1198                } catch(InterruptedException e) {
1199                }
1200            }
1201            //Log.d(LOG_TAG, "MessageThread exiting.");
1202        }
1203    }
1204
1205    RenderScript(Context ctx) {
1206        mContextType = ContextType.NORMAL;
1207        if (ctx != null) {
1208            mApplicationContext = ctx.getApplicationContext();
1209        }
1210        mRWLock = new ReentrantReadWriteLock();
1211        try {
1212            registerNativeAllocation.invoke(sRuntime, 4 * 1024 * 1024); // 4MB for GC sake
1213        } catch (Exception e) {
1214            Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
1215            throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
1216        }
1217
1218    }
1219
1220    /**
1221     * Gets the application context associated with the RenderScript context.
1222     *
1223     * @return The application context.
1224     */
1225    public final Context getApplicationContext() {
1226        return mApplicationContext;
1227    }
1228
1229    /**
1230     * @hide
1231     */
1232    public static RenderScript create(Context ctx, int sdkVersion) {
1233        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
1234    }
1235
1236    /**
1237     * Create a RenderScript context.
1238     *
1239     * @hide
1240     * @param ctx The context.
1241     * @return RenderScript
1242     */
1243    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
1244        if (!sInitialized) {
1245            Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
1246            return null;
1247        }
1248
1249        if ((flags & ~(CREATE_FLAG_LOW_LATENCY | CREATE_FLAG_LOW_POWER)) != 0) {
1250            throw new RSIllegalArgumentException("Invalid flags passed.");
1251        }
1252
1253        RenderScript rs = new RenderScript(ctx);
1254
1255        rs.mDev = rs.nDeviceCreate();
1256        rs.mContext = rs.nContextCreate(rs.mDev, flags, sdkVersion, ct.mID);
1257        rs.mContextType = ct;
1258        if (rs.mContext == 0) {
1259            throw new RSDriverException("Failed to create RS context.");
1260        }
1261        rs.mMessageThread = new MessageThread(rs);
1262        rs.mMessageThread.start();
1263        return rs;
1264    }
1265
1266    /**
1267     * Create a RenderScript context.
1268     *
1269     * @param ctx The context.
1270     * @return RenderScript
1271     */
1272    public static RenderScript create(Context ctx) {
1273        return create(ctx, ContextType.NORMAL);
1274    }
1275
1276    /**
1277     * Create a RenderScript context.
1278     *
1279     *
1280     * @param ctx The context.
1281     * @param ct The type of context to be created.
1282     * @return RenderScript
1283     */
1284    public static RenderScript create(Context ctx, ContextType ct) {
1285        int v = ctx.getApplicationInfo().targetSdkVersion;
1286        return create(ctx, v, ct, CREATE_FLAG_NONE);
1287    }
1288
1289     /**
1290     * Create a RenderScript context.
1291     *
1292     *
1293     * @param ctx The context.
1294     * @param ct The type of context to be created.
1295     * @param flags The OR of the CREATE_FLAG_* options desired
1296     * @return RenderScript
1297     */
1298    public static RenderScript create(Context ctx, ContextType ct, int flags) {
1299        int v = ctx.getApplicationInfo().targetSdkVersion;
1300        return create(ctx, v, ct, flags);
1301    }
1302
1303    /**
1304     * Print the currently available debugging information about the state of
1305     * the RS context to the log.
1306     *
1307     */
1308    public void contextDump() {
1309        validate();
1310        nContextDump(0);
1311    }
1312
1313    /**
1314     * Wait for any pending asynchronous opeations (such as copies to a RS
1315     * allocation or RS script executions) to complete.
1316     *
1317     */
1318    public void finish() {
1319        nContextFinish();
1320    }
1321
1322    /**
1323     * Destroys this RenderScript context.  Once this function is called,
1324     * using this context or any objects belonging to this context is
1325     * illegal.
1326     *
1327     */
1328    public void destroy() {
1329        validate();
1330        nContextFinish();
1331
1332        nContextDeinitToClient(mContext);
1333        mMessageThread.mRun = false;
1334        try {
1335            mMessageThread.join();
1336        } catch(InterruptedException e) {
1337        }
1338
1339        nContextDestroy();
1340
1341        nDeviceDestroy(mDev);
1342        mDev = 0;
1343    }
1344
1345    boolean isAlive() {
1346        return mContext != 0;
1347    }
1348
1349    long safeID(BaseObj o) {
1350        if(o != null) {
1351            return o.getID(this);
1352        }
1353        return 0;
1354    }
1355}
1356