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