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