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