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