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