• 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 
34 /**
35  * This class provides access to a RenderScript context, which controls RenderScript
36  * initialization, resource management, and teardown. An instance of the RenderScript
37  * class must be created before any other RS objects can be created.
38  *
39  * <div class="special reference">
40  * <h3>Developer Guides</h3>
41  * <p>For more information about creating an application that uses RenderScript, read the
42  * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
43  * </div>
44  **/
45 public class RenderScript {
46     static final String LOG_TAG = "RenderScript_jni";
47     static final boolean DEBUG  = false;
48     @SuppressWarnings({"UnusedDeclaration", "deprecation"})
49     static final boolean LOG_ENABLED = false;
50 
51     private Context mApplicationContext;
52 
53     /*
54      * We use a class initializer to allow the native code to cache some
55      * field offsets.
56      */
57     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
58     static boolean sInitialized;
59     static boolean sUseGCHooks;
60     static Object sRuntime;
61     static Method registerNativeAllocation;
62     static Method registerNativeFree;
63 
64     static Object lock = new Object();
65 
66     // Non-threadsafe functions.
nDeviceCreate()67     native int  nDeviceCreate();
nDeviceDestroy(int dev)68     native void nDeviceDestroy(int dev);
nDeviceSetConfig(int dev, int param, int value)69     native void nDeviceSetConfig(int dev, int param, int value);
nContextGetUserMessage(int con, int[] data)70     native int nContextGetUserMessage(int con, int[] data);
nContextGetErrorMessage(int con)71     native String nContextGetErrorMessage(int con);
nContextPeekMessage(int con, int[] subID)72     native int  nContextPeekMessage(int con, int[] subID);
nContextInitToClient(int con)73     native void nContextInitToClient(int con);
nContextDeinitToClient(int con)74     native void nContextDeinitToClient(int con);
75 
76     static boolean isNative = false;
77 
78     static private int sThunk = -1;
79     static private int sSdkVersion = -1;
80 
shouldThunk()81     static boolean shouldThunk() {
82         if (sThunk == -1) {
83             throw new RSRuntimeException("Can't use RS classes before setting up a RenderScript context");
84         } else if (sThunk == 1) {
85             return true;
86         }
87         return false;
88     }
89 
90     /**
91      * Determines whether or not we should be thunking into the native
92      * RenderScript layer or actually using the compatibility library.
93      */
setupThunk(int sdkVersion, Context ctx)94     static private boolean setupThunk(int sdkVersion, Context ctx) {
95         if (sThunk == -1) {
96 
97             // get the value of the debug.rs.forcecompat property
98             int forcecompat = 0;
99             try {
100                 Class<?> sysprop = Class.forName("android.os.SystemProperties");
101                 Class[] signature = {String.class, Integer.TYPE};
102                 Method getint = sysprop.getDeclaredMethod("getInt", signature);
103                 Object[] args = {"debug.rs.forcecompat", new Integer(0)};
104                 forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue();
105             } catch (Exception e) {
106 
107             }
108 
109             // use compat on Jelly Bean MR2 if we're requesting SDK 19+
110             if (android.os.Build.VERSION.SDK_INT == 18 && sdkVersion >= 19) {
111                 sThunk = 0;
112             }
113             else if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
114                      && forcecompat == 0) {
115                 sThunk = 1;
116             } else {
117                 sThunk = 0;
118             }
119 
120 
121             if (sThunk == 1) {
122                 // Workarounds that may disable thunking go here
123                 ApplicationInfo info;
124                 try {
125                     info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
126                                                                       PackageManager.GET_META_DATA);
127                 } catch (PackageManager.NameNotFoundException e) {
128                     // assume no workarounds needed
129                     return true;
130                 }
131                 long minorVersion = 0;
132 
133                 // load minorID from reflection
134                 try {
135                     Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
136                     Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
137                     minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
138                 } catch (Exception e) {
139                     // minor version remains 0 on devices with no possible WARs
140                 }
141 
142                 if (info.metaData != null) {
143                     // asynchronous teardown: minor version 1+
144                     if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableAsyncTeardown") == true) {
145                         if (minorVersion == 0) {
146                             sThunk = 0;
147                         }
148                     }
149 
150                     // blur issues on some drivers with 4.4
151                     if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableBlurWorkaround") == true) {
152                         if (android.os.Build.VERSION.SDK_INT <= 19) {
153                             //android.util.Log.e("rs", "war on");
154                             sThunk = 0;
155                         }
156                     }
157                 }
158                 // end of workarounds
159             }
160         }
161 
162         if (sThunk == 1) {
163             return true;
164         }
165         return false;
166     }
167 
168     /**
169      * Name of the file that holds the object cache.
170      */
171     private static final String CACHE_PATH = "com.android.renderscript.cache";
172     static String mCachePath;
173 
174      /**
175      * Sets the directory to use as a persistent storage for the
176      * renderscript object file cache.
177      *
178      * @hide
179      * @param cacheDir A directory the current process can write to
180      */
setupDiskCache(File cacheDir)181     public static void setupDiskCache(File cacheDir) {
182         File f = new File(cacheDir, CACHE_PATH);
183         mCachePath = f.getAbsolutePath();
184         f.mkdirs();
185     }
186 
187     /**
188      * ContextType specifies the specific type of context to be created.
189      *
190      */
191     public enum ContextType {
192         /**
193          * NORMAL context, this is the default and what shipping apps should
194          * use.
195          */
196         NORMAL (0),
197 
198         /**
199          * DEBUG context, perform extra runtime checks to validate the
200          * kernels and APIs are being used as intended.  Get and SetElementAt
201          * will be bounds checked in this mode.
202          */
203         DEBUG (1),
204 
205         /**
206          * PROFILE context, Intended to be used once the first time an
207          * application is run on a new device.  This mode allows the runtime to
208          * do additional testing and performance tuning.
209          */
210         PROFILE (2);
211 
212         int mID;
ContextType(int id)213         ContextType(int id) {
214             mID = id;
215         }
216     }
217 
218     // Methods below are wrapped to protect the non-threadsafe
219     // lockless fifo.
rsnContextCreate(int dev, int ver, int sdkVer, int contextType)220     native int  rsnContextCreate(int dev, int ver, int sdkVer, int contextType);
nContextCreate(int dev, int ver, int sdkVer, int contextType)221     synchronized int nContextCreate(int dev, int ver, int sdkVer, int contextType) {
222         return rsnContextCreate(dev, ver, sdkVer, contextType);
223     }
rsnContextDestroy(int con)224     native void rsnContextDestroy(int con);
nContextDestroy()225     synchronized void nContextDestroy() {
226         validate();
227 
228         // take teardown lock
229         // teardown lock can only be taken when no objects are being destroyed
230         ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
231         wlock.lock();
232 
233         int curCon = mContext;
234         // context is considered dead as of this point
235         mContext = 0;
236 
237         wlock.unlock();
238         rsnContextDestroy(curCon);
239     }
rsnContextSetPriority(int con, int p)240     native void rsnContextSetPriority(int con, int p);
nContextSetPriority(int p)241     synchronized void nContextSetPriority(int p) {
242         validate();
243         rsnContextSetPriority(mContext, p);
244     }
rsnContextDump(int con, int bits)245     native void rsnContextDump(int con, int bits);
nContextDump(int bits)246     synchronized void nContextDump(int bits) {
247         validate();
248         rsnContextDump(mContext, bits);
249     }
rsnContextFinish(int con)250     native void rsnContextFinish(int con);
nContextFinish()251     synchronized void nContextFinish() {
252         validate();
253         rsnContextFinish(mContext);
254     }
255 
rsnContextSendMessage(int con, int id, int[] data)256     native void rsnContextSendMessage(int con, int id, int[] data);
nContextSendMessage(int id, int[] data)257     synchronized void nContextSendMessage(int id, int[] data) {
258         validate();
259         rsnContextSendMessage(mContext, id, data);
260     }
261 
262     // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
rsnObjDestroy(int con, int id)263     native void rsnObjDestroy(int con, int id);
nObjDestroy(int id)264     void nObjDestroy(int id) {
265         // There is a race condition here.  The calling code may be run
266         // by the gc while teardown is occuring.  This protects againts
267         // deleting dead objects.
268         if (mContext != 0) {
269             rsnObjDestroy(mContext, id);
270         }
271     }
272 
rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize)273     native int  rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
nElementCreate(int type, int kind, boolean norm, int vecSize)274     synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
275         validate();
276         return rsnElementCreate(mContext, type, kind, norm, vecSize);
277     }
rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes)278     native int  rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
nElementCreate2(int[] elements, String[] names, int[] arraySizes)279     synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
280         validate();
281         return rsnElementCreate2(mContext, elements, names, arraySizes);
282     }
rsnElementGetNativeData(int con, int id, int[] elementData)283     native void rsnElementGetNativeData(int con, int id, int[] elementData);
nElementGetNativeData(int id, int[] elementData)284     synchronized void nElementGetNativeData(int id, int[] elementData) {
285         validate();
286         rsnElementGetNativeData(mContext, id, elementData);
287     }
rsnElementGetSubElements(int con, int id, int[] IDs, String[] names, int[] arraySizes)288     native void rsnElementGetSubElements(int con, int id,
289                                          int[] IDs, String[] names, int[] arraySizes);
nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes)290     synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) {
291         validate();
292         rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
293     }
294 
rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces, int yuv)295     native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces, int yuv)296     synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
297         validate();
298         return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
299     }
rsnTypeGetNativeData(int con, int id, int[] typeData)300     native void rsnTypeGetNativeData(int con, int id, int[] typeData);
nTypeGetNativeData(int id, int[] typeData)301     synchronized void nTypeGetNativeData(int id, int[] typeData) {
302         validate();
303         rsnTypeGetNativeData(mContext, id, typeData);
304     }
305 
rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer)306     native int  rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer);
nAllocationCreateTyped(int type, int mip, int usage, int pointer)307     synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) {
308         validate();
309         return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
310     }
rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage)311     native int  rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage)312     synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
313         validate();
314         return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
315     }
316 
rsnAllocationCreateBitmapBackedAllocation(int con, int type, int mip, Bitmap bmp, int usage)317     native int  rsnAllocationCreateBitmapBackedAllocation(int con, int type, int mip, Bitmap bmp, int usage);
nAllocationCreateBitmapBackedAllocation(int type, int mip, Bitmap bmp, int usage)318     synchronized int nAllocationCreateBitmapBackedAllocation(int type, int mip, Bitmap bmp, int usage) {
319         validate();
320         return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
321     }
322 
323 
rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage)324     native int  rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage)325     synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
326         validate();
327         return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
328     }
rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp)329     native int  rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
nAllocationCreateBitmapRef(int type, Bitmap bmp)330     synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
331         validate();
332         return rsnAllocationCreateBitmapRef(mContext, type, bmp);
333     }
rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage)334     native int  rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage);
nAllocationCreateFromAssetStream(int mips, int assetStream, int usage)335     synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
336         validate();
337         return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
338     }
339 
rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp)340     native void  rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
nAllocationCopyToBitmap(int alloc, Bitmap bmp)341     synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
342         validate();
343         rsnAllocationCopyToBitmap(mContext, alloc, bmp);
344     }
345 
346 
rsnAllocationSyncAll(int con, int alloc, int src)347     native void rsnAllocationSyncAll(int con, int alloc, int src);
nAllocationSyncAll(int alloc, int src)348     synchronized void nAllocationSyncAll(int alloc, int src) {
349         validate();
350         rsnAllocationSyncAll(mContext, alloc, src);
351     }
rsnAllocationIoSend(int con, int alloc)352     native void rsnAllocationIoSend(int con, int alloc);
nAllocationIoSend(int alloc)353     synchronized void nAllocationIoSend(int alloc) {
354         validate();
355         rsnAllocationIoSend(mContext, alloc);
356     }
rsnAllocationIoReceive(int con, int alloc)357     native void rsnAllocationIoReceive(int con, int alloc);
nAllocationIoReceive(int alloc)358     synchronized void nAllocationIoReceive(int alloc) {
359         validate();
360         rsnAllocationIoReceive(mContext, alloc);
361     }
362 
363 
rsnAllocationGenerateMipmaps(int con, int alloc)364     native void rsnAllocationGenerateMipmaps(int con, int alloc);
nAllocationGenerateMipmaps(int alloc)365     synchronized void nAllocationGenerateMipmaps(int alloc) {
366         validate();
367         rsnAllocationGenerateMipmaps(mContext, alloc);
368     }
rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp)369     native void  rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
nAllocationCopyFromBitmap(int alloc, Bitmap bmp)370     synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
371         validate();
372         rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
373     }
374 
375 
rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes)376     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes);
nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes)377     synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) {
378         validate();
379         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
380     }
rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes)381     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes);
nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes)382     synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) {
383         validate();
384         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
385     }
rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes)386     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes);
nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes)387     synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) {
388         validate();
389         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
390     }
rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes)391     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes);
nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes)392     synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) {
393         validate();
394         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
395     }
396 
rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes)397     native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes)398     synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
399         validate();
400         rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
401     }
402 
rsnAllocationData2D(int con, int dstAlloc, int dstXoff, int dstYoff, int dstMip, int dstFace, int width, int height, int srcAlloc, int srcXoff, int srcYoff, int srcMip, int srcFace)403     native void rsnAllocationData2D(int con,
404                                     int dstAlloc, int dstXoff, int dstYoff,
405                                     int dstMip, int dstFace,
406                                     int width, int height,
407                                     int srcAlloc, int srcXoff, int srcYoff,
408                                     int srcMip, int srcFace);
nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff, int dstMip, int dstFace, int width, int height, int srcAlloc, int srcXoff, int srcYoff, int srcMip, int srcFace)409     synchronized void nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff,
410                                         int dstMip, int dstFace,
411                                         int width, int height,
412                                         int srcAlloc, int srcXoff, int srcYoff,
413                                         int srcMip, int srcFace) {
414         validate();
415         rsnAllocationData2D(mContext,
416                             dstAlloc, dstXoff, dstYoff,
417                             dstMip, dstFace,
418                             width, height,
419                             srcAlloc, srcXoff, srcYoff,
420                             srcMip, srcFace);
421     }
422 
rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes)423     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes);
nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes)424     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) {
425         validate();
426         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
427     }
rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes)428     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes);
nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes)429     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) {
430         validate();
431         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
432     }
rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes)433     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes);
nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes)434     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) {
435         validate();
436         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
437     }
rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes)438     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes);
nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes)439     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) {
440         validate();
441         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
442     }
rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b)443     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b);
nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b)444     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) {
445         validate();
446         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
447     }
448 
rsnAllocationData3D(int con, int dstAlloc, int dstXoff, int dstYoff, int dstZoff, int dstMip, int width, int height, int depth, int srcAlloc, int srcXoff, int srcYoff, int srcZoff, int srcMip)449     native void rsnAllocationData3D(int con,
450                                     int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
451                                     int dstMip,
452                                     int width, int height, int depth,
453                                     int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
454                                     int srcMip);
nAllocationData3D(int dstAlloc, int dstXoff, int dstYoff, int dstZoff, int dstMip, int width, int height, int depth, int srcAlloc, int srcXoff, int srcYoff, int srcZoff, int srcMip)455     synchronized void nAllocationData3D(int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
456                                         int dstMip,
457                                         int width, int height, int depth,
458                                         int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
459                                         int srcMip) {
460         validate();
461         rsnAllocationData3D(mContext,
462                             dstAlloc, dstXoff, dstYoff, dstZoff,
463                             dstMip, width, height, depth,
464                             srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
465     }
466 
rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes)467     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes);
nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes)468     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes) {
469         validate();
470         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
471     }
rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes)472     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes);
nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes)473     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes) {
474         validate();
475         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
476     }
rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes)477     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes);
nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes)478     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes) {
479         validate();
480         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
481     }
rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes)482     native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes);
nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes)483     synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes) {
484         validate();
485         rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
486     }
487 
488 
rsnAllocationRead(int con, int id, byte[] d)489     native void rsnAllocationRead(int con, int id, byte[] d);
nAllocationRead(int id, byte[] d)490     synchronized void nAllocationRead(int id, byte[] d) {
491         validate();
492         rsnAllocationRead(mContext, id, d);
493     }
rsnAllocationRead(int con, int id, short[] d)494     native void rsnAllocationRead(int con, int id, short[] d);
nAllocationRead(int id, short[] d)495     synchronized void nAllocationRead(int id, short[] d) {
496         validate();
497         rsnAllocationRead(mContext, id, d);
498     }
rsnAllocationRead(int con, int id, int[] d)499     native void rsnAllocationRead(int con, int id, int[] d);
nAllocationRead(int id, int[] d)500     synchronized void nAllocationRead(int id, int[] d) {
501         validate();
502         rsnAllocationRead(mContext, id, d);
503     }
rsnAllocationRead(int con, int id, float[] d)504     native void rsnAllocationRead(int con, int id, float[] d);
nAllocationRead(int id, float[] d)505     synchronized void nAllocationRead(int id, float[] d) {
506         validate();
507         rsnAllocationRead(mContext, id, d);
508     }
rsnAllocationGetType(int con, int id)509     native int  rsnAllocationGetType(int con, int id);
nAllocationGetType(int id)510     synchronized int nAllocationGetType(int id) {
511         validate();
512         return rsnAllocationGetType(mContext, id);
513     }
514 
rsnAllocationResize1D(int con, int id, int dimX)515     native void rsnAllocationResize1D(int con, int id, int dimX);
nAllocationResize1D(int id, int dimX)516     synchronized void nAllocationResize1D(int id, int dimX) {
517         validate();
518         rsnAllocationResize1D(mContext, id, dimX);
519     }
rsnAllocationResize2D(int con, int id, int dimX, int dimY)520     native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
nAllocationResize2D(int id, int dimX, int dimY)521     synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
522         validate();
523         rsnAllocationResize2D(mContext, id, dimX, dimY);
524     }
525 
rsnScriptBindAllocation(int con, int script, int alloc, int slot)526     native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
nScriptBindAllocation(int script, int alloc, int slot)527     synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
528         validate();
529         rsnScriptBindAllocation(mContext, script, alloc, slot);
530     }
rsnScriptSetTimeZone(int con, int script, byte[] timeZone)531     native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
nScriptSetTimeZone(int script, byte[] timeZone)532     synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
533         validate();
534         rsnScriptSetTimeZone(mContext, script, timeZone);
535     }
rsnScriptInvoke(int con, int id, int slot)536     native void rsnScriptInvoke(int con, int id, int slot);
nScriptInvoke(int id, int slot)537     synchronized void nScriptInvoke(int id, int slot) {
538         validate();
539         rsnScriptInvoke(mContext, id, slot);
540     }
rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params)541     native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params);
rsnScriptForEach(int con, int id, int slot, int ain, int aout)542     native void rsnScriptForEach(int con, int id, int slot, int ain, int aout);
rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, byte[] params, int xstart, int xend, int ystart, int yend, int zstart, int zend)543     native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, byte[] params,
544                                         int xstart, int xend, int ystart, int yend, int zstart, int zend);
rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, int xstart, int xend, int ystart, int yend, int zstart, int zend)545     native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout,
546                                         int xstart, int xend, int ystart, int yend, int zstart, int zend);
nScriptForEach(int id, int slot, int ain, int aout, byte[] params)547     synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) {
548         validate();
549         if (params == null) {
550             rsnScriptForEach(mContext, id, slot, ain, aout);
551         } else {
552             rsnScriptForEach(mContext, id, slot, ain, aout, params);
553         }
554     }
555 
nScriptForEachClipped(int id, int slot, int ain, int aout, byte[] params, int xstart, int xend, int ystart, int yend, int zstart, int zend)556     synchronized void nScriptForEachClipped(int id, int slot, int ain, int aout, byte[] params,
557                                             int xstart, int xend, int ystart, int yend, int zstart, int zend) {
558         validate();
559         if (params == null) {
560             rsnScriptForEachClipped(mContext, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend);
561         } else {
562             rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend);
563         }
564     }
565 
rsnScriptInvokeV(int con, int id, int slot, byte[] params)566     native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
nScriptInvokeV(int id, int slot, byte[] params)567     synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
568         validate();
569         rsnScriptInvokeV(mContext, id, slot, params);
570     }
rsnScriptSetVarI(int con, int id, int slot, int val)571     native void rsnScriptSetVarI(int con, int id, int slot, int val);
nScriptSetVarI(int id, int slot, int val)572     synchronized void nScriptSetVarI(int id, int slot, int val) {
573         validate();
574         rsnScriptSetVarI(mContext, id, slot, val);
575     }
rsnScriptSetVarJ(int con, int id, int slot, long val)576     native void rsnScriptSetVarJ(int con, int id, int slot, long val);
nScriptSetVarJ(int id, int slot, long val)577     synchronized void nScriptSetVarJ(int id, int slot, long val) {
578         validate();
579         rsnScriptSetVarJ(mContext, id, slot, val);
580     }
rsnScriptSetVarF(int con, int id, int slot, float val)581     native void rsnScriptSetVarF(int con, int id, int slot, float val);
nScriptSetVarF(int id, int slot, float val)582     synchronized void nScriptSetVarF(int id, int slot, float val) {
583         validate();
584         rsnScriptSetVarF(mContext, id, slot, val);
585     }
rsnScriptSetVarD(int con, int id, int slot, double val)586     native void rsnScriptSetVarD(int con, int id, int slot, double val);
nScriptSetVarD(int id, int slot, double val)587     synchronized void nScriptSetVarD(int id, int slot, double val) {
588         validate();
589         rsnScriptSetVarD(mContext, id, slot, val);
590     }
rsnScriptSetVarV(int con, int id, int slot, byte[] val)591     native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
nScriptSetVarV(int id, int slot, byte[] val)592     synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
593         validate();
594         rsnScriptSetVarV(mContext, id, slot, val);
595     }
rsnScriptSetVarVE(int con, int id, int slot, byte[] val, int e, int[] dims)596     native void rsnScriptSetVarVE(int con, int id, int slot, byte[] val,
597                                   int e, int[] dims);
nScriptSetVarVE(int id, int slot, byte[] val, int e, int[] dims)598     synchronized void nScriptSetVarVE(int id, int slot, byte[] val,
599                                       int e, int[] dims) {
600         validate();
601         rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
602     }
rsnScriptSetVarObj(int con, int id, int slot, int val)603     native void rsnScriptSetVarObj(int con, int id, int slot, int val);
nScriptSetVarObj(int id, int slot, int val)604     synchronized void nScriptSetVarObj(int id, int slot, int val) {
605         validate();
606         rsnScriptSetVarObj(mContext, id, slot, val);
607     }
608 
rsnScriptCCreate(int con, String resName, String cacheDir, byte[] script, int length)609     native int  rsnScriptCCreate(int con, String resName, String cacheDir,
610                                  byte[] script, int length);
nScriptCCreate(String resName, String cacheDir, byte[] script, int length)611     synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
612         validate();
613         return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
614     }
615 
rsnScriptIntrinsicCreate(int con, int id, int eid)616     native int  rsnScriptIntrinsicCreate(int con, int id, int eid);
nScriptIntrinsicCreate(int id, int eid)617     synchronized int nScriptIntrinsicCreate(int id, int eid) {
618         validate();
619         return rsnScriptIntrinsicCreate(mContext, id, eid);
620     }
621 
rsnScriptKernelIDCreate(int con, int sid, int slot, int sig)622     native int  rsnScriptKernelIDCreate(int con, int sid, int slot, int sig);
nScriptKernelIDCreate(int sid, int slot, int sig)623     synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) {
624         validate();
625         return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
626     }
627 
rsnScriptFieldIDCreate(int con, int sid, int slot)628     native int  rsnScriptFieldIDCreate(int con, int sid, int slot);
nScriptFieldIDCreate(int sid, int slot)629     synchronized int nScriptFieldIDCreate(int sid, int slot) {
630         validate();
631         return rsnScriptFieldIDCreate(mContext, sid, slot);
632     }
633 
rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types)634     native int  rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types)635     synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
636         validate();
637         return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
638     }
639 
rsnScriptGroupSetInput(int con, int group, int kernel, int alloc)640     native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc);
nScriptGroupSetInput(int group, int kernel, int alloc)641     synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) {
642         validate();
643         rsnScriptGroupSetInput(mContext, group, kernel, alloc);
644     }
645 
rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc)646     native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc);
nScriptGroupSetOutput(int group, int kernel, int alloc)647     synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) {
648         validate();
649         rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
650     }
651 
rsnScriptGroupExecute(int con, int group)652     native void rsnScriptGroupExecute(int con, int group);
nScriptGroupExecute(int group)653     synchronized void nScriptGroupExecute(int group) {
654         validate();
655         rsnScriptGroupExecute(mContext, group);
656     }
657 
rsnSamplerCreate(int con, int magFilter, int minFilter, int wrapS, int wrapT, int wrapR, float aniso)658     native int  rsnSamplerCreate(int con, int magFilter, int minFilter,
659                                  int wrapS, int wrapT, int wrapR, float aniso);
nSamplerCreate(int magFilter, int minFilter, int wrapS, int wrapT, int wrapR, float aniso)660     synchronized int nSamplerCreate(int magFilter, int minFilter,
661                                  int wrapS, int wrapT, int wrapR, float aniso) {
662         validate();
663         return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
664     }
665 
666 
667 
668 
669     int     mDev;
670     int     mContext;
671     ReentrantReadWriteLock mRWLock;
672     @SuppressWarnings({"FieldCanBeLocal"})
673     MessageThread mMessageThread;
674 
675     Element mElement_U8;
676     Element mElement_I8;
677     Element mElement_U16;
678     Element mElement_I16;
679     Element mElement_U32;
680     Element mElement_I32;
681     Element mElement_U64;
682     Element mElement_I64;
683     Element mElement_F32;
684     Element mElement_F64;
685     Element mElement_BOOLEAN;
686 
687     Element mElement_ELEMENT;
688     Element mElement_TYPE;
689     Element mElement_ALLOCATION;
690     Element mElement_SAMPLER;
691     Element mElement_SCRIPT;
692 
693     Element mElement_A_8;
694     Element mElement_RGB_565;
695     Element mElement_RGB_888;
696     Element mElement_RGBA_5551;
697     Element mElement_RGBA_4444;
698     Element mElement_RGBA_8888;
699 
700     Element mElement_FLOAT_2;
701     Element mElement_FLOAT_3;
702     Element mElement_FLOAT_4;
703 
704     Element mElement_DOUBLE_2;
705     Element mElement_DOUBLE_3;
706     Element mElement_DOUBLE_4;
707 
708     Element mElement_UCHAR_2;
709     Element mElement_UCHAR_3;
710     Element mElement_UCHAR_4;
711 
712     Element mElement_CHAR_2;
713     Element mElement_CHAR_3;
714     Element mElement_CHAR_4;
715 
716     Element mElement_USHORT_2;
717     Element mElement_USHORT_3;
718     Element mElement_USHORT_4;
719 
720     Element mElement_SHORT_2;
721     Element mElement_SHORT_3;
722     Element mElement_SHORT_4;
723 
724     Element mElement_UINT_2;
725     Element mElement_UINT_3;
726     Element mElement_UINT_4;
727 
728     Element mElement_INT_2;
729     Element mElement_INT_3;
730     Element mElement_INT_4;
731 
732     Element mElement_ULONG_2;
733     Element mElement_ULONG_3;
734     Element mElement_ULONG_4;
735 
736     Element mElement_LONG_2;
737     Element mElement_LONG_3;
738     Element mElement_LONG_4;
739 
740     Element mElement_MATRIX_4X4;
741     Element mElement_MATRIX_3X3;
742     Element mElement_MATRIX_2X2;
743 
744     Sampler mSampler_CLAMP_NEAREST;
745     Sampler mSampler_CLAMP_LINEAR;
746     Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
747     Sampler mSampler_WRAP_NEAREST;
748     Sampler mSampler_WRAP_LINEAR;
749     Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
750     Sampler mSampler_MIRRORED_REPEAT_NEAREST;
751     Sampler mSampler_MIRRORED_REPEAT_LINEAR;
752     Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
753 
754 
755     ///////////////////////////////////////////////////////////////////////////////////
756     //
757 
758     /**
759      * The base class from which an application should derive in order
760      * to receive RS messages from scripts. When a script calls {@code
761      * rsSendToClient}, the data fields will be filled, and the run
762      * method will be called on a separate thread.  This will occur
763      * some time after {@code rsSendToClient} completes in the script,
764      * as {@code rsSendToClient} is asynchronous. Message handlers are
765      * not guaranteed to have completed when {@link
766      * android.support.v8.renderscript.RenderScript#finish} returns.
767      *
768      */
769     public static class RSMessageHandler implements Runnable {
770         protected int[] mData;
771         protected int mID;
772         protected int mLength;
run()773         public void run() {
774         }
775     }
776     /**
777      * If an application is expecting messages, it should set this
778      * field to an instance of {@link RSMessageHandler}.  This
779      * instance will receive all the user messages sent from {@code
780      * sendToClient} by scripts from this context.
781      *
782      */
783     RSMessageHandler mMessageCallback = null;
784 
setMessageHandler(RSMessageHandler msg)785     public void setMessageHandler(RSMessageHandler msg) {
786         mMessageCallback = msg;
787         if (isNative) {
788             RenderScriptThunker rst = (RenderScriptThunker) this;
789             rst.setMessageHandler(msg);
790         }
791     }
getMessageHandler()792     public RSMessageHandler getMessageHandler() {
793         return mMessageCallback;
794     }
795 
796     /**
797      * Place a message into the message queue to be sent back to the message
798      * handler once all previous commands have been executed.
799      *
800      * @hide
801      *
802      * @param id
803      * @param data
804      */
sendMessage(int id, int[] data)805     public void sendMessage(int id, int[] data) {
806         nContextSendMessage(id, data);
807     }
808 
809     /**
810      * The runtime error handler base class.  An application should derive from this class
811      * if it wishes to install an error handler.  When errors occur at runtime,
812      * the fields in this class will be filled, and the run method will be called.
813      *
814      */
815     public static class RSErrorHandler implements Runnable {
816         protected String mErrorMessage;
817         protected int mErrorNum;
run()818         public void run() {
819         }
820     }
821 
822     /**
823      * Application Error handler.  All runtime errors will be dispatched to the
824      * instance of RSAsyncError set here.  If this field is null a
825      * {@link RSRuntimeException} will instead be thrown with details about the error.
826      * This will cause program termaination.
827      *
828      */
829     RSErrorHandler mErrorCallback = null;
830 
setErrorHandler(RSErrorHandler msg)831     public void setErrorHandler(RSErrorHandler msg) {
832         mErrorCallback = msg;
833         if (isNative) {
834             RenderScriptThunker rst = (RenderScriptThunker) this;
835             rst.setErrorHandler(msg);
836         }
837     }
getErrorHandler()838     public RSErrorHandler getErrorHandler() {
839         return mErrorCallback;
840     }
841 
842     /**
843      * RenderScript worker thread priority enumeration.  The default value is
844      * NORMAL.  Applications wishing to do background processing should set
845      * their priority to LOW to avoid starving forground processes.
846      */
847     public enum Priority {
848         LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
849         NORMAL (Process.THREAD_PRIORITY_DISPLAY);
850 
851         int mID;
Priority(int id)852         Priority(int id) {
853             mID = id;
854         }
855     }
856 
validate()857     void validate() {
858         if (mContext == 0) {
859             throw new RSInvalidStateException("Calling RS with no Context active.");
860         }
861     }
862 
863 
864     /**
865      * Change the priority of the worker threads for this context.
866      *
867      * @param p New priority to be set.
868      */
setPriority(Priority p)869     public void setPriority(Priority p) {
870         validate();
871         nContextSetPriority(p.mID);
872     }
873 
874     static class MessageThread extends Thread {
875         RenderScript mRS;
876         boolean mRun = true;
877         int[] mAuxData = new int[2];
878 
879         static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
880         static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
881         static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
882         static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
883         static final int RS_MESSAGE_TO_CLIENT_USER = 4;
884 
885         static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
886 
MessageThread(RenderScript rs)887         MessageThread(RenderScript rs) {
888             super("RSMessageThread");
889             mRS = rs;
890 
891         }
892 
run()893         public void run() {
894             // This function is a temporary solution.  The final solution will
895             // used typed allocations where the message id is the type indicator.
896             int[] rbuf = new int[16];
897             mRS.nContextInitToClient(mRS.mContext);
898             while(mRun) {
899                 rbuf[0] = 0;
900                 int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
901                 int size = mAuxData[1];
902                 int subID = mAuxData[0];
903 
904                 if (msg == RS_MESSAGE_TO_CLIENT_USER) {
905                     if ((size>>2) >= rbuf.length) {
906                         rbuf = new int[(size + 3) >> 2];
907                     }
908                     if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
909                         RS_MESSAGE_TO_CLIENT_USER) {
910                         throw new RSDriverException("Error processing message from RenderScript.");
911                     }
912 
913                     if(mRS.mMessageCallback != null) {
914                         mRS.mMessageCallback.mData = rbuf;
915                         mRS.mMessageCallback.mID = subID;
916                         mRS.mMessageCallback.mLength = size;
917                         mRS.mMessageCallback.run();
918                     } else {
919                         throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
920                     }
921                     continue;
922                 }
923 
924                 if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
925                     String e = mRS.nContextGetErrorMessage(mRS.mContext);
926 
927                     if (subID >= RS_ERROR_FATAL_UNKNOWN) {
928                         throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
929                     }
930 
931                     if(mRS.mErrorCallback != null) {
932                         mRS.mErrorCallback.mErrorMessage = e;
933                         mRS.mErrorCallback.mErrorNum = subID;
934                         mRS.mErrorCallback.run();
935                     } else {
936                         android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
937                         // Do not throw here. In these cases, we do not have
938                         // a fatal error.
939                     }
940                     continue;
941                 }
942 
943                 // 2: teardown.
944                 // But we want to avoid starving other threads during
945                 // teardown by yielding until the next line in the destructor
946                 // can execute to set mRun = false
947                 try {
948                     sleep(1, 0);
949                 } catch(InterruptedException e) {
950                 }
951             }
952             //Log.d(LOG_TAG, "MessageThread exiting.");
953         }
954     }
955 
RenderScript(Context ctx)956     RenderScript(Context ctx) {
957         if (ctx != null) {
958             mApplicationContext = ctx.getApplicationContext();
959         }
960         mRWLock = new ReentrantReadWriteLock();
961     }
962 
963     /**
964      * Gets the application context associated with the RenderScript context.
965      *
966      * @return The application context.
967      */
getApplicationContext()968     public final Context getApplicationContext() {
969         return mApplicationContext;
970     }
971 
972     /**
973      * @hide
974      */
create(Context ctx, int sdkVersion)975     public static RenderScript create(Context ctx, int sdkVersion) {
976         return create(ctx, sdkVersion, ContextType.NORMAL);
977     }
978 
979     /**
980      * Create a RenderScript context.
981      *
982      * @hide
983      * @param ctx The context.
984      * @return RenderScript
985      */
create(Context ctx, int sdkVersion, ContextType ct)986     public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
987         RenderScript rs = new RenderScript(ctx);
988 
989         if (sSdkVersion == -1) {
990             sSdkVersion = sdkVersion;
991         } else if (sSdkVersion != sdkVersion) {
992             throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
993         }
994 
995         if (setupThunk(sSdkVersion, ctx)) {
996             android.util.Log.v(LOG_TAG, "RS native mode");
997             return RenderScriptThunker.create(ctx, sSdkVersion);
998         }
999         synchronized(lock) {
1000             if (sInitialized == false) {
1001                 try {
1002                     Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
1003                     Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
1004                     sRuntime = get_runtime.invoke(null);
1005                     registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", Integer.TYPE);
1006                     registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", Integer.TYPE);
1007                     sUseGCHooks = true;
1008                 } catch (Exception e) {
1009                     Log.e(LOG_TAG, "No GC methods");
1010                     sUseGCHooks = false;
1011                 }
1012                 try {
1013                     System.loadLibrary("RSSupport");
1014                     System.loadLibrary("rsjni");
1015                     sInitialized = true;
1016                 } catch (UnsatisfiedLinkError e) {
1017                     Log.e(LOG_TAG, "Error loading RS jni library: " + e);
1018                     throw new RSRuntimeException("Error loading RS jni library: " + e);
1019                 }
1020             }
1021         }
1022 
1023         android.util.Log.v(LOG_TAG, "RS compat mode");
1024         rs.mDev = rs.nDeviceCreate();
1025         rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion, ct.mID);
1026         if (rs.mContext == 0) {
1027             throw new RSDriverException("Failed to create RS context.");
1028         }
1029         rs.mMessageThread = new MessageThread(rs);
1030         rs.mMessageThread.start();
1031         return rs;
1032     }
1033 
1034     /**
1035      * Create a RenderScript context.
1036      *
1037      * @param ctx The context.
1038      * @return RenderScript
1039      */
create(Context ctx)1040     public static RenderScript create(Context ctx) {
1041         return create(ctx, ContextType.NORMAL);
1042     }
1043 
1044     /**
1045      * Create a RenderScript context.
1046      *
1047      * @hide
1048      *
1049      * @param ctx The context.
1050      * @param ct The type of context to be created.
1051      * @return RenderScript
1052      */
create(Context ctx, ContextType ct)1053     public static RenderScript create(Context ctx, ContextType ct) {
1054         int v = ctx.getApplicationInfo().targetSdkVersion;
1055         return create(ctx, v, ct);
1056     }
1057 
1058     /**
1059      * Print the currently available debugging information about the state of
1060      * the RS context to the log.
1061      *
1062      */
contextDump()1063     public void contextDump() {
1064         validate();
1065         nContextDump(0);
1066     }
1067 
1068     /**
1069      * Wait for any pending asynchronous opeations (such as copies to a RS
1070      * allocation or RS script executions) to complete.
1071      *
1072      */
finish()1073     public void finish() {
1074         nContextFinish();
1075     }
1076 
1077     /**
1078      * Destroys this RenderScript context.  Once this function is called,
1079      * using this context or any objects belonging to this context is
1080      * illegal.
1081      *
1082      */
destroy()1083     public void destroy() {
1084         validate();
1085         nContextFinish();
1086         nContextDeinitToClient(mContext);
1087         mMessageThread.mRun = false;
1088         try {
1089             mMessageThread.join();
1090         } catch(InterruptedException e) {
1091         }
1092 
1093         nContextDestroy();
1094         nDeviceDestroy(mDev);
1095         mDev = 0;
1096     }
1097 
isAlive()1098     boolean isAlive() {
1099         return mContext != 0;
1100     }
1101 
safeID(BaseObj o)1102     int safeID(BaseObj o) {
1103         if(o != null) {
1104             return o.getID(this);
1105         }
1106         return 0;
1107     }
1108 }
1109