[go: nahoru, domu]

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