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.nio.ByteBuffer;
22import java.util.ArrayList;
23import java.util.concurrent.locks.ReentrantReadWriteLock;
24
25import android.content.Context;
26import android.content.res.AssetManager;
27import android.graphics.Bitmap;
28import android.graphics.SurfaceTexture;
29import android.os.SystemProperties;
30import android.os.Trace;
31import android.util.Log;
32import android.view.Surface;
33
34// TODO: Clean up the whitespace that separates methods in this class.
35
36/**
37 * This class provides access to a RenderScript context, which controls RenderScript
38 * initialization, resource management, and teardown. An instance of the RenderScript
39 * class must be created before any other RS objects can be created.
40 *
41 * <div class="special reference">
42 * <h3>Developer Guides</h3>
43 * <p>For more information about creating an application that uses RenderScript, read the
44 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
45 * </div>
46 **/
47public class RenderScript {
48    static final long TRACE_TAG = Trace.TRACE_TAG_RS;
49
50    static final String LOG_TAG = "RenderScript_jni";
51    static final boolean DEBUG  = false;
52    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
53    static final boolean LOG_ENABLED = false;
54
55    static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
56    private boolean mIsProcessContext = false;
57    private int mContextFlags = 0;
58    private int mContextSdkVersion = 0;
59
60
61    private Context mApplicationContext;
62
63    /*
64     * We use a class initializer to allow the native code to cache some
65     * field offsets.
66     */
67    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // TODO: now used locally; remove?
68    static boolean sInitialized;
69    native static void _nInit();
70
71    static Object sRuntime;
72    static Method registerNativeAllocation;
73    static Method registerNativeFree;
74
75    /*
76     * Context creation flag that specifies a normal context.
77    */
78    public static final int CREATE_FLAG_NONE = 0x0000;
79
80    /*
81     * Context creation flag which specifies a context optimized for low
82     * latency over peak performance. This is a hint and may have no effect
83     * on some implementations.
84    */
85    public static final int CREATE_FLAG_LOW_LATENCY = 0x0002;
86
87    /*
88     * Context creation flag which specifies a context optimized for long
89     * battery life over peak performance. This is a hint and may have no effect
90     * on some implementations.
91    */
92    public static final int CREATE_FLAG_LOW_POWER = 0x0004;
93
94    /**
95     * @hide
96     * Context creation flag which instructs the implementation to wait for
97     * a debugger to be attached before continuing execution.
98    */
99    public static final int CREATE_FLAG_WAIT_FOR_ATTACH = 0x0008;
100
101
102    /*
103     * Detect the bitness of the VM to allow FieldPacker to do the right thing.
104     */
105    static native int rsnSystemGetPointerSize();
106    static int sPointerSize;
107
108    static {
109        sInitialized = false;
110        if (!SystemProperties.getBoolean("config.disable_renderscript", false)) {
111            try {
112                Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
113                Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
114                sRuntime = get_runtime.invoke(null);
115                registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
116                registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
117            } catch (Exception e) {
118                Log.e(LOG_TAG, "Error loading GC methods: " + e);
119                throw new RSRuntimeException("Error loading GC methods: " + e);
120            }
121            try {
122                System.loadLibrary("rs_jni");
123                _nInit();
124                sInitialized = true;
125                sPointerSize = rsnSystemGetPointerSize();
126            } catch (UnsatisfiedLinkError e) {
127                Log.e(LOG_TAG, "Error loading RS jni library: " + e);
128                throw new RSRuntimeException("Error loading RS jni library: " + e);
129            }
130        }
131    }
132
133    // Non-threadsafe functions.
134    native long  nDeviceCreate();
135    native void nDeviceDestroy(long dev);
136    native void nDeviceSetConfig(long dev, int param, int value);
137    native int nContextGetUserMessage(long con, int[] data);
138    native String nContextGetErrorMessage(long con);
139    native int  nContextPeekMessage(long con, int[] subID);
140    native void nContextInitToClient(long con);
141    native void nContextDeinitToClient(long con);
142
143    // this should be a monotonically increasing ID
144    // used in conjunction with the API version of a device
145    static final long sMinorVersion = 1;
146
147    /**
148     * @hide
149     *
150     * Only exist to be compatible with old version RenderScript Support lib.
151     * Will eventually be removed.
152     *
153     * @return Always return 1
154     *
155     */
156    public static long getMinorID() {
157        return 1;
158    }
159
160
161    /**
162     * Returns an identifier that can be used to identify a particular
163     * minor version of RS.
164     *
165     * @return The minor RenderScript version number
166     *
167     */
168    public static long getMinorVersion() {
169        return sMinorVersion;
170    }
171
172    /**
173     * ContextType specifies the specific type of context to be created.
174     *
175     */
176    public enum ContextType {
177        /**
178         * NORMAL context, this is the default and what shipping apps should
179         * use.
180         */
181        NORMAL (0),
182
183        /**
184         * DEBUG context, perform extra runtime checks to validate the
185         * kernels and APIs are being used as intended.  Get and SetElementAt
186         * will be bounds checked in this mode.
187         */
188        DEBUG (1),
189
190        /**
191         * PROFILE context, Intended to be used once the first time an
192         * application is run on a new device.  This mode allows the runtime to
193         * do additional testing and performance tuning.
194         */
195        PROFILE (2);
196
197        int mID;
198        ContextType(int id) {
199            mID = id;
200        }
201    }
202
203    ContextType mContextType;
204    ReentrantReadWriteLock mRWLock;
205
206    // Methods below are wrapped to protect the non-threadsafe
207    // lockless fifo.
208    native long  rsnContextCreateGL(long dev, int ver, int sdkVer,
209                 int colorMin, int colorPref,
210                 int alphaMin, int alphaPref,
211                 int depthMin, int depthPref,
212                 int stencilMin, int stencilPref,
213                 int samplesMin, int samplesPref, float samplesQ, int dpi);
214    synchronized long nContextCreateGL(long dev, int ver, int sdkVer,
215                 int colorMin, int colorPref,
216                 int alphaMin, int alphaPref,
217                 int depthMin, int depthPref,
218                 int stencilMin, int stencilPref,
219                 int samplesMin, int samplesPref, float samplesQ, int dpi) {
220        return rsnContextCreateGL(dev, ver, sdkVer, colorMin, colorPref,
221                                  alphaMin, alphaPref, depthMin, depthPref,
222                                  stencilMin, stencilPref,
223                                  samplesMin, samplesPref, samplesQ, dpi);
224    }
225    native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType);
226    synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType) {
227        return rsnContextCreate(dev, ver, sdkVer, contextType);
228    }
229    native void rsnContextDestroy(long con);
230    synchronized void nContextDestroy() {
231        validate();
232
233        // take teardown lock
234        // teardown lock can only be taken when no objects are being destroyed
235        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
236        wlock.lock();
237
238        long curCon = mContext;
239        // context is considered dead as of this point
240        mContext = 0;
241
242        wlock.unlock();
243        rsnContextDestroy(curCon);
244    }
245    native void rsnContextSetSurface(long con, int w, int h, Surface sur);
246    synchronized void nContextSetSurface(int w, int h, Surface sur) {
247        validate();
248        rsnContextSetSurface(mContext, w, h, sur);
249    }
250    native void rsnContextSetSurfaceTexture(long con, int w, int h, SurfaceTexture sur);
251    synchronized void nContextSetSurfaceTexture(int w, int h, SurfaceTexture sur) {
252        validate();
253        rsnContextSetSurfaceTexture(mContext, w, h, sur);
254    }
255    native void rsnContextSetPriority(long con, int p);
256    synchronized void nContextSetPriority(int p) {
257        validate();
258        rsnContextSetPriority(mContext, p);
259    }
260    native void rsnContextSetCacheDir(long con, String cacheDir);
261    synchronized void nContextSetCacheDir(String cacheDir) {
262        validate();
263        rsnContextSetCacheDir(mContext, cacheDir);
264    }
265    native void rsnContextDump(long con, int bits);
266    synchronized void nContextDump(int bits) {
267        validate();
268        rsnContextDump(mContext, bits);
269    }
270    native void rsnContextFinish(long con);
271    synchronized void nContextFinish() {
272        validate();
273        rsnContextFinish(mContext);
274    }
275
276    native void rsnContextSendMessage(long con, int id, int[] data);
277    synchronized void nContextSendMessage(int id, int[] data) {
278        validate();
279        rsnContextSendMessage(mContext, id, data);
280    }
281
282    native void rsnContextBindRootScript(long con, long script);
283    synchronized void nContextBindRootScript(long script) {
284        validate();
285        rsnContextBindRootScript(mContext, script);
286    }
287    native void rsnContextBindSampler(long con, int sampler, int slot);
288    synchronized void nContextBindSampler(int sampler, int slot) {
289        validate();
290        rsnContextBindSampler(mContext, sampler, slot);
291    }
292    native void rsnContextBindProgramStore(long con, long pfs);
293    synchronized void nContextBindProgramStore(long pfs) {
294        validate();
295        rsnContextBindProgramStore(mContext, pfs);
296    }
297    native void rsnContextBindProgramFragment(long con, long pf);
298    synchronized void nContextBindProgramFragment(long pf) {
299        validate();
300        rsnContextBindProgramFragment(mContext, pf);
301    }
302    native void rsnContextBindProgramVertex(long con, long pv);
303    synchronized void nContextBindProgramVertex(long pv) {
304        validate();
305        rsnContextBindProgramVertex(mContext, pv);
306    }
307    native void rsnContextBindProgramRaster(long con, long pr);
308    synchronized void nContextBindProgramRaster(long pr) {
309        validate();
310        rsnContextBindProgramRaster(mContext, pr);
311    }
312    native void rsnContextPause(long con);
313    synchronized void nContextPause() {
314        validate();
315        rsnContextPause(mContext);
316    }
317    native void rsnContextResume(long con);
318    synchronized void nContextResume() {
319        validate();
320        rsnContextResume(mContext);
321    }
322
323    native long rsnClosureCreate(long con, long kernelID, long returnValue,
324        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
325        long[] depFieldIDs);
326    synchronized long nClosureCreate(long kernelID, long returnValue,
327        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
328        long[] depFieldIDs) {
329      validate();
330      long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
331          sizes, depClosures, depFieldIDs);
332      if (c == 0) {
333          throw new RSRuntimeException("Failed creating closure.");
334      }
335      return c;
336    }
337
338    native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
339        long[] fieldIDs, long[] values, int[] sizes);
340    synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
341        long[] fieldIDs, long[] values, int[] sizes) {
342      validate();
343      long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
344          values, sizes);
345      if (c == 0) {
346          throw new RSRuntimeException("Failed creating closure.");
347      }
348      return c;
349    }
350
351    native void rsnClosureSetArg(long con, long closureID, int index,
352      long value, int size);
353    synchronized void nClosureSetArg(long closureID, int index, long value,
354        int size) {
355      validate();
356      rsnClosureSetArg(mContext, closureID, index, value, size);
357    }
358
359    native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
360        long value, int size);
361    // Does this have to be synchronized?
362    synchronized void nClosureSetGlobal(long closureID, long fieldID,
363        long value, int size) {
364      validate(); // TODO: is this necessary?
365      rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
366    }
367
368    native long rsnScriptGroup2Create(long con, String name, String cachePath,
369                                      long[] closures);
370    synchronized long nScriptGroup2Create(String name, String cachePath,
371                                          long[] closures) {
372      validate();
373      long g = rsnScriptGroup2Create(mContext, name, cachePath, closures);
374      if (g == 0) {
375          throw new RSRuntimeException("Failed creating script group.");
376      }
377      return g;
378    }
379
380    native void rsnScriptGroup2Execute(long con, long groupID);
381    synchronized void nScriptGroup2Execute(long groupID) {
382      validate();
383      rsnScriptGroup2Execute(mContext, groupID);
384    }
385
386    native void rsnAssignName(long con, long obj, byte[] name);
387    synchronized void nAssignName(long obj, byte[] name) {
388        validate();
389        rsnAssignName(mContext, obj, name);
390    }
391    native String rsnGetName(long con, long obj);
392    synchronized String nGetName(long obj) {
393        validate();
394        return rsnGetName(mContext, obj);
395    }
396
397    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
398    native void rsnObjDestroy(long con, long id);
399    void nObjDestroy(long id) {
400        // There is a race condition here.  The calling code may be run
401        // by the gc while teardown is occuring.  This protects againts
402        // deleting dead objects.
403        if (mContext != 0) {
404            rsnObjDestroy(mContext, id);
405        }
406    }
407
408    native long rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
409    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
410        validate();
411        return rsnElementCreate(mContext, type, kind, norm, vecSize);
412    }
413    native long rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
414    synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
415        validate();
416        return rsnElementCreate2(mContext, elements, names, arraySizes);
417    }
418    native void rsnElementGetNativeData(long con, long id, int[] elementData);
419    synchronized void nElementGetNativeData(long id, int[] elementData) {
420        validate();
421        rsnElementGetNativeData(mContext, id, elementData);
422    }
423    native void rsnElementGetSubElements(long con, long id,
424                                         long[] IDs, String[] names, int[] arraySizes);
425    synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
426        validate();
427        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
428    }
429
430    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
431    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
432        validate();
433        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
434    }
435    native void rsnTypeGetNativeData(long con, long id, long[] typeData);
436    synchronized void nTypeGetNativeData(long id, long[] typeData) {
437        validate();
438        rsnTypeGetNativeData(mContext, id, typeData);
439    }
440
441    native long rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
442    synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
443        validate();
444        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
445    }
446    native long rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
447    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
448        validate();
449        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
450    }
451
452    native long rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
453    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
454        validate();
455        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
456    }
457
458    native long rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
459    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
460        validate();
461        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
462    }
463    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
464    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
465        validate();
466        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
467    }
468    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
469    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
470        validate();
471        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
472    }
473
474    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
475    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
476        validate();
477        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
478    }
479
480    native void rsnAllocationSyncAll(long con, long alloc, int src);
481    synchronized void nAllocationSyncAll(long alloc, int src) {
482        validate();
483        rsnAllocationSyncAll(mContext, alloc, src);
484    }
485
486    native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, long[] stride, int xBytesSize, int dimY, int dimZ);
487    synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, long[] stride, int xBytesSize, int dimY, int dimZ) {
488        validate();
489        return rsnAllocationGetByteBuffer(mContext, alloc, stride, xBytesSize, dimY, dimZ);
490    }
491
492    native void rsnAllocationSetupBufferQueue(long con, long alloc, int numAlloc);
493    synchronized void nAllocationSetupBufferQueue(long alloc, int numAlloc) {
494        validate();
495        rsnAllocationSetupBufferQueue(mContext, alloc, numAlloc);
496    }
497    native void rsnAllocationShareBufferQueue(long con, long alloc1, long alloc2);
498    synchronized void nAllocationShareBufferQueue(long alloc1, long alloc2) {
499        validate();
500        rsnAllocationShareBufferQueue(mContext, alloc1, alloc2);
501    }
502    native Surface rsnAllocationGetSurface(long con, long alloc);
503    synchronized Surface nAllocationGetSurface(long alloc) {
504        validate();
505        return rsnAllocationGetSurface(mContext, alloc);
506    }
507    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
508    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
509        validate();
510        rsnAllocationSetSurface(mContext, alloc, sur);
511    }
512    native void rsnAllocationIoSend(long con, long alloc);
513    synchronized void nAllocationIoSend(long alloc) {
514        validate();
515        rsnAllocationIoSend(mContext, alloc);
516    }
517    native long rsnAllocationIoReceive(long con, long alloc);
518    synchronized long nAllocationIoReceive(long alloc) {
519        validate();
520        return rsnAllocationIoReceive(mContext, alloc);
521    }
522
523    native void rsnAllocationGenerateMipmaps(long con, long alloc);
524    synchronized void nAllocationGenerateMipmaps(long alloc) {
525        validate();
526        rsnAllocationGenerateMipmaps(mContext, alloc);
527    }
528    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
529    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
530        validate();
531        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
532    }
533
534
535    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt,
536                                    int mSize, boolean usePadding);
537    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt,
538                                        int mSize, boolean usePadding) {
539        validate();
540        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
541    }
542
543    native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes);
544    synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) {
545        validate();
546        rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
547    }
548
549    native void rsnAllocationData2D(long con,
550                                    long dstAlloc, int dstXoff, int dstYoff,
551                                    int dstMip, int dstFace,
552                                    int width, int height,
553                                    long srcAlloc, int srcXoff, int srcYoff,
554                                    int srcMip, int srcFace);
555    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
556                                        int dstMip, int dstFace,
557                                        int width, int height,
558                                        long srcAlloc, int srcXoff, int srcYoff,
559                                        int srcMip, int srcFace) {
560        validate();
561        rsnAllocationData2D(mContext,
562                            dstAlloc, dstXoff, dstYoff,
563                            dstMip, dstFace,
564                            width, height,
565                            srcAlloc, srcXoff, srcYoff,
566                            srcMip, srcFace);
567    }
568
569    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
570                                    int w, int h, Object d, int sizeBytes, int dt,
571                                    int mSize, boolean usePadding);
572    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
573                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
574                                        int mSize, boolean usePadding) {
575        validate();
576        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
577    }
578
579    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
580    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
581        validate();
582        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
583    }
584
585    native void rsnAllocationData3D(long con,
586                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
587                                    int dstMip,
588                                    int width, int height, int depth,
589                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
590                                    int srcMip);
591    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
592                                        int dstMip,
593                                        int width, int height, int depth,
594                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
595                                        int srcMip) {
596        validate();
597        rsnAllocationData3D(mContext,
598                            dstAlloc, dstXoff, dstYoff, dstZoff,
599                            dstMip, width, height, depth,
600                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
601    }
602
603    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
604                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
605                                    int mSize, boolean usePadding);
606    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
607                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
608                                        int mSize, boolean usePadding) {
609        validate();
610        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes,
611                            dt.mID, mSize, usePadding);
612    }
613
614    native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding);
615    synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) {
616        validate();
617        rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding);
618    }
619
620    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
621                                    int sizeBytes, int dt, int mSize, boolean usePadding);
622    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
623                                        int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) {
624        validate();
625        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
626    }
627
628    native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff,
629                                         int mip, int compIdx, byte[] d, int sizeBytes);
630    synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff,
631                                             int mip, int compIdx, byte[] d, int sizeBytes) {
632        validate();
633        rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
634    }
635
636    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
637                                    int w, int h, Object d, int sizeBytes, int dt,
638                                    int mSize, boolean usePadding);
639    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
640                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
641                                        int mSize, boolean usePadding) {
642        validate();
643        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
644    }
645
646    native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip,
647                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
648                                    int mSize, boolean usePadding);
649    synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip,
650                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
651                                        int mSize, boolean usePadding) {
652        validate();
653        rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding);
654    }
655
656    native long  rsnAllocationGetType(long con, long id);
657    synchronized long nAllocationGetType(long id) {
658        validate();
659        return rsnAllocationGetType(mContext, id);
660    }
661
662    native void rsnAllocationResize1D(long con, long id, int dimX);
663    synchronized void nAllocationResize1D(long id, int dimX) {
664        validate();
665        rsnAllocationResize1D(mContext, id, dimX);
666    }
667
668    native long  rsnAllocationAdapterCreate(long con, long allocId, long typeId);
669    synchronized long nAllocationAdapterCreate(long allocId, long typeId) {
670        validate();
671        return rsnAllocationAdapterCreate(mContext, allocId, typeId);
672    }
673
674    native void  rsnAllocationAdapterOffset(long con, long id, int x, int y, int z,
675                                            int mip, int face, int a1, int a2, int a3, int a4);
676    synchronized void nAllocationAdapterOffset(long id, int x, int y, int z,
677                                               int mip, int face, int a1, int a2, int a3, int a4) {
678        validate();
679        rsnAllocationAdapterOffset(mContext, id, x, y, z, mip, face, a1, a2, a3, a4);
680    }
681
682    native long rsnFileA3DCreateFromAssetStream(long con, long assetStream);
683    synchronized long nFileA3DCreateFromAssetStream(long assetStream) {
684        validate();
685        return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
686    }
687    native long rsnFileA3DCreateFromFile(long con, String path);
688    synchronized long nFileA3DCreateFromFile(String path) {
689        validate();
690        return rsnFileA3DCreateFromFile(mContext, path);
691    }
692    native long rsnFileA3DCreateFromAsset(long con, AssetManager mgr, String path);
693    synchronized long nFileA3DCreateFromAsset(AssetManager mgr, String path) {
694        validate();
695        return rsnFileA3DCreateFromAsset(mContext, mgr, path);
696    }
697    native int  rsnFileA3DGetNumIndexEntries(long con, long fileA3D);
698    synchronized int nFileA3DGetNumIndexEntries(long fileA3D) {
699        validate();
700        return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
701    }
702    native void rsnFileA3DGetIndexEntries(long con, long fileA3D, int numEntries, int[] IDs, String[] names);
703    synchronized void nFileA3DGetIndexEntries(long fileA3D, int numEntries, int[] IDs, String[] names) {
704        validate();
705        rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
706    }
707    native long rsnFileA3DGetEntryByIndex(long con, long fileA3D, int index);
708    synchronized long nFileA3DGetEntryByIndex(long fileA3D, int index) {
709        validate();
710        return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
711    }
712
713    native long rsnFontCreateFromFile(long con, String fileName, float size, int dpi);
714    synchronized long nFontCreateFromFile(String fileName, float size, int dpi) {
715        validate();
716        return rsnFontCreateFromFile(mContext, fileName, size, dpi);
717    }
718    native long rsnFontCreateFromAssetStream(long con, String name, float size, int dpi, long assetStream);
719    synchronized long nFontCreateFromAssetStream(String name, float size, int dpi, long assetStream) {
720        validate();
721        return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
722    }
723    native long rsnFontCreateFromAsset(long con, AssetManager mgr, String path, float size, int dpi);
724    synchronized long nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
725        validate();
726        return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
727    }
728
729
730    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot);
731    synchronized void nScriptBindAllocation(long script, long alloc, int slot) {
732        validate();
733        rsnScriptBindAllocation(mContext, script, alloc, slot);
734    }
735    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone);
736    synchronized void nScriptSetTimeZone(long script, byte[] timeZone) {
737        validate();
738        rsnScriptSetTimeZone(mContext, script, timeZone);
739    }
740    native void rsnScriptInvoke(long con, long id, int slot);
741    synchronized void nScriptInvoke(long id, int slot) {
742        validate();
743        rsnScriptInvoke(mContext, id, slot);
744    }
745
746    native void rsnScriptForEach(long con, long id, int slot, long[] ains,
747                                 long aout, byte[] params, int[] limits);
748
749    synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
750                                     byte[] params, int[] limits) {
751        validate();
752        rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
753    }
754
755    native void rsnScriptReduce(long con, long id, int slot, long[] ains,
756                                long aout, int[] limits);
757    synchronized void nScriptReduce(long id, int slot, long ains[], long aout,
758                                    int[] limits) {
759        validate();
760        rsnScriptReduce(mContext, id, slot, ains, aout, limits);
761    }
762
763    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
764    synchronized void nScriptInvokeV(long id, int slot, byte[] params) {
765        validate();
766        rsnScriptInvokeV(mContext, id, slot, params);
767    }
768
769    native void rsnScriptSetVarI(long con, long id, int slot, int val);
770    synchronized void nScriptSetVarI(long id, int slot, int val) {
771        validate();
772        rsnScriptSetVarI(mContext, id, slot, val);
773    }
774    native int rsnScriptGetVarI(long con, long id, int slot);
775    synchronized int nScriptGetVarI(long id, int slot) {
776        validate();
777        return rsnScriptGetVarI(mContext, id, slot);
778    }
779
780    native void rsnScriptSetVarJ(long con, long id, int slot, long val);
781    synchronized void nScriptSetVarJ(long id, int slot, long val) {
782        validate();
783        rsnScriptSetVarJ(mContext, id, slot, val);
784    }
785    native long rsnScriptGetVarJ(long con, long id, int slot);
786    synchronized long nScriptGetVarJ(long id, int slot) {
787        validate();
788        return rsnScriptGetVarJ(mContext, id, slot);
789    }
790
791    native void rsnScriptSetVarF(long con, long id, int slot, float val);
792    synchronized void nScriptSetVarF(long id, int slot, float val) {
793        validate();
794        rsnScriptSetVarF(mContext, id, slot, val);
795    }
796    native float rsnScriptGetVarF(long con, long id, int slot);
797    synchronized float nScriptGetVarF(long id, int slot) {
798        validate();
799        return rsnScriptGetVarF(mContext, id, slot);
800    }
801    native void rsnScriptSetVarD(long con, long id, int slot, double val);
802    synchronized void nScriptSetVarD(long id, int slot, double val) {
803        validate();
804        rsnScriptSetVarD(mContext, id, slot, val);
805    }
806    native double rsnScriptGetVarD(long con, long id, int slot);
807    synchronized double nScriptGetVarD(long id, int slot) {
808        validate();
809        return rsnScriptGetVarD(mContext, id, slot);
810    }
811    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val);
812    synchronized void nScriptSetVarV(long id, int slot, byte[] val) {
813        validate();
814        rsnScriptSetVarV(mContext, id, slot, val);
815    }
816    native void rsnScriptGetVarV(long con, long id, int slot, byte[] val);
817    synchronized void nScriptGetVarV(long id, int slot, byte[] val) {
818        validate();
819        rsnScriptGetVarV(mContext, id, slot, val);
820    }
821    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
822                                  long e, int[] dims);
823    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
824                                      long e, int[] dims) {
825        validate();
826        rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
827    }
828    native void rsnScriptSetVarObj(long con, long id, int slot, long val);
829    synchronized void nScriptSetVarObj(long id, int slot, long val) {
830        validate();
831        rsnScriptSetVarObj(mContext, id, slot, val);
832    }
833
834    native long rsnScriptCCreate(long con, String resName, String cacheDir,
835                                 byte[] script, int length);
836    synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
837        validate();
838        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
839    }
840
841    native long rsnScriptIntrinsicCreate(long con, int id, long eid);
842    synchronized long nScriptIntrinsicCreate(int id, long eid) {
843        validate();
844        return rsnScriptIntrinsicCreate(mContext, id, eid);
845    }
846
847    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig);
848    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig) {
849        validate();
850        return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
851    }
852
853    native long  rsnScriptInvokeIDCreate(long con, long sid, int slot);
854    synchronized long nScriptInvokeIDCreate(long sid, int slot) {
855        validate();
856        return rsnScriptInvokeIDCreate(mContext, sid, slot);
857    }
858
859    native long  rsnScriptFieldIDCreate(long con, long sid, int slot);
860    synchronized long nScriptFieldIDCreate(long sid, int slot) {
861        validate();
862        return rsnScriptFieldIDCreate(mContext, sid, slot);
863    }
864
865    native long rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
866    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
867        validate();
868        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
869    }
870
871    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
872    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
873        validate();
874        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
875    }
876
877    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
878    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
879        validate();
880        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
881    }
882
883    native void rsnScriptGroupExecute(long con, long group);
884    synchronized void nScriptGroupExecute(long group) {
885        validate();
886        rsnScriptGroupExecute(mContext, group);
887    }
888
889    native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
890                                 int wrapS, int wrapT, int wrapR, float aniso);
891    synchronized long nSamplerCreate(int magFilter, int minFilter,
892                                 int wrapS, int wrapT, int wrapR, float aniso) {
893        validate();
894        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
895    }
896
897    native long rsnProgramStoreCreate(long con, boolean r, boolean g, boolean b, boolean a,
898                                      boolean depthMask, boolean dither,
899                                      int srcMode, int dstMode, int depthFunc);
900    synchronized long nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
901                                         boolean depthMask, boolean dither,
902                                         int srcMode, int dstMode, int depthFunc) {
903        validate();
904        return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode,
905                                     dstMode, depthFunc);
906    }
907
908    native long rsnProgramRasterCreate(long con, boolean pointSprite, int cullMode);
909    synchronized long nProgramRasterCreate(boolean pointSprite, int cullMode) {
910        validate();
911        return rsnProgramRasterCreate(mContext, pointSprite, cullMode);
912    }
913
914    native void rsnProgramBindConstants(long con, long pv, int slot, long mID);
915    synchronized void nProgramBindConstants(long pv, int slot, long mID) {
916        validate();
917        rsnProgramBindConstants(mContext, pv, slot, mID);
918    }
919    native void rsnProgramBindTexture(long con, long vpf, int slot, long a);
920    synchronized void nProgramBindTexture(long vpf, int slot, long a) {
921        validate();
922        rsnProgramBindTexture(mContext, vpf, slot, a);
923    }
924    native void rsnProgramBindSampler(long con, long vpf, int slot, long s);
925    synchronized void nProgramBindSampler(long vpf, int slot, long s) {
926        validate();
927        rsnProgramBindSampler(mContext, vpf, slot, s);
928    }
929    native long rsnProgramFragmentCreate(long con, String shader, String[] texNames, long[] params);
930    synchronized long nProgramFragmentCreate(String shader, String[] texNames, long[] params) {
931        validate();
932        return rsnProgramFragmentCreate(mContext, shader, texNames, params);
933    }
934    native long rsnProgramVertexCreate(long con, String shader, String[] texNames, long[] params);
935    synchronized long nProgramVertexCreate(String shader, String[] texNames, long[] params) {
936        validate();
937        return rsnProgramVertexCreate(mContext, shader, texNames, params);
938    }
939
940    native long rsnMeshCreate(long con, long[] vtx, long[] idx, int[] prim);
941    synchronized long nMeshCreate(long[] vtx, long[] idx, int[] prim) {
942        validate();
943        return rsnMeshCreate(mContext, vtx, idx, prim);
944    }
945    native int  rsnMeshGetVertexBufferCount(long con, long id);
946    synchronized int nMeshGetVertexBufferCount(long id) {
947        validate();
948        return rsnMeshGetVertexBufferCount(mContext, id);
949    }
950    native int  rsnMeshGetIndexCount(long con, long id);
951    synchronized int nMeshGetIndexCount(long id) {
952        validate();
953        return rsnMeshGetIndexCount(mContext, id);
954    }
955    native void rsnMeshGetVertices(long con, long id, long[] vtxIds, int vtxIdCount);
956    synchronized void nMeshGetVertices(long id, long[] vtxIds, int vtxIdCount) {
957        validate();
958        rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
959    }
960    native void rsnMeshGetIndices(long con, long id, long[] idxIds, int[] primitives, int vtxIdCount);
961    synchronized void nMeshGetIndices(long id, long[] idxIds, int[] primitives, int vtxIdCount) {
962        validate();
963        rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
964    }
965
966    native void rsnScriptIntrinsicBLAS_Single(long con, long id, int func, int TransA,
967                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
968                                              float alpha, long A, long B, float beta, long C, int incX, int incY,
969                                              int KL, int KU);
970    synchronized void nScriptIntrinsicBLAS_Single(long id, int func, int TransA,
971                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
972                                                  float alpha, long A, long B, float beta, long C, int incX, int incY,
973                                                  int KL, int KU) {
974        validate();
975        rsnScriptIntrinsicBLAS_Single(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU);
976    }
977
978    native void rsnScriptIntrinsicBLAS_Double(long con, long id, int func, int TransA,
979                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
980                                              double alpha, long A, long B, double beta, long C, int incX, int incY,
981                                              int KL, int KU);
982    synchronized void nScriptIntrinsicBLAS_Double(long id, int func, int TransA,
983                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
984                                                  double alpha, long A, long B, double beta, long C, int incX, int incY,
985                                                  int KL, int KU) {
986        validate();
987        rsnScriptIntrinsicBLAS_Double(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU);
988    }
989
990    native void rsnScriptIntrinsicBLAS_Complex(long con, long id, int func, int TransA,
991                                               int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
992                                               float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
993                                               int KL, int KU);
994    synchronized void nScriptIntrinsicBLAS_Complex(long id, int func, int TransA,
995                                                   int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
996                                                   float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
997                                                   int KL, int KU) {
998        validate();
999        rsnScriptIntrinsicBLAS_Complex(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU);
1000    }
1001
1002    native void rsnScriptIntrinsicBLAS_Z(long con, long id, int func, int TransA,
1003                                         int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
1004                                         double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
1005                                         int KL, int KU);
1006    synchronized void nScriptIntrinsicBLAS_Z(long id, int func, int TransA,
1007                                             int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
1008                                             double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
1009                                             int KL, int KU) {
1010        validate();
1011        rsnScriptIntrinsicBLAS_Z(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU);
1012    }
1013
1014    native void rsnScriptIntrinsicBLAS_BNNM(long con, long id, int M, int N, int K,
1015                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
1016                                             int c_mult_int);
1017    synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K,
1018                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
1019                                             int c_mult_int) {
1020        validate();
1021        rsnScriptIntrinsicBLAS_BNNM(mContext, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int);
1022    }
1023
1024
1025
1026    long     mContext;
1027    private boolean mDestroyed = false;
1028
1029    @SuppressWarnings({"FieldCanBeLocal"})
1030    MessageThread mMessageThread;
1031
1032    volatile Element mElement_U8;
1033    volatile Element mElement_I8;
1034    volatile Element mElement_U16;
1035    volatile Element mElement_I16;
1036    volatile Element mElement_U32;
1037    volatile Element mElement_I32;
1038    volatile Element mElement_U64;
1039    volatile Element mElement_I64;
1040    volatile Element mElement_F16;
1041    volatile Element mElement_F32;
1042    volatile Element mElement_F64;
1043    volatile Element mElement_BOOLEAN;
1044
1045    volatile Element mElement_ELEMENT;
1046    volatile Element mElement_TYPE;
1047    volatile Element mElement_ALLOCATION;
1048    volatile Element mElement_SAMPLER;
1049    volatile Element mElement_SCRIPT;
1050    volatile Element mElement_MESH;
1051    volatile Element mElement_PROGRAM_FRAGMENT;
1052    volatile Element mElement_PROGRAM_VERTEX;
1053    volatile Element mElement_PROGRAM_RASTER;
1054    volatile Element mElement_PROGRAM_STORE;
1055    volatile Element mElement_FONT;
1056
1057    volatile Element mElement_A_8;
1058    volatile Element mElement_RGB_565;
1059    volatile Element mElement_RGB_888;
1060    volatile Element mElement_RGBA_5551;
1061    volatile Element mElement_RGBA_4444;
1062    volatile Element mElement_RGBA_8888;
1063
1064    volatile Element mElement_HALF_2;
1065    volatile Element mElement_HALF_3;
1066    volatile Element mElement_HALF_4;
1067
1068    volatile Element mElement_FLOAT_2;
1069    volatile Element mElement_FLOAT_3;
1070    volatile Element mElement_FLOAT_4;
1071
1072    volatile Element mElement_DOUBLE_2;
1073    volatile Element mElement_DOUBLE_3;
1074    volatile Element mElement_DOUBLE_4;
1075
1076    volatile Element mElement_UCHAR_2;
1077    volatile Element mElement_UCHAR_3;
1078    volatile Element mElement_UCHAR_4;
1079
1080    volatile Element mElement_CHAR_2;
1081    volatile Element mElement_CHAR_3;
1082    volatile Element mElement_CHAR_4;
1083
1084    volatile Element mElement_USHORT_2;
1085    volatile Element mElement_USHORT_3;
1086    volatile Element mElement_USHORT_4;
1087
1088    volatile Element mElement_SHORT_2;
1089    volatile Element mElement_SHORT_3;
1090    volatile Element mElement_SHORT_4;
1091
1092    volatile Element mElement_UINT_2;
1093    volatile Element mElement_UINT_3;
1094    volatile Element mElement_UINT_4;
1095
1096    volatile Element mElement_INT_2;
1097    volatile Element mElement_INT_3;
1098    volatile Element mElement_INT_4;
1099
1100    volatile Element mElement_ULONG_2;
1101    volatile Element mElement_ULONG_3;
1102    volatile Element mElement_ULONG_4;
1103
1104    volatile Element mElement_LONG_2;
1105    volatile Element mElement_LONG_3;
1106    volatile Element mElement_LONG_4;
1107
1108    volatile Element mElement_YUV;
1109
1110    volatile Element mElement_MATRIX_4X4;
1111    volatile Element mElement_MATRIX_3X3;
1112    volatile Element mElement_MATRIX_2X2;
1113
1114    volatile Sampler mSampler_CLAMP_NEAREST;
1115    volatile Sampler mSampler_CLAMP_LINEAR;
1116    volatile Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
1117    volatile Sampler mSampler_WRAP_NEAREST;
1118    volatile Sampler mSampler_WRAP_LINEAR;
1119    volatile Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
1120    volatile Sampler mSampler_MIRRORED_REPEAT_NEAREST;
1121    volatile Sampler mSampler_MIRRORED_REPEAT_LINEAR;
1122    volatile Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
1123
1124    ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
1125    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
1126    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
1127    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
1128
1129    ProgramRaster mProgramRaster_CULL_BACK;
1130    ProgramRaster mProgramRaster_CULL_FRONT;
1131    ProgramRaster mProgramRaster_CULL_NONE;
1132
1133    ///////////////////////////////////////////////////////////////////////////////////
1134    //
1135
1136    /**
1137     * The base class from which an application should derive in order
1138     * to receive RS messages from scripts. When a script calls {@code
1139     * rsSendToClient}, the data fields will be filled, and the run
1140     * method will be called on a separate thread.  This will occur
1141     * some time after {@code rsSendToClient} completes in the script,
1142     * as {@code rsSendToClient} is asynchronous. Message handlers are
1143     * not guaranteed to have completed when {@link
1144     * android.renderscript.RenderScript#finish} returns.
1145     *
1146     */
1147    public static class RSMessageHandler implements Runnable {
1148        protected int[] mData;
1149        protected int mID;
1150        protected int mLength;
1151        public void run() {
1152        }
1153    }
1154    /**
1155     * If an application is expecting messages, it should set this
1156     * field to an instance of {@link RSMessageHandler}.  This
1157     * instance will receive all the user messages sent from {@code
1158     * sendToClient} by scripts from this context.
1159     *
1160     */
1161    RSMessageHandler mMessageCallback = null;
1162
1163    public void setMessageHandler(RSMessageHandler msg) {
1164        mMessageCallback = msg;
1165    }
1166    public RSMessageHandler getMessageHandler() {
1167        return mMessageCallback;
1168    }
1169
1170    /**
1171     * Place a message into the message queue to be sent back to the message
1172     * handler once all previous commands have been executed.
1173     *
1174     * @param id
1175     * @param data
1176     */
1177    public void sendMessage(int id, int[] data) {
1178        nContextSendMessage(id, data);
1179    }
1180
1181    /**
1182     * The runtime error handler base class.  An application should derive from this class
1183     * if it wishes to install an error handler.  When errors occur at runtime,
1184     * the fields in this class will be filled, and the run method will be called.
1185     *
1186     */
1187    public static class RSErrorHandler implements Runnable {
1188        protected String mErrorMessage;
1189        protected int mErrorNum;
1190        public void run() {
1191        }
1192    }
1193
1194    /**
1195     * Application Error handler.  All runtime errors will be dispatched to the
1196     * instance of RSAsyncError set here.  If this field is null a
1197     * {@link RSRuntimeException} will instead be thrown with details about the error.
1198     * This will cause program termaination.
1199     *
1200     */
1201    RSErrorHandler mErrorCallback = null;
1202
1203    public void setErrorHandler(RSErrorHandler msg) {
1204        mErrorCallback = msg;
1205    }
1206    public RSErrorHandler getErrorHandler() {
1207        return mErrorCallback;
1208    }
1209
1210    /**
1211     * RenderScript worker thread priority enumeration.  The default value is
1212     * NORMAL.  Applications wishing to do background processing should set
1213     * their priority to LOW to avoid starving forground processes.
1214     */
1215    public enum Priority {
1216        // These values used to represent official thread priority values
1217        // now they are simply enums to be used by the runtime side
1218        LOW (15),
1219        NORMAL (-8);
1220
1221        int mID;
1222        Priority(int id) {
1223            mID = id;
1224        }
1225    }
1226
1227    void validateObject(BaseObj o) {
1228        if (o != null) {
1229            if (o.mRS != this) {
1230                throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
1231            }
1232        }
1233    }
1234
1235    void validate() {
1236        if (mContext == 0) {
1237            throw new RSInvalidStateException("Calling RS with no Context active.");
1238        }
1239    }
1240
1241
1242    /**
1243     * Change the priority of the worker threads for this context.
1244     *
1245     * @param p New priority to be set.
1246     */
1247    public void setPriority(Priority p) {
1248        validate();
1249        nContextSetPriority(p.mID);
1250    }
1251
1252    static class MessageThread extends Thread {
1253        RenderScript mRS;
1254        boolean mRun = true;
1255        int[] mAuxData = new int[2];
1256
1257        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
1258        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
1259        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
1260        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
1261        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
1262        static final int RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5;
1263
1264        static final int RS_ERROR_FATAL_DEBUG = 0x0800;
1265        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
1266
1267        MessageThread(RenderScript rs) {
1268            super("RSMessageThread");
1269            mRS = rs;
1270
1271        }
1272
1273        public void run() {
1274            // This function is a temporary solution.  The final solution will
1275            // used typed allocations where the message id is the type indicator.
1276            int[] rbuf = new int[16];
1277            mRS.nContextInitToClient(mRS.mContext);
1278            while(mRun) {
1279                rbuf[0] = 0;
1280                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
1281                int size = mAuxData[1];
1282                int subID = mAuxData[0];
1283
1284                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
1285                    if ((size>>2) >= rbuf.length) {
1286                        rbuf = new int[(size + 3) >> 2];
1287                    }
1288                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1289                        RS_MESSAGE_TO_CLIENT_USER) {
1290                        throw new RSDriverException("Error processing message from RenderScript.");
1291                    }
1292
1293                    if(mRS.mMessageCallback != null) {
1294                        mRS.mMessageCallback.mData = rbuf;
1295                        mRS.mMessageCallback.mID = subID;
1296                        mRS.mMessageCallback.mLength = size;
1297                        mRS.mMessageCallback.run();
1298                    } else {
1299                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
1300                    }
1301                    continue;
1302                }
1303
1304                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
1305                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
1306
1307                    // Throw RSRuntimeException under the following conditions:
1308                    //
1309                    // 1) It is an unknown fatal error.
1310                    // 2) It is a debug fatal error, and we are not in a
1311                    //    debug context.
1312                    // 3) It is a debug fatal error, and we do not have an
1313                    //    error callback.
1314                    if (subID >= RS_ERROR_FATAL_UNKNOWN ||
1315                        (subID >= RS_ERROR_FATAL_DEBUG &&
1316                         (mRS.mContextType != ContextType.DEBUG ||
1317                          mRS.mErrorCallback == null))) {
1318                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
1319                    }
1320
1321                    if(mRS.mErrorCallback != null) {
1322                        mRS.mErrorCallback.mErrorMessage = e;
1323                        mRS.mErrorCallback.mErrorNum = subID;
1324                        mRS.mErrorCallback.run();
1325                    } else {
1326                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
1327                        // Do not throw here. In these cases, we do not have
1328                        // a fatal error.
1329                    }
1330                    continue;
1331                }
1332
1333                if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
1334                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
1335                        RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
1336                        throw new RSDriverException("Error processing message from RenderScript.");
1337                    }
1338                    long bufferID = ((long)rbuf[1] << 32L) + ((long)rbuf[0] & 0xffffffffL);
1339                    Allocation.sendBufferNotification(bufferID);
1340                    continue;
1341                }
1342
1343                // 2: teardown.
1344                // But we want to avoid starving other threads during
1345                // teardown by yielding until the next line in the destructor
1346                // can execute to set mRun = false
1347                try {
1348                    sleep(1, 0);
1349                } catch(InterruptedException e) {
1350                }
1351            }
1352            //Log.d(LOG_TAG, "MessageThread exiting.");
1353        }
1354    }
1355
1356    RenderScript(Context ctx) {
1357        mContextType = ContextType.NORMAL;
1358        if (ctx != null) {
1359            mApplicationContext = ctx.getApplicationContext();
1360        }
1361        mRWLock = new ReentrantReadWriteLock();
1362        try {
1363            registerNativeAllocation.invoke(sRuntime, 4 * 1024 * 1024); // 4MB for GC sake
1364        } catch (Exception e) {
1365            Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
1366            throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
1367        }
1368
1369    }
1370
1371    /**
1372     * Gets the application context associated with the RenderScript context.
1373     *
1374     * @return The application context.
1375     */
1376    public final Context getApplicationContext() {
1377        return mApplicationContext;
1378    }
1379
1380    /**
1381     * Name of the file that holds the object cache.
1382     */
1383    private static String mCachePath;
1384
1385    /**
1386     * Gets the path to the code cache.
1387     */
1388    static synchronized String getCachePath() {
1389        if (mCachePath == null) {
1390            final String CACHE_PATH = "com.android.renderscript.cache";
1391            if (RenderScriptCacheDir.mCacheDir == null) {
1392                throw new RSRuntimeException("RenderScript code cache directory uninitialized.");
1393            }
1394            File f = new File(RenderScriptCacheDir.mCacheDir, CACHE_PATH);
1395            mCachePath = f.getAbsolutePath();
1396            f.mkdirs();
1397        }
1398        return mCachePath;
1399    }
1400
1401    /**
1402     * Create a RenderScript context.
1403     *
1404     * @param ctx The context.
1405     * @return RenderScript
1406     */
1407    private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) {
1408        if (!sInitialized) {
1409            Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
1410            return null;
1411        }
1412
1413        if ((flags & ~(CREATE_FLAG_LOW_LATENCY | CREATE_FLAG_LOW_POWER |
1414                       CREATE_FLAG_WAIT_FOR_ATTACH)) != 0) {
1415            throw new RSIllegalArgumentException("Invalid flags passed.");
1416        }
1417
1418        RenderScript rs = new RenderScript(ctx);
1419
1420        long device = rs.nDeviceCreate();
1421        rs.mContext = rs.nContextCreate(device, flags, sdkVersion, ct.mID);
1422        rs.mContextType = ct;
1423        rs.mContextFlags = flags;
1424        rs.mContextSdkVersion = sdkVersion;
1425        if (rs.mContext == 0) {
1426            throw new RSDriverException("Failed to create RS context.");
1427        }
1428
1429        // set up cache directory for entire context
1430        rs.nContextSetCacheDir(RenderScript.getCachePath());
1431
1432        rs.mMessageThread = new MessageThread(rs);
1433        rs.mMessageThread.start();
1434        return rs;
1435    }
1436
1437    /**
1438     * calls create(ctx, ContextType.NORMAL, CREATE_FLAG_NONE)
1439     *
1440     * See documentation for @create for details
1441     *
1442     * @param ctx The context.
1443     * @return RenderScript
1444     */
1445    public static RenderScript create(Context ctx) {
1446        return create(ctx, ContextType.NORMAL);
1447    }
1448
1449    /**
1450     * calls create(ctx, ct, CREATE_FLAG_NONE)
1451     *
1452     * See documentation for @create for details
1453     *
1454     * @param ctx The context.
1455     * @param ct The type of context to be created.
1456     * @return RenderScript
1457     */
1458    public static RenderScript create(Context ctx, ContextType ct) {
1459        return create(ctx, ct, CREATE_FLAG_NONE);
1460    }
1461
1462
1463    /**
1464     * Gets or creates a RenderScript context of the specified type.
1465     *
1466     * The returned context will be cached for future reuse within
1467     * the process. When an application is finished using
1468     * RenderScript it should call releaseAllContexts()
1469     *
1470     * A process context is a context designed for easy creation and
1471     * lifecycle management.  Multiple calls to this function will
1472     * return the same object provided they are called with the same
1473     * options.  This allows it to be used any time a RenderScript
1474     * context is needed.
1475     *
1476     * Prior to API 23 this always created a new context.
1477     *
1478     * @param ctx The context.
1479     * @param ct The type of context to be created.
1480     * @param flags The OR of the CREATE_FLAG_* options desired
1481     * @return RenderScript
1482     */
1483    public static RenderScript create(Context ctx, ContextType ct, int flags) {
1484        int v = ctx.getApplicationInfo().targetSdkVersion;
1485        return create(ctx, v, ct, flags);
1486    }
1487
1488    /**
1489     * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE)
1490     *
1491     * Used by the RenderScriptThunker to maintain backward compatibility.
1492     *
1493     * @hide
1494     * @param ctx The context.
1495     * @param sdkVersion The target SDK Version.
1496     * @return RenderScript
1497     */
1498    public static RenderScript create(Context ctx, int sdkVersion) {
1499        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
1500    }
1501
1502     /**
1503     * Gets or creates a RenderScript context of the specified type.
1504     *
1505     * @param ctx The context.
1506     * @param ct The type of context to be created.
1507     * @param sdkVersion The target SDK Version.
1508     * @param flags The OR of the CREATE_FLAG_* options desired
1509     * @return RenderScript
1510     */
1511    private static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
1512        if (sdkVersion < 23) {
1513            return internalCreate(ctx, sdkVersion, ct, flags);
1514        }
1515
1516        synchronized (mProcessContextList) {
1517            for (RenderScript prs : mProcessContextList) {
1518                if ((prs.mContextType == ct) &&
1519                    (prs.mContextFlags == flags) &&
1520                    (prs.mContextSdkVersion == sdkVersion)) {
1521
1522                    return prs;
1523                }
1524            }
1525
1526            RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags);
1527            prs.mIsProcessContext = true;
1528            mProcessContextList.add(prs);
1529            return prs;
1530        }
1531    }
1532
1533    /**
1534     * Releases all the process contexts.  This is the same as
1535     * calling .destroy() on each unique context retreived with
1536     * create(...). If no contexts have been created this
1537     * function does nothing.
1538     *
1539     * Typically you call this when your application is losing focus
1540     * and will not be using a context for some time.
1541     *
1542     * This has no effect on a context created with
1543     * createMultiContext()
1544     */
1545    public static void releaseAllContexts() {
1546        ArrayList<RenderScript> oldList;
1547        synchronized (mProcessContextList) {
1548            oldList = mProcessContextList;
1549            mProcessContextList = new ArrayList<RenderScript>();
1550        }
1551
1552        for (RenderScript prs : oldList) {
1553            prs.mIsProcessContext = false;
1554            prs.destroy();
1555        }
1556        oldList.clear();
1557    }
1558
1559
1560
1561    /**
1562     * Create a RenderScript context.
1563     *
1564     * This is an advanced function intended for applications which
1565     * need to create more than one RenderScript context to be used
1566     * at the same time.
1567     *
1568     * If you need a single context please use create()
1569     *
1570     * @param ctx The context.
1571     * @return RenderScript
1572     */
1573    public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) {
1574        return internalCreate(ctx, API_number, ct, flags);
1575    }
1576
1577
1578    /**
1579     * Print the currently available debugging information about the state of
1580     * the RS context to the log.
1581     *
1582     */
1583    public void contextDump() {
1584        validate();
1585        nContextDump(0);
1586    }
1587
1588    /**
1589     * Wait for any pending asynchronous opeations (such as copies to a RS
1590     * allocation or RS script executions) to complete.
1591     *
1592     */
1593    public void finish() {
1594        nContextFinish();
1595    }
1596
1597    private void helpDestroy() {
1598        boolean shouldDestroy = false;
1599        synchronized(this) {
1600            if (!mDestroyed) {
1601                shouldDestroy = true;
1602                mDestroyed = true;
1603            }
1604        }
1605
1606        if (shouldDestroy) {
1607            nContextFinish();
1608
1609            nContextDeinitToClient(mContext);
1610            mMessageThread.mRun = false;
1611            // Interrupt mMessageThread so it gets to see immediately that mRun is false
1612            // and exit rightaway.
1613            mMessageThread.interrupt();
1614
1615            // Wait for mMessageThread to join.  Try in a loop, in case this thread gets interrupted
1616            // during the wait.  If interrupted, set the "interrupted" status of the current thread.
1617            boolean hasJoined = false, interrupted = false;
1618            while (!hasJoined) {
1619                try {
1620                    mMessageThread.join();
1621                    hasJoined = true;
1622                } catch (InterruptedException e) {
1623                    interrupted = true;
1624                }
1625            }
1626            if (interrupted) {
1627                Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join");
1628                Thread.currentThread().interrupt();
1629            }
1630
1631            nContextDestroy();
1632        }
1633    }
1634
1635    protected void finalize() throws Throwable {
1636        helpDestroy();
1637        super.finalize();
1638    }
1639
1640
1641    /**
1642     * Destroys this RenderScript context.  Once this function is called,
1643     * using this context or any objects belonging to this context is
1644     * illegal.
1645     *
1646     * API 23+, this function is a NOP if the context was created
1647     * with create().  Please use releaseAllContexts() to clean up
1648     * contexts created with the create function.
1649     *
1650     */
1651    public void destroy() {
1652        if (mIsProcessContext) {
1653            // users cannot destroy a process context
1654            return;
1655        }
1656        validate();
1657        helpDestroy();
1658    }
1659
1660    boolean isAlive() {
1661        return mContext != 0;
1662    }
1663
1664    long safeID(BaseObj o) {
1665        if(o != null) {
1666            return o.getID(this);
1667        }
1668        return 0;
1669    }
1670}
1671