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