Home | History | Annotate | Download | only in renderscript
      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 
     17 package android.renderscript;
     18 
     19 import java.io.File;
     20 import java.lang.reflect.Field;
     21 import java.lang.reflect.Method;
     22 import java.util.concurrent.locks.ReentrantReadWriteLock;
     23 
     24 import android.content.Context;
     25 import android.content.pm.ApplicationInfo;
     26 import android.content.pm.PackageManager;
     27 import android.content.res.AssetManager;
     28 import android.graphics.Bitmap;
     29 import android.graphics.BitmapFactory;
     30 import android.graphics.SurfaceTexture;
     31 import android.os.Process;
     32 import android.util.Log;
     33 import android.view.Surface;
     34 import android.os.SystemProperties;
     35 import android.os.Trace;
     36 
     37 /**
     38  * This class provides access to a RenderScript context, which controls RenderScript
     39  * initialization, resource management, and teardown. An instance of the RenderScript
     40  * class must be created before any other RS objects can be created.
     41  *
     42  * <div class="special reference">
     43  * <h3>Developer Guides</h3>
     44  * <p>For more information about creating an application that uses RenderScript, read the
     45  * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
     46  * </div>
     47  **/
     48 public class RenderScript {
     49     static final long TRACE_TAG = Trace.TRACE_TAG_RS;
     50 
     51     static final String LOG_TAG = "RenderScript_jni";
     52     static final boolean DEBUG  = false;
     53     @SuppressWarnings({"UnusedDeclaration", "deprecation"})
     54     static final boolean LOG_ENABLED = false;
     55 
     56     private Context mApplicationContext;
     57 
     58     /*
     59      * We use a class initializer to allow the native code to cache some
     60      * field offsets.
     61      */
     62     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // TODO: now used locally; remove?
     63     static boolean sInitialized;
     64     native static void _nInit();
     65 
     66     static Object sRuntime;
     67     static Method registerNativeAllocation;
     68     static Method registerNativeFree;
     69 
     70     static {
     71         sInitialized = false;
     72         if (!SystemProperties.getBoolean("config.disable_renderscript", false)) {
     73             try {
     74                 Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
     75                 Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
     76                 sRuntime = get_runtime.invoke(null);
     77                 registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
     78                 registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
     79             } catch (Exception e) {
     80                 Log.e(LOG_TAG, "Error loading GC methods: " + e);
     81                 throw new RSRuntimeException("Error loading GC methods: " + e);
     82             }
     83             try {
     84                 System.loadLibrary("rs_jni");
     85                 _nInit();
     86                 sInitialized = true;
     87             } catch (UnsatisfiedLinkError e) {
     88                 Log.e(LOG_TAG, "Error loading RS jni library: " + e);
     89                 throw new RSRuntimeException("Error loading RS jni library: " + e);
     90             }
     91         }
     92     }
     93 
     94     // Non-threadsafe functions.
     95     native int  nDeviceCreate();
     96     native void nDeviceDestroy(int dev);
     97     native void nDeviceSetConfig(int dev, int param, int value);
     98     native int nContextGetUserMessage(int con, int[] data);
     99     native String nContextGetErrorMessage(int con);
    100     native int  nContextPeekMessage(int con, int[] subID);
    101     native void nContextInitToClient(int con);
    102     native void nContextDeinitToClient(int con);
    103 
    104     static File mCacheDir;
    105 
    106     // this should be a monotonically increasing ID
    107     // used in conjunction with the API version of a device
    108     static final long sMinorID = 1;
    109 
    110     /**
    111      * Returns an identifier that can be used to identify a particular
    112      * minor version of RS.
    113      *
    114      * @hide
    115      */
    116     public static long getMinorID() {
    117         return sMinorID;
    118     }
    119 
    120      /**
    121      * Sets the directory to use as a persistent storage for the
    122      * renderscript object file cache.
    123      *
    124      * @hide
    125      * @param cacheDir A directory the current process can write to
    126      */
    127     public static void setupDiskCache(File cacheDir) {
    128         if (!sInitialized) {
    129             Log.e(LOG_TAG, "RenderScript.setupDiskCache() called when disabled");
    130             return;
    131         }
    132 
    133         // Defer creation of cache path to nScriptCCreate().
    134         mCacheDir = cacheDir;
    135     }
    136 
    137     /**
    138      * ContextType specifies the specific type of context to be created.
    139      *
    140      */
    141     public enum ContextType {
    142         /**
    143          * NORMAL context, this is the default and what shipping apps should
    144          * use.
    145          */
    146         NORMAL (0),
    147 
    148         /**
    149          * DEBUG context, perform extra runtime checks to validate the
    150          * kernels and APIs are being used as intended.  Get and SetElementAt
    151          * will be bounds checked in this mode.
    152          */
    153         DEBUG (1),
    154 
    155         /**
    156          * PROFILE context, Intended to be used once the first time an
    157          * application is run on a new device.  This mode allows the runtime to
    158          * do additional testing and performance tuning.
    159          */
    160         PROFILE (2);
    161 
    162         int mID;
    163         ContextType(int id) {
    164             mID = id;
    165         }
    166     }
    167 
    168     ContextType mContextType;
    169     ReentrantReadWriteLock mRWLock;
    170 
    171     // Methods below are wrapped to protect the non-threadsafe
    172     // lockless fifo.
    173     native int  rsnContextCreateGL(int dev, int ver, int sdkVer,
    174                  int colorMin, int colorPref,
    175                  int alphaMin, int alphaPref,
    176                  int depthMin, int depthPref,
    177                  int stencilMin, int stencilPref,
    178                  int samplesMin, int samplesPref, float samplesQ, int dpi);
    179     synchronized int nContextCreateGL(int dev, int ver, int sdkVer,
    180                  int colorMin, int colorPref,
    181                  int alphaMin, int alphaPref,
    182                  int depthMin, int depthPref,
    183                  int stencilMin, int stencilPref,
    184                  int samplesMin, int samplesPref, float samplesQ, int dpi) {
    185         return rsnContextCreateGL(dev, ver, sdkVer, colorMin, colorPref,
    186                                   alphaMin, alphaPref, depthMin, depthPref,
    187                                   stencilMin, stencilPref,
    188                                   samplesMin, samplesPref, samplesQ, dpi);
    189     }
    190     native int  rsnContextCreate(int dev, int ver, int sdkVer, int contextType);
    191     synchronized int nContextCreate(int dev, int ver, int sdkVer, int contextType) {
    192         return rsnContextCreate(dev, ver, sdkVer, contextType);
    193     }
    194     native void rsnContextDestroy(int con);
    195     synchronized void nContextDestroy() {
    196         validate();
    197 
    198         // take teardown lock
    199         // teardown lock can only be taken when no objects are being destroyed
    200         ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
    201         wlock.lock();
    202 
    203         int curCon = mContext;
    204         // context is considered dead as of this point
    205         mContext = 0;
    206 
    207         wlock.unlock();
    208         rsnContextDestroy(curCon);
    209     }
    210     native void rsnContextSetSurface(int con, int w, int h, Surface sur);
    211     synchronized void nContextSetSurface(int w, int h, Surface sur) {
    212         validate();
    213         rsnContextSetSurface(mContext, w, h, sur);
    214     }
    215     native void rsnContextSetSurfaceTexture(int con, int w, int h, SurfaceTexture sur);
    216     synchronized void nContextSetSurfaceTexture(int w, int h, SurfaceTexture sur) {
    217         validate();
    218         rsnContextSetSurfaceTexture(mContext, w, h, sur);
    219     }
    220     native void rsnContextSetPriority(int con, int p);
    221     synchronized void nContextSetPriority(int p) {
    222         validate();
    223         rsnContextSetPriority(mContext, p);
    224     }
    225     native void rsnContextDump(int con, int bits);
    226     synchronized void nContextDump(int bits) {
    227         validate();
    228         rsnContextDump(mContext, bits);
    229     }
    230     native void rsnContextFinish(int con);
    231     synchronized void nContextFinish() {
    232         validate();
    233         rsnContextFinish(mContext);
    234     }
    235 
    236     native void rsnContextSendMessage(int con, int id, int[] data);
    237     synchronized void nContextSendMessage(int id, int[] data) {
    238         validate();
    239         rsnContextSendMessage(mContext, id, data);
    240     }
    241 
    242     native void rsnContextBindRootScript(int con, int script);
    243     synchronized void nContextBindRootScript(int script) {
    244         validate();
    245         rsnContextBindRootScript(mContext, script);
    246     }
    247     native void rsnContextBindSampler(int con, int sampler, int slot);
    248     synchronized void nContextBindSampler(int sampler, int slot) {
    249         validate();
    250         rsnContextBindSampler(mContext, sampler, slot);
    251     }
    252     native void rsnContextBindProgramStore(int con, int pfs);
    253     synchronized void nContextBindProgramStore(int pfs) {
    254         validate();
    255         rsnContextBindProgramStore(mContext, pfs);
    256     }
    257     native void rsnContextBindProgramFragment(int con, int pf);
    258     synchronized void nContextBindProgramFragment(int pf) {
    259         validate();
    260         rsnContextBindProgramFragment(mContext, pf);
    261     }
    262     native void rsnContextBindProgramVertex(int con, int pv);
    263     synchronized void nContextBindProgramVertex(int pv) {
    264         validate();
    265         rsnContextBindProgramVertex(mContext, pv);
    266     }
    267     native void rsnContextBindProgramRaster(int con, int pr);
    268     synchronized void nContextBindProgramRaster(int pr) {
    269         validate();
    270         rsnContextBindProgramRaster(mContext, pr);
    271     }
    272     native void rsnContextPause(int con);
    273     synchronized void nContextPause() {
    274         validate();
    275         rsnContextPause(mContext);
    276     }
    277     native void rsnContextResume(int con);
    278     synchronized void nContextResume() {
    279         validate();
    280         rsnContextResume(mContext);
    281     }
    282 
    283     native void rsnAssignName(int con, int obj, byte[] name);
    284     synchronized void nAssignName(int obj, byte[] name) {
    285         validate();
    286         rsnAssignName(mContext, obj, name);
    287     }
    288     native String rsnGetName(int con, int obj);
    289     synchronized String nGetName(int obj) {
    290         validate();
    291         return rsnGetName(mContext, obj);
    292     }
    293     // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
    294     native void rsnObjDestroy(int con, int id);
    295     void nObjDestroy(int id) {
    296         // There is a race condition here.  The calling code may be run
    297         // by the gc while teardown is occuring.  This protects againts
    298         // deleting dead objects.
    299         if (mContext != 0) {
    300             rsnObjDestroy(mContext, id);
    301         }
    302     }
    303 
    304     native int  rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
    305     synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
    306         validate();
    307         return rsnElementCreate(mContext, type, kind, norm, vecSize);
    308     }
    309     native int  rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
    310     synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
    311         validate();
    312         return rsnElementCreate2(mContext, elements, names, arraySizes);
    313     }
    314     native void rsnElementGetNativeData(int con, int id, int[] elementData);
    315     synchronized void nElementGetNativeData(int id, int[] elementData) {
    316         validate();
    317         rsnElementGetNativeData(mContext, id, elementData);
    318     }
    319     native void rsnElementGetSubElements(int con, int id,
    320                                          int[] IDs, String[] names, int[] arraySizes);
    321     synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) {
    322         validate();
    323         rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
    324     }
    325 
    326     native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
    327     synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
    328         validate();
    329         return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
    330     }
    331     native void rsnTypeGetNativeData(int con, int id, int[] typeData);
    332     synchronized void nTypeGetNativeData(int id, int[] typeData) {
    333         validate();
    334         rsnTypeGetNativeData(mContext, id, typeData);
    335     }
    336 
    337     native int  rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer);
    338     synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) {
    339         validate();
    340         return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
    341     }
    342     native int  rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
    343     synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
    344         validate();
    345         return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
    346     }
    347 
    348     native int  rsnAllocationCreateBitmapBackedAllocation(int con, int type, int mip, Bitmap bmp, int usage);
    349     synchronized int nAllocationCreateBitmapBackedAllocation(int type, int mip, Bitmap bmp, int usage) {
    350         validate();
    351         return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
    352     }
    353 
    354 
    355     native int  rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
    356     synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
    357         validate();
    358         return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
    359     }
    360     native int  rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
    361     synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
    362         validate();
    363         return rsnAllocationCreateBitmapRef(mContext, type, bmp);
    364     }
    365     native int  rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage);
    366     synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
    367         validate();
    368         return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
    369     }
    370 
    371     native void  rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
    372     synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
    373         validate();
    374         rsnAllocationCopyToBitmap(mContext, alloc, bmp);
    375     }
    376 
    377 
    378     native void rsnAllocationSyncAll(int con, int alloc, int src);
    379     synchronized void nAllocationSyncAll(int alloc, int src) {
    380         validate();
    381         rsnAllocationSyncAll(mContext, alloc, src);
    382     }
    383     native Surface rsnAllocationGetSurface(int con, int alloc);
    384     synchronized Surface nAllocationGetSurface(int alloc) {
    385         validate();
    386         return rsnAllocationGetSurface(mContext, alloc);
    387     }
    388     native void rsnAllocationSetSurface(int con, int alloc, Surface sur);
    389     synchronized void nAllocationSetSurface(int alloc, Surface sur) {
    390         validate();
    391         rsnAllocationSetSurface(mContext, alloc, sur);
    392     }
    393     native void rsnAllocationIoSend(int con, int alloc);
    394     synchronized void nAllocationIoSend(int alloc) {
    395         validate();
    396         rsnAllocationIoSend(mContext, alloc);
    397     }
    398     native void rsnAllocationIoReceive(int con, int alloc);
    399     synchronized void nAllocationIoReceive(int alloc) {
    400         validate();
    401         rsnAllocationIoReceive(mContext, alloc);
    402     }
    403 
    404 
    405     native void rsnAllocationGenerateMipmaps(int con, int alloc);
    406     synchronized void nAllocationGenerateMipmaps(int alloc) {
    407         validate();
    408         rsnAllocationGenerateMipmaps(mContext, alloc);
    409     }
    410     native void  rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
    411     synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
    412         validate();
    413         rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
    414     }
    415 
    416 
    417     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes);
    418     synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) {
    419         validate();
    420         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
    421     }
    422     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes);
    423     synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) {
    424         validate();
    425         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
    426     }
    427     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes);
    428     synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) {
    429         validate();
    430         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
    431     }
    432     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes);
    433     synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) {
    434         validate();
    435         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
    436     }
    437 
    438     native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
    439     synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
    440         validate();
    441         rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
    442     }
    443 
    444     native void rsnAllocationData2D(int con,
    445                                     int dstAlloc, int dstXoff, int dstYoff,
    446                                     int dstMip, int dstFace,
    447                                     int width, int height,
    448                                     int srcAlloc, int srcXoff, int srcYoff,
    449                                     int srcMip, int srcFace);
    450     synchronized void nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff,
    451                                         int dstMip, int dstFace,
    452                                         int width, int height,
    453                                         int srcAlloc, int srcXoff, int srcYoff,
    454                                         int srcMip, int srcFace) {
    455         validate();
    456         rsnAllocationData2D(mContext,
    457                             dstAlloc, dstXoff, dstYoff,
    458                             dstMip, dstFace,
    459                             width, height,
    460                             srcAlloc, srcXoff, srcYoff,
    461                             srcMip, srcFace);
    462     }
    463 
    464     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes);
    465     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) {
    466         validate();
    467         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
    468     }
    469     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes);
    470     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) {
    471         validate();
    472         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
    473     }
    474     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes);
    475     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) {
    476         validate();
    477         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
    478     }
    479     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes);
    480     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) {
    481         validate();
    482         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
    483     }
    484     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b);
    485     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) {
    486         validate();
    487         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
    488     }
    489 
    490     native void rsnAllocationData3D(int con,
    491                                     int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
    492                                     int dstMip,
    493                                     int width, int height, int depth,
    494                                     int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
    495                                     int srcMip);
    496     synchronized void nAllocationData3D(int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
    497                                         int dstMip,
    498                                         int width, int height, int depth,
    499                                         int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
    500                                         int srcMip) {
    501         validate();
    502         rsnAllocationData3D(mContext,
    503                             dstAlloc, dstXoff, dstYoff, dstZoff,
    504                             dstMip, width, height, depth,
    505                             srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
    506     }
    507 
    508     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes);
    509     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes) {
    510         validate();
    511         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
    512     }
    513     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes);
    514     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes) {
    515         validate();
    516         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
    517     }
    518     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes);
    519     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes) {
    520         validate();
    521         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
    522     }
    523     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes);
    524     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes) {
    525         validate();
    526         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
    527     }
    528 
    529 
    530     native void rsnAllocationRead(int con, int id, byte[] d);
    531     synchronized void nAllocationRead(int id, byte[] d) {
    532         validate();
    533         rsnAllocationRead(mContext, id, d);
    534     }
    535     native void rsnAllocationRead(int con, int id, short[] d);
    536     synchronized void nAllocationRead(int id, short[] d) {
    537         validate();
    538         rsnAllocationRead(mContext, id, d);
    539     }
    540     native void rsnAllocationRead(int con, int id, int[] d);
    541     synchronized void nAllocationRead(int id, int[] d) {
    542         validate();
    543         rsnAllocationRead(mContext, id, d);
    544     }
    545     native void rsnAllocationRead(int con, int id, float[] d);
    546     synchronized void nAllocationRead(int id, float[] d) {
    547         validate();
    548         rsnAllocationRead(mContext, id, d);
    549     }
    550     native int  rsnAllocationGetType(int con, int id);
    551     synchronized int nAllocationGetType(int id) {
    552         validate();
    553         return rsnAllocationGetType(mContext, id);
    554     }
    555 
    556     native void rsnAllocationResize1D(int con, int id, int dimX);
    557     synchronized void nAllocationResize1D(int id, int dimX) {
    558         validate();
    559         rsnAllocationResize1D(mContext, id, dimX);
    560     }
    561 
    562     native int  rsnFileA3DCreateFromAssetStream(int con, int assetStream);
    563     synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
    564         validate();
    565         return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
    566     }
    567     native int  rsnFileA3DCreateFromFile(int con, String path);
    568     synchronized int nFileA3DCreateFromFile(String path) {
    569         validate();
    570         return rsnFileA3DCreateFromFile(mContext, path);
    571     }
    572     native int  rsnFileA3DCreateFromAsset(int con, AssetManager mgr, String path);
    573     synchronized int nFileA3DCreateFromAsset(AssetManager mgr, String path) {
    574         validate();
    575         return rsnFileA3DCreateFromAsset(mContext, mgr, path);
    576     }
    577     native int  rsnFileA3DGetNumIndexEntries(int con, int fileA3D);
    578     synchronized int nFileA3DGetNumIndexEntries(int fileA3D) {
    579         validate();
    580         return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
    581     }
    582     native void rsnFileA3DGetIndexEntries(int con, int fileA3D, int numEntries, int[] IDs, String[] names);
    583     synchronized void nFileA3DGetIndexEntries(int fileA3D, int numEntries, int[] IDs, String[] names) {
    584         validate();
    585         rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
    586     }
    587     native int  rsnFileA3DGetEntryByIndex(int con, int fileA3D, int index);
    588     synchronized int nFileA3DGetEntryByIndex(int fileA3D, int index) {
    589         validate();
    590         return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
    591     }
    592 
    593     native int  rsnFontCreateFromFile(int con, String fileName, float size, int dpi);
    594     synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
    595         validate();
    596         return rsnFontCreateFromFile(mContext, fileName, size, dpi);
    597     }
    598     native int  rsnFontCreateFromAssetStream(int con, String name, float size, int dpi, int assetStream);
    599     synchronized int nFontCreateFromAssetStream(String name, float size, int dpi, int assetStream) {
    600         validate();
    601         return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
    602     }
    603     native int  rsnFontCreateFromAsset(int con, AssetManager mgr, String path, float size, int dpi);
    604     synchronized int nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
    605         validate();
    606         return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
    607     }
    608 
    609 
    610     native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
    611     synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
    612         validate();
    613         rsnScriptBindAllocation(mContext, script, alloc, slot);
    614     }
    615     native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
    616     synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
    617         validate();
    618         rsnScriptSetTimeZone(mContext, script, timeZone);
    619     }
    620     native void rsnScriptInvoke(int con, int id, int slot);
    621     synchronized void nScriptInvoke(int id, int slot) {
    622         validate();
    623         rsnScriptInvoke(mContext, id, slot);
    624     }
    625     native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params);
    626     native void rsnScriptForEach(int con, int id, int slot, int ain, int aout);
    627     native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, byte[] params,
    628                                         int xstart, int xend, int ystart, int yend, int zstart, int zend);
    629     native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout,
    630                                         int xstart, int xend, int ystart, int yend, int zstart, int zend);
    631     synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) {
    632         validate();
    633         if (params == null) {
    634             rsnScriptForEach(mContext, id, slot, ain, aout);
    635         } else {
    636             rsnScriptForEach(mContext, id, slot, ain, aout, params);
    637         }
    638     }
    639 
    640     synchronized void nScriptForEachClipped(int id, int slot, int ain, int aout, byte[] params,
    641                                             int xstart, int xend, int ystart, int yend, int zstart, int zend) {
    642         validate();
    643         if (params == null) {
    644             rsnScriptForEachClipped(mContext, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend);
    645         } else {
    646             rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend);
    647         }
    648     }
    649 
    650     native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
    651     synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
    652         validate();
    653         rsnScriptInvokeV(mContext, id, slot, params);
    654     }
    655 
    656     native void rsnScriptSetVarI(int con, int id, int slot, int val);
    657     synchronized void nScriptSetVarI(int id, int slot, int val) {
    658         validate();
    659         rsnScriptSetVarI(mContext, id, slot, val);
    660     }
    661     native int rsnScriptGetVarI(int con, int id, int slot);
    662     synchronized int nScriptGetVarI(int id, int slot) {
    663         validate();
    664         return rsnScriptGetVarI(mContext, id, slot);
    665     }
    666 
    667     native void rsnScriptSetVarJ(int con, int id, int slot, long val);
    668     synchronized void nScriptSetVarJ(int id, int slot, long val) {
    669         validate();
    670         rsnScriptSetVarJ(mContext, id, slot, val);
    671     }
    672     native long rsnScriptGetVarJ(int con, int id, int slot);
    673     synchronized long nScriptGetVarJ(int id, int slot) {
    674         validate();
    675         return rsnScriptGetVarJ(mContext, id, slot);
    676     }
    677 
    678     native void rsnScriptSetVarF(int con, int id, int slot, float val);
    679     synchronized void nScriptSetVarF(int id, int slot, float val) {
    680         validate();
    681         rsnScriptSetVarF(mContext, id, slot, val);
    682     }
    683     native float rsnScriptGetVarF(int con, int id, int slot);
    684     synchronized float nScriptGetVarF(int id, int slot) {
    685         validate();
    686         return rsnScriptGetVarF(mContext, id, slot);
    687     }
    688     native void rsnScriptSetVarD(int con, int id, int slot, double val);
    689     synchronized void nScriptSetVarD(int id, int slot, double val) {
    690         validate();
    691         rsnScriptSetVarD(mContext, id, slot, val);
    692     }
    693     native double rsnScriptGetVarD(int con, int id, int slot);
    694     synchronized double nScriptGetVarD(int id, int slot) {
    695         validate();
    696         return rsnScriptGetVarD(mContext, id, slot);
    697     }
    698     native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
    699     synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
    700         validate();
    701         rsnScriptSetVarV(mContext, id, slot, val);
    702     }
    703     native void rsnScriptGetVarV(int con, int id, int slot, byte[] val);
    704     synchronized void nScriptGetVarV(int id, int slot, byte[] val) {
    705         validate();
    706         rsnScriptGetVarV(mContext, id, slot, val);
    707     }
    708     native void rsnScriptSetVarVE(int con, int id, int slot, byte[] val,
    709                                   int e, int[] dims);
    710     synchronized void nScriptSetVarVE(int id, int slot, byte[] val,
    711                                       int e, int[] dims) {
    712         validate();
    713         rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
    714     }
    715     native void rsnScriptSetVarObj(int con, int id, int slot, int val);
    716     synchronized void nScriptSetVarObj(int id, int slot, int val) {
    717         validate();
    718         rsnScriptSetVarObj(mContext, id, slot, val);
    719     }
    720 
    721     native int  rsnScriptCCreate(int con, String resName, String cacheDir,
    722                                  byte[] script, int length);
    723     synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
    724         validate();
    725         return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
    726     }
    727 
    728     native int  rsnScriptIntrinsicCreate(int con, int id, int eid);
    729     synchronized int nScriptIntrinsicCreate(int id, int eid) {
    730         validate();
    731         return rsnScriptIntrinsicCreate(mContext, id, eid);
    732     }
    733 
    734     native int  rsnScriptKernelIDCreate(int con, int sid, int slot, int sig);
    735     synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) {
    736         validate();
    737         return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
    738     }
    739 
    740     native int  rsnScriptFieldIDCreate(int con, int sid, int slot);
    741     synchronized int nScriptFieldIDCreate(int sid, int slot) {
    742         validate();
    743         return rsnScriptFieldIDCreate(mContext, sid, slot);
    744     }
    745 
    746     native int  rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
    747     synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
    748         validate();
    749         return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
    750     }
    751 
    752     native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc);
    753     synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) {
    754         validate();
    755         rsnScriptGroupSetInput(mContext, group, kernel, alloc);
    756     }
    757 
    758     native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc);
    759     synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) {
    760         validate();
    761         rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
    762     }
    763 
    764     native void rsnScriptGroupExecute(int con, int group);
    765     synchronized void nScriptGroupExecute(int group) {
    766         validate();
    767         rsnScriptGroupExecute(mContext, group);
    768     }
    769 
    770     native int  rsnSamplerCreate(int con, int magFilter, int minFilter,
    771                                  int wrapS, int wrapT, int wrapR, float aniso);
    772     synchronized int nSamplerCreate(int magFilter, int minFilter,
    773                                  int wrapS, int wrapT, int wrapR, float aniso) {
    774         validate();
    775         return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
    776     }
    777 
    778     native int  rsnProgramStoreCreate(int con, boolean r, boolean g, boolean b, boolean a,
    779                                       boolean depthMask, boolean dither,
    780                                       int srcMode, int dstMode, int depthFunc);
    781     synchronized int nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
    782                                          boolean depthMask, boolean dither,
    783                                          int srcMode, int dstMode, int depthFunc) {
    784         validate();
    785         return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode,
    786                                      dstMode, depthFunc);
    787     }
    788 
    789     native int  rsnProgramRasterCreate(int con, boolean pointSprite, int cullMode);
    790     synchronized int nProgramRasterCreate(boolean pointSprite, int cullMode) {
    791         validate();
    792         return rsnProgramRasterCreate(mContext, pointSprite, cullMode);
    793     }
    794 
    795     native void rsnProgramBindConstants(int con, int pv, int slot, int mID);
    796     synchronized void nProgramBindConstants(int pv, int slot, int mID) {
    797         validate();
    798         rsnProgramBindConstants(mContext, pv, slot, mID);
    799     }
    800     native void rsnProgramBindTexture(int con, int vpf, int slot, int a);
    801     synchronized void nProgramBindTexture(int vpf, int slot, int a) {
    802         validate();
    803         rsnProgramBindTexture(mContext, vpf, slot, a);
    804     }
    805     native void rsnProgramBindSampler(int con, int vpf, int slot, int s);
    806     synchronized void nProgramBindSampler(int vpf, int slot, int s) {
    807         validate();
    808         rsnProgramBindSampler(mContext, vpf, slot, s);
    809     }
    810     native int  rsnProgramFragmentCreate(int con, String shader, String[] texNames, int[] params);
    811     synchronized int nProgramFragmentCreate(String shader, String[] texNames, int[] params) {
    812         validate();
    813         return rsnProgramFragmentCreate(mContext, shader, texNames, params);
    814     }
    815     native int  rsnProgramVertexCreate(int con, String shader, String[] texNames, int[] params);
    816     synchronized int nProgramVertexCreate(String shader, String[] texNames, int[] params) {
    817         validate();
    818         return rsnProgramVertexCreate(mContext, shader, texNames, params);
    819     }
    820 
    821     native int  rsnMeshCreate(int con, int[] vtx, int[] idx, int[] prim);
    822     synchronized int nMeshCreate(int[] vtx, int[] idx, int[] prim) {
    823         validate();
    824         return rsnMeshCreate(mContext, vtx, idx, prim);
    825     }
    826     native int  rsnMeshGetVertexBufferCount(int con, int id);
    827     synchronized int nMeshGetVertexBufferCount(int id) {
    828         validate();
    829         return rsnMeshGetVertexBufferCount(mContext, id);
    830     }
    831     native int  rsnMeshGetIndexCount(int con, int id);
    832     synchronized int nMeshGetIndexCount(int id) {
    833         validate();
    834         return rsnMeshGetIndexCount(mContext, id);
    835     }
    836     native void rsnMeshGetVertices(int con, int id, int[] vtxIds, int vtxIdCount);
    837     synchronized void nMeshGetVertices(int id, int[] vtxIds, int vtxIdCount) {
    838         validate();
    839         rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
    840     }
    841     native void rsnMeshGetIndices(int con, int id, int[] idxIds, int[] primitives, int vtxIdCount);
    842     synchronized void nMeshGetIndices(int id, int[] idxIds, int[] primitives, int vtxIdCount) {
    843         validate();
    844         rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
    845     }
    846 
    847     native int  rsnPathCreate(int con, int prim, boolean isStatic, int vtx, int loop, float q);
    848     synchronized int nPathCreate(int prim, boolean isStatic, int vtx, int loop, float q) {
    849         validate();
    850         return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q);
    851     }
    852 
    853     int     mDev;
    854     int     mContext;
    855     @SuppressWarnings({"FieldCanBeLocal"})
    856     MessageThread mMessageThread;
    857 
    858     Element mElement_U8;
    859     Element mElement_I8;
    860     Element mElement_U16;
    861     Element mElement_I16;
    862     Element mElement_U32;
    863     Element mElement_I32;
    864     Element mElement_U64;
    865     Element mElement_I64;
    866     Element mElement_F32;
    867     Element mElement_F64;
    868     Element mElement_BOOLEAN;
    869 
    870     Element mElement_ELEMENT;
    871     Element mElement_TYPE;
    872     Element mElement_ALLOCATION;
    873     Element mElement_SAMPLER;
    874     Element mElement_SCRIPT;
    875     Element mElement_MESH;
    876     Element mElement_PROGRAM_FRAGMENT;
    877     Element mElement_PROGRAM_VERTEX;
    878     Element mElement_PROGRAM_RASTER;
    879     Element mElement_PROGRAM_STORE;
    880     Element mElement_FONT;
    881 
    882     Element mElement_A_8;
    883     Element mElement_RGB_565;
    884     Element mElement_RGB_888;
    885     Element mElement_RGBA_5551;
    886     Element mElement_RGBA_4444;
    887     Element mElement_RGBA_8888;
    888 
    889     Element mElement_FLOAT_2;
    890     Element mElement_FLOAT_3;
    891     Element mElement_FLOAT_4;
    892 
    893     Element mElement_DOUBLE_2;
    894     Element mElement_DOUBLE_3;
    895     Element mElement_DOUBLE_4;
    896 
    897     Element mElement_UCHAR_2;
    898     Element mElement_UCHAR_3;
    899     Element mElement_UCHAR_4;
    900 
    901     Element mElement_CHAR_2;
    902     Element mElement_CHAR_3;
    903     Element mElement_CHAR_4;
    904 
    905     Element mElement_USHORT_2;
    906     Element mElement_USHORT_3;
    907     Element mElement_USHORT_4;
    908 
    909     Element mElement_SHORT_2;
    910     Element mElement_SHORT_3;
    911     Element mElement_SHORT_4;
    912 
    913     Element mElement_UINT_2;
    914     Element mElement_UINT_3;
    915     Element mElement_UINT_4;
    916 
    917     Element mElement_INT_2;
    918     Element mElement_INT_3;
    919     Element mElement_INT_4;
    920 
    921     Element mElement_ULONG_2;
    922     Element mElement_ULONG_3;
    923     Element mElement_ULONG_4;
    924 
    925     Element mElement_LONG_2;
    926     Element mElement_LONG_3;
    927     Element mElement_LONG_4;
    928 
    929     Element mElement_YUV;
    930 
    931     Element mElement_MATRIX_4X4;
    932     Element mElement_MATRIX_3X3;
    933     Element mElement_MATRIX_2X2;
    934 
    935     Sampler mSampler_CLAMP_NEAREST;
    936     Sampler mSampler_CLAMP_LINEAR;
    937     Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
    938     Sampler mSampler_WRAP_NEAREST;
    939     Sampler mSampler_WRAP_LINEAR;
    940     Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
    941     Sampler mSampler_MIRRORED_REPEAT_NEAREST;
    942     Sampler mSampler_MIRRORED_REPEAT_LINEAR;
    943     Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
    944 
    945     ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
    946     ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
    947     ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
    948     ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
    949 
    950     ProgramRaster mProgramRaster_CULL_BACK;
    951     ProgramRaster mProgramRaster_CULL_FRONT;
    952     ProgramRaster mProgramRaster_CULL_NONE;
    953 
    954     ///////////////////////////////////////////////////////////////////////////////////
    955     //
    956 
    957     /**
    958      * The base class from which an application should derive in order
    959      * to receive RS messages from scripts. When a script calls {@code
    960      * rsSendToClient}, the data fields will be filled, and the run
    961      * method will be called on a separate thread.  This will occur
    962      * some time after {@code rsSendToClient} completes in the script,
    963      * as {@code rsSendToClient} is asynchronous. Message handlers are
    964      * not guaranteed to have completed when {@link
    965      * android.renderscript.RenderScript#finish} returns.
    966      *
    967      */
    968     public static class RSMessageHandler implements Runnable {
    969         protected int[] mData;
    970         protected int mID;
    971         protected int mLength;
    972         public void run() {
    973         }
    974     }
    975     /**
    976      * If an application is expecting messages, it should set this
    977      * field to an instance of {@link RSMessageHandler}.  This
    978      * instance will receive all the user messages sent from {@code
    979      * sendToClient} by scripts from this context.
    980      *
    981      */
    982     RSMessageHandler mMessageCallback = null;
    983 
    984     public void setMessageHandler(RSMessageHandler msg) {
    985         mMessageCallback = msg;
    986     }
    987     public RSMessageHandler getMessageHandler() {
    988         return mMessageCallback;
    989     }
    990 
    991     /**
    992      * Place a message into the message queue to be sent back to the message
    993      * handler once all previous commands have been executed.
    994      *
    995      * @param id
    996      * @param data
    997      */
    998     public void sendMessage(int id, int[] data) {
    999         nContextSendMessage(id, data);
   1000     }
   1001 
   1002     /**
   1003      * The runtime error handler base class.  An application should derive from this class
   1004      * if it wishes to install an error handler.  When errors occur at runtime,
   1005      * the fields in this class will be filled, and the run method will be called.
   1006      *
   1007      */
   1008     public static class RSErrorHandler implements Runnable {
   1009         protected String mErrorMessage;
   1010         protected int mErrorNum;
   1011         public void run() {
   1012         }
   1013     }
   1014 
   1015     /**
   1016      * Application Error handler.  All runtime errors will be dispatched to the
   1017      * instance of RSAsyncError set here.  If this field is null a
   1018      * {@link RSRuntimeException} will instead be thrown with details about the error.
   1019      * This will cause program termaination.
   1020      *
   1021      */
   1022     RSErrorHandler mErrorCallback = null;
   1023 
   1024     public void setErrorHandler(RSErrorHandler msg) {
   1025         mErrorCallback = msg;
   1026     }
   1027     public RSErrorHandler getErrorHandler() {
   1028         return mErrorCallback;
   1029     }
   1030 
   1031     /**
   1032      * RenderScript worker thread priority enumeration.  The default value is
   1033      * NORMAL.  Applications wishing to do background processing should set
   1034      * their priority to LOW to avoid starving forground processes.
   1035      */
   1036     public enum Priority {
   1037         LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
   1038         NORMAL (Process.THREAD_PRIORITY_DISPLAY);
   1039 
   1040         int mID;
   1041         Priority(int id) {
   1042             mID = id;
   1043         }
   1044     }
   1045 
   1046     void validate() {
   1047         if (mContext == 0) {
   1048             throw new RSInvalidStateException("Calling RS with no Context active.");
   1049         }
   1050     }
   1051 
   1052 
   1053     /**
   1054      * Change the priority of the worker threads for this context.
   1055      *
   1056      * @param p New priority to be set.
   1057      */
   1058     public void setPriority(Priority p) {
   1059         validate();
   1060         nContextSetPriority(p.mID);
   1061     }
   1062 
   1063     static class MessageThread extends Thread {
   1064         RenderScript mRS;
   1065         boolean mRun = true;
   1066         int[] mAuxData = new int[2];
   1067 
   1068         static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
   1069         static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
   1070         static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
   1071         static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
   1072         static final int RS_MESSAGE_TO_CLIENT_USER = 4;
   1073         static final int RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5;
   1074 
   1075         static final int RS_ERROR_FATAL_DEBUG = 0x0800;
   1076         static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
   1077 
   1078         MessageThread(RenderScript rs) {
   1079             super("RSMessageThread");
   1080             mRS = rs;
   1081 
   1082         }
   1083 
   1084         public void run() {
   1085             // This function is a temporary solution.  The final solution will
   1086             // used typed allocations where the message id is the type indicator.
   1087             int[] rbuf = new int[16];
   1088             mRS.nContextInitToClient(mRS.mContext);
   1089             while(mRun) {
   1090                 rbuf[0] = 0;
   1091                 int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
   1092                 int size = mAuxData[1];
   1093                 int subID = mAuxData[0];
   1094 
   1095                 if (msg == RS_MESSAGE_TO_CLIENT_USER) {
   1096                     if ((size>>2) >= rbuf.length) {
   1097                         rbuf = new int[(size + 3) >> 2];
   1098                     }
   1099                     if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
   1100                         RS_MESSAGE_TO_CLIENT_USER) {
   1101                         throw new RSDriverException("Error processing message from RenderScript.");
   1102                     }
   1103 
   1104                     if(mRS.mMessageCallback != null) {
   1105                         mRS.mMessageCallback.mData = rbuf;
   1106                         mRS.mMessageCallback.mID = subID;
   1107                         mRS.mMessageCallback.mLength = size;
   1108                         mRS.mMessageCallback.run();
   1109                     } else {
   1110                         throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
   1111                     }
   1112                     continue;
   1113                 }
   1114 
   1115                 if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
   1116                     String e = mRS.nContextGetErrorMessage(mRS.mContext);
   1117 
   1118                     // Throw RSRuntimeException under the following conditions:
   1119                     //
   1120                     // 1) It is an unknown fatal error.
   1121                     // 2) It is a debug fatal error, and we are not in a
   1122                     //    debug context.
   1123                     // 3) It is a debug fatal error, and we do not have an
   1124                     //    error callback.
   1125                     if (subID >= RS_ERROR_FATAL_UNKNOWN ||
   1126                         (subID >= RS_ERROR_FATAL_DEBUG &&
   1127                          (mRS.mContextType != ContextType.DEBUG ||
   1128                           mRS.mErrorCallback == null))) {
   1129                         throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
   1130                     }
   1131 
   1132                     if(mRS.mErrorCallback != null) {
   1133                         mRS.mErrorCallback.mErrorMessage = e;
   1134                         mRS.mErrorCallback.mErrorNum = subID;
   1135                         mRS.mErrorCallback.run();
   1136                     } else {
   1137                         android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
   1138                         // Do not throw here. In these cases, we do not have
   1139                         // a fatal error.
   1140                     }
   1141                     continue;
   1142                 }
   1143 
   1144                 if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
   1145                     Allocation.sendBufferNotification(subID);
   1146                     continue;
   1147                 }
   1148 
   1149                 // 2: teardown.
   1150                 // But we want to avoid starving other threads during
   1151                 // teardown by yielding until the next line in the destructor
   1152                 // can execute to set mRun = false
   1153                 try {
   1154                     sleep(1, 0);
   1155                 } catch(InterruptedException e) {
   1156                 }
   1157             }
   1158             //Log.d(LOG_TAG, "MessageThread exiting.");
   1159         }
   1160     }
   1161 
   1162     RenderScript(Context ctx) {
   1163         mContextType = ContextType.NORMAL;
   1164         if (ctx != null) {
   1165             mApplicationContext = ctx.getApplicationContext();
   1166         }
   1167         mRWLock = new ReentrantReadWriteLock();
   1168     }
   1169 
   1170     /**
   1171      * Gets the application context associated with the RenderScript context.
   1172      *
   1173      * @return The application context.
   1174      */
   1175     public final Context getApplicationContext() {
   1176         return mApplicationContext;
   1177     }
   1178 
   1179     /**
   1180      * @hide
   1181      */
   1182     public static RenderScript create(Context ctx, int sdkVersion) {
   1183         return create(ctx, sdkVersion, ContextType.NORMAL);
   1184     }
   1185 
   1186     /**
   1187      * Create a RenderScript context.
   1188      *
   1189      * @hide
   1190      * @param ctx The context.
   1191      * @return RenderScript
   1192      */
   1193     public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
   1194         if (!sInitialized) {
   1195             Log.e(LOG_TAG, "RenderScript.create() called when disabled; someone is likely to crash");
   1196             return null;
   1197         }
   1198 
   1199         RenderScript rs = new RenderScript(ctx);
   1200 
   1201         rs.mDev = rs.nDeviceCreate();
   1202         rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID);
   1203         rs.mContextType = ct;
   1204         if (rs.mContext == 0) {
   1205             throw new RSDriverException("Failed to create RS context.");
   1206         }
   1207         rs.mMessageThread = new MessageThread(rs);
   1208         rs.mMessageThread.start();
   1209         return rs;
   1210     }
   1211 
   1212     /**
   1213      * Create a RenderScript context.
   1214      *
   1215      * @param ctx The context.
   1216      * @return RenderScript
   1217      */
   1218     public static RenderScript create(Context ctx) {
   1219         return create(ctx, ContextType.NORMAL);
   1220     }
   1221 
   1222     /**
   1223      * Create a RenderScript context.
   1224      *
   1225      *
   1226      * @param ctx The context.
   1227      * @param ct The type of context to be created.
   1228      * @return RenderScript
   1229      */
   1230     public static RenderScript create(Context ctx, ContextType ct) {
   1231         int v = ctx.getApplicationInfo().targetSdkVersion;
   1232         return create(ctx, v, ct);
   1233     }
   1234 
   1235     /**
   1236      * Print the currently available debugging information about the state of
   1237      * the RS context to the log.
   1238      *
   1239      */
   1240     public void contextDump() {
   1241         validate();
   1242         nContextDump(0);
   1243     }
   1244 
   1245     /**
   1246      * Wait for any pending asynchronous opeations (such as copies to a RS
   1247      * allocation or RS script executions) to complete.
   1248      *
   1249      */
   1250     public void finish() {
   1251         nContextFinish();
   1252     }
   1253 
   1254     /**
   1255      * Destroys this RenderScript context.  Once this function is called,
   1256      * using this context or any objects belonging to this context is
   1257      * illegal.
   1258      *
   1259      */
   1260     public void destroy() {
   1261         validate();
   1262         nContextFinish();
   1263 
   1264         nContextDeinitToClient(mContext);
   1265         mMessageThread.mRun = false;
   1266         try {
   1267             mMessageThread.join();
   1268         } catch(InterruptedException e) {
   1269         }
   1270 
   1271         nContextDestroy();
   1272 
   1273         nDeviceDestroy(mDev);
   1274         mDev = 0;
   1275     }
   1276 
   1277     boolean isAlive() {
   1278         return mContext != 0;
   1279     }
   1280 
   1281     int safeID(BaseObj o) {
   1282         if(o != null) {
   1283             return o.getID(this);
   1284         }
   1285         return 0;
   1286     }
   1287 }
   1288