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