/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.renderscript;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.ArrayList;
import java.nio.ByteBuffer;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Process;
import android.util.Log;
import android.view.Surface;

/**
 * This class provides access to a RenderScript context, which controls RenderScript
 * initialization, resource management, and teardown. An instance of the RenderScript
 * class must be created before any other RS objects can be created.
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For more information about creating an application that uses RenderScript, read the
 * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
 * </div>
 *
 * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
 * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
 * guide</a> for the proposed alternatives.
 **/
@Deprecated
public class RenderScript {
    static final String LOG_TAG = "RenderScript_jni";
    static final boolean DEBUG  = false;
    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
    static final boolean LOG_ENABLED = false;
    static final int SUPPORT_LIB_API = 23;
    static final int SUPPORT_LIB_VERSION = 2301;

    static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
    private boolean mIsProcessContext = false;
    private boolean mEnableMultiInput = false;
    private int mDispatchAPILevel = 0;

    private int mContextFlags = 0;
    private int mContextSdkVersion = 0;

    private Context mApplicationContext;
    private String mNativeLibDir;

    static private String mDenyList = "";
     /**
     * Sets the denylist of Models to only use support lib runtime.
     * Should be used before context create.
     *
     * @param denylist User provided denylist string.
     *
     * Format: "(MANUFACTURER1:PRODUCT1:MODEL1), (MANUFACTURER2:PRODUCT2:MODEL2)..."
     * e.g. : To Denylist Nexus 7(2013) and Nexus 5.
     *        mDenyList = "(asus:razor:Nexus 7), (LGE:hammerhead:Nexus 5)";
     */
    static public void setDenyList(String denyList) {
        if (denyList != null) {
            mDenyList = denyList;
        }
    }
     /**
     * Force using support lib runtime.
     * Should be used before context create.
     *
     */
    static public void forceCompat() {
        sNative = 0;
    }
    /*
     * We use a class initializer to allow the native code to cache some
     * field offsets.
     */
    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
    static boolean sInitialized;
    static boolean sUseGCHooks;
    static Object sRuntime;
    static Method registerNativeAllocation;
    static Method registerNativeFree;

    static Object lock = new Object();

    // Non-threadsafe functions.
    native boolean nLoadSO(boolean useNative, int deviceApi, String libPath);
    native boolean nLoadIOSO();
    native long nDeviceCreate();
    native void nDeviceDestroy(long dev);
    native void nDeviceSetConfig(long dev, int param, int value);
    native int nContextGetUserMessage(long con, int[] data);
    native String nContextGetErrorMessage(long con);
    native int  nContextPeekMessage(long con, int[] subID);
    native void nContextInitToClient(long con);
    native void nContextDeinitToClient(long con);

    static private int sNative = -1;
    static private int sSdkVersion = -1;
    static private boolean useIOlib = false;
    static private boolean useNative;

    /*
     * Context creation flag that specifies a normal context.
     * RenderScript Support lib only support normal context.
     */
    public static final int CREATE_FLAG_NONE = 0x0000;

    int getDispatchAPILevel() {
        return mDispatchAPILevel;
    }

    boolean isUseNative() {
        return useNative;
    }
    /*
     * Detect the bitness of the VM to allow FieldPacker and generated code to do the right thing.
     */
    static native int rsnSystemGetPointerSize();
    static int sPointerSize;
    static public int getPointerSize() {
        // We provide an accessor rather than making the data item public for two reasons.
        // 1) Prevents anyone outside this class from writing the data item.
        // 2) Prevents anyone outside this class from reading the data item unless a class
        //    instance has been created (ensuring the data item has been initialized).
        // DISCLAIMER: Reflection can circumvent these preventive measures.
        synchronized(lock) {
            if (!sInitialized)
                throw new RSInvalidStateException("Calling getPointerSize() before any RenderScript instantiated");
        }
        return sPointerSize;
    }

    /**
     * Determines whether or not we should be thunking into the native
     * RenderScript layer or actually using the compatibility library.
     */
    static private boolean setupNative(int sdkVersion, Context ctx) {
        // if targetSdkVersion is higher than the device api version, always use compat mode.
        // Workaround for KK
        if (android.os.Build.VERSION.SDK_INT < sdkVersion &&
            android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
            sNative = 0;
        }

        if (sNative == -1) {

            // get the value of the debug.rs.forcecompat property
            int forcecompat = 0;
            try {
                Class<?> sysprop = Class.forName("android.os.SystemProperties");
                Class[] signature = {String.class, Integer.TYPE};
                Method getint = sysprop.getDeclaredMethod("getInt", signature);
                Object[] args = {"debug.rs.forcecompat", new Integer(0)};
                forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue();
            } catch (Exception e) {

            }

            if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
                     && forcecompat == 0) {
                sNative = 1;
            } else {
                sNative = 0;
            }


            if (sNative == 1) {
                // Workarounds that may disable thunking go here
                ApplicationInfo info;
                try {
                    info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
                                                                      PackageManager.GET_META_DATA);
                } catch (PackageManager.NameNotFoundException e) {
                    // assume no workarounds needed
                    return true;
                }
                long minorVersion = 0;

                // load minorID from reflection
                try {
                    Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
                    Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
                    minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
                } catch (Exception e) {
                    // minor version remains 0 on devices with no possible WARs
                }

                if (info.metaData != null) {
                    // asynchronous teardown: minor version 1+
                    if (info.metaData.getBoolean("androidx.renderscript.EnableAsyncTeardown") == true) {
                        if (minorVersion == 0) {
                            sNative = 0;
                        }
                    }

                    // blur issues on some drivers with 4.4
                    if (info.metaData.getBoolean("androidx.renderscript.EnableBlurWorkaround") == true) {
                        if (android.os.Build.VERSION.SDK_INT <= 19) {
                            //android.util.Log.e("rs", "war on");
                            sNative = 0;
                        }
                    }
                }
                // end of workarounds
            }
        }

        if (sNative == 1) {
            // check against the denylist
            if (mDenyList.length() > 0) {
                String deviceInfo = '(' +
                                    android.os.Build.MANUFACTURER +
                                    ':' +
                                    android.os.Build.PRODUCT +
                                    ':' +
                                    android.os.Build.MODEL +
                                    ')';
                if (mDenyList.contains(deviceInfo)) {
                    sNative = 0;
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Name of the file that holds the object cache.
     */
    private static final String CACHE_PATH = "com.android.renderscript.cache";
    static String mCachePath;

     /**
     * Sets the directory to use as a persistent storage for the
     * renderscript object file cache.
     *
     * @hide
     * @param cacheDir A directory the current process can write to
     */
    public static void setupDiskCache(File cacheDir) {
        File f = new File(cacheDir, CACHE_PATH);
        mCachePath = f.getAbsolutePath();
        f.mkdirs();
    }

    /**
     * ContextType specifies the specific type of context to be created.
     *
     */
    public enum ContextType {
        /**
         * NORMAL context, this is the default and what shipping apps should
         * use.
         */
        NORMAL (0),

        /**
         * DEBUG context, perform extra runtime checks to validate the
         * kernels and APIs are being used as intended.  Get and SetElementAt
         * will be bounds checked in this mode.
         */
        DEBUG (1),

        /**
         * PROFILE context, Intended to be used once the first time an
         * application is run on a new device.  This mode allows the runtime to
         * do additional testing and performance tuning.
         */
        PROFILE (2);

        int mID;
        ContextType(int id) {
            mID = id;
        }
    }

    ContextType mContextType;
    // Methods below are wrapped to protect the non-threadsafe
    // lockless fifo.

    native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir);
    synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir) {
        return rsnContextCreate(dev, ver, sdkVer, contextType, nativeLibDir);
    }
    native void rsnContextDestroy(long con);
    synchronized void nContextDestroy() {
        validate();

        // take teardown lock
        // teardown lock can only be taken when no objects are being destroyed
        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
        wlock.lock();

        long curCon = mContext;
        // context is considered dead as of this point
        mContext = 0;

        wlock.unlock();
        rsnContextDestroy(curCon);
    }
    native void rsnContextSetPriority(long con, int p);
    synchronized void nContextSetPriority(int p) {
        validate();
        rsnContextSetPriority(mContext, p);
    }
    native void rsnContextDump(long con, int bits);
    synchronized void nContextDump(int bits) {
        validate();
        rsnContextDump(mContext, bits);
    }
    native void rsnContextFinish(long con);
    synchronized void nContextFinish() {
        validate();
        rsnContextFinish(mContext);
    }

    native void rsnContextSendMessage(long con, int id, int[] data);
    synchronized void nContextSendMessage(int id, int[] data) {
        validate();
        rsnContextSendMessage(mContext, id, data);
    }

    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
    native void rsnObjDestroy(long con, long id);
    void nObjDestroy(long id) {
        // There is a race condition here.  The calling code may be run
        // by the gc while teardown is occuring.  This protects againts
        // deleting dead objects.
        if (mContext != 0) {
            rsnObjDestroy(mContext, id);
        }
    }

    native long  rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
        validate();
        return rsnElementCreate(mContext, type, kind, norm, vecSize);
    }
    native long  rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
    synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
        validate();
        return rsnElementCreate2(mContext, elements, names, arraySizes);
    }
    native void rsnElementGetNativeData(long con, long id, int[] elementData);
    synchronized void nElementGetNativeData(long id, int[] elementData) {
        validate();
        rsnElementGetNativeData(mContext, id, elementData);
    }
    native void rsnElementGetSubElements(long con, long id,
                                         long[] IDs, String[] names, int[] arraySizes);
    synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
        validate();
        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
    }

    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
        validate();
        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
    }

    native void rsnTypeGetNativeData(long con, long id, long[] typeData);
    synchronized void nTypeGetNativeData(long id, long[] typeData) {
        validate();
        rsnTypeGetNativeData(mContext, id, typeData);
    }

    native long  rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
    synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
        validate();
        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
    }
    native long  rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
        validate();
        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
    }

    native long  rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
        validate();
        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
    }


    native long  rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
        validate();
        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
    }
    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
        validate();
        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
    }
    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
        validate();
        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
    }

    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
        validate();
        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
    }


    native void rsnAllocationSyncAll(long con, long alloc, int src);
    synchronized void nAllocationSyncAll(long alloc, int src) {
        validate();
        rsnAllocationSyncAll(mContext, alloc, src);
    }

    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
        validate();
        rsnAllocationSetSurface(mContext, alloc, sur);
    }

    native void rsnAllocationIoSend(long con, long alloc);
    synchronized void nAllocationIoSend(long alloc) {
        validate();
        rsnAllocationIoSend(mContext, alloc);
    }
    native void rsnAllocationIoReceive(long con, long alloc);
    synchronized void nAllocationIoReceive(long alloc) {
        validate();
        rsnAllocationIoReceive(mContext, alloc);
    }
    native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ);
    synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, int xBytesSize, int dimY, int dimZ) {
        validate();
        return rsnAllocationGetByteBuffer(mContext, alloc, xBytesSize, dimY, dimZ);
    }
    native long rsnAllocationGetStride(long con, long alloc);
    synchronized long nAllocationGetStride(long alloc) {
        validate();
        return rsnAllocationGetStride(mContext, alloc);
    }

    native void rsnAllocationGenerateMipmaps(long con, long alloc);
    synchronized void nAllocationGenerateMipmaps(long alloc) {
        validate();
        rsnAllocationGenerateMipmaps(mContext, alloc);
    }
    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
        validate();
        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
    }


    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt,
                                    int mSize, boolean usePadding);
    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt,
                                        int mSize, boolean usePadding) {
        validate();
        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
    }

    native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
    synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
        validate();
        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
    }
    /*
    native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes);
    synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) {
        validate();
        rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
    }
    */

    native void rsnAllocationData2D(long con,
                                    long dstAlloc, int dstXoff, int dstYoff,
                                    int dstMip, int dstFace,
                                    int width, int height,
                                    long srcAlloc, int srcXoff, int srcYoff,
                                    int srcMip, int srcFace);
    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
                                        int dstMip, int dstFace,
                                        int width, int height,
                                        long srcAlloc, int srcXoff, int srcYoff,
                                        int srcMip, int srcFace) {
        validate();
        rsnAllocationData2D(mContext,
                            dstAlloc, dstXoff, dstYoff,
                            dstMip, dstFace,
                            width, height,
                            srcAlloc, srcXoff, srcYoff,
                            srcMip, srcFace);
    }

    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
                                    int w, int h, Object d, int sizeBytes, int dt,
                                    int mSize, boolean usePadding);
    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
                                        int mSize, boolean usePadding) {
        validate();
        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
    }

    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
        validate();
        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
    }

    native void rsnAllocationData3D(long con,
                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
                                    int dstMip,
                                    int width, int height, int depth,
                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
                                    int srcMip);
    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
                                        int dstMip,
                                        int width, int height, int depth,
                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
                                        int srcMip) {
        validate();
        rsnAllocationData3D(mContext,
                            dstAlloc, dstXoff, dstYoff, dstZoff,
                            dstMip, width, height, depth,
                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
    }


    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
                                    int mSize, boolean usePadding);
    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
                                        int mSize, boolean usePadding) {
        validate();
        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes,
                            dt.mID, mSize, usePadding);
    }

    native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding);
    synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) {
        validate();
        rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding);
    }

    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
                                    int sizeBytes, int dt, int mSize, boolean usePadding);
    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
                                        int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) {
        validate();
        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
    }

    /*
    native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff,
                                         int mip, int compIdx, byte[] d, int sizeBytes);
    synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff,
                                             int mip, int compIdx, byte[] d, int sizeBytes) {
        validate();
        rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
    }
    */

    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
                                    int w, int h, Object d, int sizeBytes, int dt,
                                    int mSize, boolean usePadding);
    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
                                        int mSize, boolean usePadding) {
        validate();
        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
    }

    /*
    native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip,
                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
                                    int mSize, boolean usePadding);
    synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip,
                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
                                        int mSize, boolean usePadding) {
        validate();
        rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding);
    }
    */

    native long  rsnAllocationGetType(long con, long id);
    synchronized long nAllocationGetType(long id) {
        validate();
        return rsnAllocationGetType(mContext, id);
    }

    native void rsnAllocationResize1D(long con, long id, int dimX);
    synchronized void nAllocationResize1D(long id, int dimX) {
        validate();
        rsnAllocationResize1D(mContext, id, dimX);
    }
    native void rsnAllocationResize2D(long con, long id, int dimX, int dimY);
    synchronized void nAllocationResize2D(long id, int dimX, int dimY) {
        validate();
        rsnAllocationResize2D(mContext, id, dimX, dimY);
    }

    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc);
    synchronized void nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptBindAllocation(curCon, script, alloc, slot, mUseInc);
    }
    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc);
    synchronized void nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetTimeZone(curCon, script, timeZone, mUseInc);
    }
    native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc);
    synchronized void nScriptInvoke(long id, int slot, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptInvoke(curCon, id, slot, mUseInc);
    }
    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc);
    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc);
    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params,
                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout,
                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
    synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc) {
        validate();
        if (params == null) {
            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, mUseInc);
        } else {
            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, params, mUseInc);
        }
    }

    synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
                                            int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc) {
        validate();
        if (params == null) {
            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend, mUseInc);
        } else {
            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend, mUseInc);
        }
    }

    native void rsnScriptForEach(long con, long id, int slot, long[] ains,
                                 long aout, byte[] params, int[] limits);

    synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
                                     byte[] params, int[] limits) {
        if (!mEnableMultiInput) {
            Log.e(LOG_TAG, "Multi-input kernels are not supported, please change targetSdkVersion to >= 23");
            throw new RSRuntimeException("Multi-input kernels are not supported before API 23)");
        }
        validate();
        rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
    }

    native void rsnScriptReduce(long con, long id, int slot, long[] ains,
                                long aout, int[] limits);
    synchronized void nScriptReduce(long id, int slot, long ains[], long aout,
                                    int[] limits) {
        validate();
        rsnScriptReduce(mContext, id, slot, ains, aout, limits);
    }

    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc);
    synchronized void nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptInvokeV(curCon, id, slot, params, mUseInc);
    }
    native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc);
    synchronized void nScriptSetVarI(long id, int slot, int val, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetVarI(curCon, id, slot, val, mUseInc);
    }
    native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc);
    synchronized void nScriptSetVarJ(long id, int slot, long val, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetVarJ(curCon, id, slot, val, mUseInc);
    }
    native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc);
    synchronized void nScriptSetVarF(long id, int slot, float val, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetVarF(curCon, id, slot, val, mUseInc);
    }
    native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc);
    synchronized void nScriptSetVarD(long id, int slot, double val, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetVarD(curCon, id, slot, val, mUseInc);
    }
    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc);
    synchronized void nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetVarV(curCon, id, slot, val, mUseInc);
    }
    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
                                  long e, int[] dims, boolean mUseInc);
    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
                                      long e, int[] dims, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetVarVE(curCon, id, slot, val, e, dims, mUseInc);
    }
    native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc);
    synchronized void nScriptSetVarObj(long id, int slot, long val, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        rsnScriptSetVarObj(curCon, id, slot, val, mUseInc);
    }

    native long  rsnScriptCCreate(long con, String resName, String cacheDir,
                                 byte[] script, int length);
    synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
        validate();
        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
    }

    native long  rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc);
    synchronized long nScriptIntrinsicCreate(int id, long eid, boolean mUseInc) {
        validate();
        if (mUseInc) {
            if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
                Log.e(LOG_TAG, "Incremental Intrinsics are not supported, please change targetSdkVersion to >= 21");
                throw new RSRuntimeException("Incremental Intrinsics are not supported before Lollipop (API 21)");
            }

            if (!mIncLoaded) {
                try {
                    System.loadLibrary("RSSupport");
                } catch (UnsatisfiedLinkError e) {
                    Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e);
                    throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e);
                }
                if (!nIncLoadSO(SUPPORT_LIB_API, mNativeLibDir + "/libRSSupport.so")) {
                    throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support");
                }
                mIncLoaded = true;
            }
            if (mIncCon == 0) {
                //Create a placeholder compat context (synchronous).
                long device = nIncDeviceCreate();
                mIncCon = nIncContextCreate(device, 0, 0, 0);
            }
            return rsnScriptIntrinsicCreate(mIncCon, id, eid, mUseInc);
        } else {
            return rsnScriptIntrinsicCreate(mContext, id, eid, mUseInc);
        }
    }

    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc);
    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        return rsnScriptKernelIDCreate(curCon, sid, slot, sig, mUseInc);
    }

    native long  rsnScriptInvokeIDCreate(long con, long sid, int slot);
    synchronized long nScriptInvokeIDCreate(long sid, int slot) {
        validate();
        return rsnScriptInvokeIDCreate(mContext, sid, slot);
    }

    native long  rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc);
    synchronized long nScriptFieldIDCreate(long sid, int slot, boolean mUseInc) {
        validate();
        long curCon = mContext;
        if (mUseInc) {
            curCon = mIncCon;
        }
        return rsnScriptFieldIDCreate(curCon, sid, slot, mUseInc);
    }

    native long  rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
        validate();
        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
    }

    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
        validate();
        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
    }

    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
        validate();
        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
    }

    native void rsnScriptGroupExecute(long con, long group);
    synchronized void nScriptGroupExecute(long group) {
        validate();
        rsnScriptGroupExecute(mContext, group);
    }

    native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
                                 int wrapS, int wrapT, int wrapR, float aniso);
    synchronized long nSamplerCreate(int magFilter, int minFilter,
                                 int wrapS, int wrapT, int wrapR, float aniso) {
        validate();
        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
    }

// entry points for ScriptGroup2
    native long rsnClosureCreate(long con, long kernelID, long returnValue,
        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
        long[] depFieldIDs);
    synchronized long nClosureCreate(long kernelID, long returnValue,
        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
        long[] depFieldIDs) {
      validate();
      long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
          sizes, depClosures, depFieldIDs);
      if (c == 0) {
          throw new RSRuntimeException("Failed creating closure.");
      }
      return c;
    }

    native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
        long[] fieldIDs, long[] values, int[] sizes);
    synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
        long[] fieldIDs, long[] values, int[] sizes) {
      validate();
      long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
          values, sizes);
      if (c == 0) {
          throw new RSRuntimeException("Failed creating closure.");
      }
      return c;
    }

    native void rsnClosureSetArg(long con, long closureID, int index,
      long value, int size);
    synchronized void nClosureSetArg(long closureID, int index, long value,
        int size) {
      validate();
      rsnClosureSetArg(mContext, closureID, index, value, size);
    }

    native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
        long value, int size);
    // Does this have to be synchronized?
    synchronized void nClosureSetGlobal(long closureID, long fieldID,
        long value, int size) {
      validate(); // TODO: is this necessary?
      rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
    }

    native long rsnScriptGroup2Create(long con, String name, String cachePath,
                                      long[] closures);
    synchronized long nScriptGroup2Create(String name, String cachePath,
                                          long[] closures) {
      validate();
      return rsnScriptGroup2Create(mContext, name, cachePath, closures);
    }

    native void rsnScriptGroup2Execute(long con, long groupID);
    synchronized void nScriptGroup2Execute(long groupID) {
      validate();
      rsnScriptGroup2Execute(mContext, groupID);
    }

    native void rsnScriptIntrinsicBLAS_Single(long con, long incCon, long id, int func, int TransA,
                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                              float alpha, long A, long B, float beta, long C, int incX, int incY,
                                              int KL, int KU, boolean mUseInc);
    synchronized void nScriptIntrinsicBLAS_Single(long id, int func, int TransA,
                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                                  float alpha, long A, long B, float beta, long C, int incX, int incY,
                                                  int KL, int KU, boolean mUseInc) {
        validate();
        rsnScriptIntrinsicBLAS_Single(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
    }

    native void rsnScriptIntrinsicBLAS_Double(long con, long incCon, long id, int func, int TransA,
                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                              double alpha, long A, long B, double beta, long C, int incX, int incY,
                                              int KL, int KU, boolean mUseInc);
    synchronized void nScriptIntrinsicBLAS_Double(long id, int func, int TransA,
                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                                  double alpha, long A, long B, double beta, long C, int incX, int incY,
                                                  int KL, int KU, boolean mUseInc) {
        validate();
        rsnScriptIntrinsicBLAS_Double(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
    }

    native void rsnScriptIntrinsicBLAS_Complex(long con, long incCon, long id, int func, int TransA,
                                               int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                               float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
                                               int KL, int KU, boolean mUseInc);
    synchronized void nScriptIntrinsicBLAS_Complex(long id, int func, int TransA,
                                                   int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                                   float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
                                                   int KL, int KU, boolean mUseInc) {
        validate();
        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);
    }

    native void rsnScriptIntrinsicBLAS_Z(long con, long incCon, long id, int func, int TransA,
                                         int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                         double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
                                         int KL, int KU, boolean mUseInc);
    synchronized void nScriptIntrinsicBLAS_Z(long id, int func, int TransA,
                                             int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
                                             double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
                                             int KL, int KU, boolean mUseInc) {
        validate();
        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);
    }

    native void rsnScriptIntrinsicBLAS_BNNM(long con, long incCon, long id, int M, int N, int K,
                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
                                             int c_mult_int, boolean mUseInc);
    synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K,
                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
                                             int c_mult_int, boolean mUseInc) {
        validate();
        rsnScriptIntrinsicBLAS_BNNM(mContext, mIncCon, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int, mUseInc);
    }

// Additional Entry points For inc libRSSupport

    native boolean nIncLoadSO(int deviceApi, String libPath);
    native long nIncDeviceCreate();
    native void nIncDeviceDestroy(long dev);
    // Methods below are wrapped to protect the non-threadsafe
    // lockless fifo.
    native long  rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType);
    synchronized long nIncContextCreate(long dev, int ver, int sdkVer, int contextType) {
        return rsnIncContextCreate(dev, ver, sdkVer, contextType);
    }
    native void rsnIncContextDestroy(long con);
    synchronized void nIncContextDestroy() {
        validate();

        // take teardown lock
        // teardown lock can only be taken when no objects are being destroyed
        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
        wlock.lock();

        long curCon = mIncCon;
        // context is considered dead as of this point
        mIncCon = 0;

        wlock.unlock();
        rsnIncContextDestroy(curCon);
    }

    native void rsnIncContextFinish(long con);
    synchronized void nIncContextFinish() {
        validate();
        rsnIncContextFinish(mIncCon);
    }

    native void rsnIncObjDestroy(long con, long id);
    void nIncObjDestroy(long id) {
        // There is a race condition here.  The calling code may be run
        // by the gc while teardown is occuring.  This protects againts
        // deleting dead objects.
        if (mIncCon != 0) {
            rsnIncObjDestroy(mIncCon, id);
        }
    }
    native long  rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize);
    synchronized long nIncElementCreate(long type, int kind, boolean norm, int vecSize) {
        validate();
        return rsnIncElementCreate(mIncCon, type, kind, norm, vecSize);
    }
    native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
    synchronized long nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
        validate();
        return rsnIncTypeCreate(mIncCon, eid, x, y, z, mips, faces, yuv);
    }
    native long  rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize);
    synchronized long nIncAllocationCreateTyped(long alloc, long type, int xBytesSize) {
        validate();
        return rsnIncAllocationCreateTyped(mContext, mIncCon, alloc, type, xBytesSize);
    }

    long     mContext;
    private boolean mDestroyed = false;
    //Placeholder device & context for Inc Support Lib
    long     mIncCon;
    //indicator of whether inc support lib has been loaded or not.
    boolean  mIncLoaded;
    ReentrantReadWriteLock mRWLock;
    @SuppressWarnings({"FieldCanBeLocal"})
    MessageThread mMessageThread;

    Element mElement_U8;
    Element mElement_I8;
    Element mElement_U16;
    Element mElement_I16;
    Element mElement_U32;
    Element mElement_I32;
    Element mElement_U64;
    Element mElement_I64;
    Element mElement_F32;
    Element mElement_F64;
    Element mElement_BOOLEAN;

    Element mElement_ELEMENT;
    Element mElement_TYPE;
    Element mElement_ALLOCATION;
    Element mElement_SAMPLER;
    Element mElement_SCRIPT;

    Element mElement_A_8;
    Element mElement_RGB_565;
    Element mElement_RGB_888;
    Element mElement_RGBA_5551;
    Element mElement_RGBA_4444;
    Element mElement_RGBA_8888;

    Element mElement_FLOAT_2;
    Element mElement_FLOAT_3;
    Element mElement_FLOAT_4;

    Element mElement_DOUBLE_2;
    Element mElement_DOUBLE_3;
    Element mElement_DOUBLE_4;

    Element mElement_UCHAR_2;
    Element mElement_UCHAR_3;
    Element mElement_UCHAR_4;

    Element mElement_CHAR_2;
    Element mElement_CHAR_3;
    Element mElement_CHAR_4;

    Element mElement_USHORT_2;
    Element mElement_USHORT_3;
    Element mElement_USHORT_4;

    Element mElement_SHORT_2;
    Element mElement_SHORT_3;
    Element mElement_SHORT_4;

    Element mElement_UINT_2;
    Element mElement_UINT_3;
    Element mElement_UINT_4;

    Element mElement_INT_2;
    Element mElement_INT_3;
    Element mElement_INT_4;

    Element mElement_ULONG_2;
    Element mElement_ULONG_3;
    Element mElement_ULONG_4;

    Element mElement_LONG_2;
    Element mElement_LONG_3;
    Element mElement_LONG_4;

    Element mElement_MATRIX_4X4;
    Element mElement_MATRIX_3X3;
    Element mElement_MATRIX_2X2;

    Sampler mSampler_CLAMP_NEAREST;
    Sampler mSampler_CLAMP_LINEAR;
    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
    Sampler mSampler_WRAP_NEAREST;
    Sampler mSampler_WRAP_LINEAR;
    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;


    ///////////////////////////////////////////////////////////////////////////////////
    //

    /**
     * The base class from which an application should derive in order
     * to receive RS messages from scripts. When a script calls {@code
     * rsSendToClient}, the data fields will be filled, and the run
     * method will be called on a separate thread.  This will occur
     * some time after {@code rsSendToClient} completes in the script,
     * as {@code rsSendToClient} is asynchronous. Message handlers are
     * not guaranteed to have completed when {@link
     * androidx.renderscript.RenderScript#finish} returns.
     *
     */
    public static class RSMessageHandler implements Runnable {
        protected int[] mData;
        protected int mID;
        protected int mLength;
        public void run() {
        }
    }
    /**
     * If an application is expecting messages, it should set this
     * field to an instance of {@link RSMessageHandler}.  This
     * instance will receive all the user messages sent from {@code
     * sendToClient} by scripts from this context.
     *
     */
    RSMessageHandler mMessageCallback = null;

    public void setMessageHandler(RSMessageHandler msg) {
        mMessageCallback = msg;
    }
    public RSMessageHandler getMessageHandler() {
        return mMessageCallback;
    }

    /**
     * Place a message into the message queue to be sent back to the message
     * handler once all previous commands have been executed.
     *
     * @param id
     * @param data
     */
    public void sendMessage(int id, int[] data) {
        nContextSendMessage(id, data);
    }

    /**
     * The runtime error handler base class.  An application should derive from this class
     * if it wishes to install an error handler.  When errors occur at runtime,
     * the fields in this class will be filled, and the run method will be called.
     *
     */
    public static class RSErrorHandler implements Runnable {
        protected String mErrorMessage;
        protected int mErrorNum;
        public void run() {
        }
    }

    /**
     * Application Error handler.  All runtime errors will be dispatched to the
     * instance of RSAsyncError set here.  If this field is null a
     * {@link RSRuntimeException} will instead be thrown with details about the error.
     * This will cause program termaination.
     *
     */
    RSErrorHandler mErrorCallback = null;

    public void setErrorHandler(RSErrorHandler msg) {
        mErrorCallback = msg;
    }
    public RSErrorHandler getErrorHandler() {
        return mErrorCallback;
    }

    /**
     * RenderScript worker thread priority enumeration.  The default value is
     * NORMAL.  Applications wishing to do background processing should set
     * their priority to LOW to avoid starving forground processes.
     */
    public enum Priority {
        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
        NORMAL (Process.THREAD_PRIORITY_DISPLAY);

        int mID;
        Priority(int id) {
            mID = id;
        }
    }

    void validateObject(BaseObj o) {
        if (o != null) {
            if (o.mRS != this) {
                throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
            }
        }
    }

    void validate() {
        if (mContext == 0) {
            throw new RSInvalidStateException("Calling RS with no Context active.");
        }
    }

    /**
     * check if IO support lib is available.
     */
    boolean usingIO() {
        return useIOlib;
    }
    /**
     * Change the priority of the worker threads for this context.
     *
     * @param p New priority to be set.
     */
    public void setPriority(Priority p) {
        validate();
        nContextSetPriority(p.mID);
    }

    static class MessageThread extends Thread {
        RenderScript mRS;
        boolean mRun = true;
        int[] mAuxData = new int[2];

        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;

        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
        static final int RS_ERROR_FATAL_DEBUG = 0x800;
        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;

        MessageThread(RenderScript rs) {
            super("RSMessageThread");
            mRS = rs;

        }

        public void run() {
            // This function is a temporary solution.  The final solution will
            // used typed allocations where the message id is the type indicator.
            int[] rbuf = new int[16];
            mRS.nContextInitToClient(mRS.mContext);
            while(mRun) {
                rbuf[0] = 0;
                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
                int size = mAuxData[1];
                int subID = mAuxData[0];

                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
                    if ((size>>2) >= rbuf.length) {
                        rbuf = new int[(size + 3) >> 2];
                    }
                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
                        RS_MESSAGE_TO_CLIENT_USER) {
                        throw new RSDriverException("Error processing message from RenderScript.");
                    }

                    if(mRS.mMessageCallback != null) {
                        mRS.mMessageCallback.mData = rbuf;
                        mRS.mMessageCallback.mID = subID;
                        mRS.mMessageCallback.mLength = size;
                        mRS.mMessageCallback.run();
                    } else {
                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
                    }
                    continue;
                }

                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
                    String e = mRS.nContextGetErrorMessage(mRS.mContext);

                    // Copied from java/android/renderscript/RenderScript.java
                    // Throw RSRuntimeException under the following conditions:
                    //
                    // 1) It is an unknown fatal error.
                    // 2) It is a debug fatal error, and we are not in a
                    //    debug context.
                    // 3) It is a debug fatal error, and we do not have an
                    //    error callback.
                    if (subID >= RS_ERROR_FATAL_UNKNOWN ||
                        (subID >= RS_ERROR_FATAL_DEBUG &&
                         (mRS.mContextType != ContextType.DEBUG ||
                          mRS.mErrorCallback == null))) {
                        android.util.Log.e(LOG_TAG, "fatal RS error, " + e);
                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
                    }

                    if(mRS.mErrorCallback != null) {
                        mRS.mErrorCallback.mErrorMessage = e;
                        mRS.mErrorCallback.mErrorNum = subID;
                        mRS.mErrorCallback.run();
                    } else {
                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
                        // Do not throw here. In these cases, we do not have
                        // a fatal error.
                    }
                    continue;
                }

                // 2: teardown.
                // But we want to avoid starving other threads during
                // teardown by yielding until the next line in the destructor
                // can execute to set mRun = false
                try {
                    sleep(1, 0);
                } catch(InterruptedException e) {
                }
            }
            //Log.d(LOG_TAG, "MessageThread exiting.");
        }
    }

    RenderScript(Context ctx) {
        mContextType = ContextType.NORMAL;
        if (ctx != null) {
            mApplicationContext = ctx.getApplicationContext();
            // Only set mNativeLibDir for API 9+.
            mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
        }
        mIncCon = 0;
        mIncLoaded = false;
        mRWLock = new ReentrantReadWriteLock();
    }

    /**
     * Gets the application context associated with the RenderScript context.
     *
     * @return The application context.
     */
    public final Context getApplicationContext() {
        return mApplicationContext;
    }

    /**
     * Create a RenderScript context.
     *
     * @param ctx The context.
     * @return RenderScript
     */
    private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) {
        RenderScript rs = new RenderScript(ctx);

        if (sSdkVersion == -1) {
            sSdkVersion = sdkVersion;
        } else if (sSdkVersion != sdkVersion) {
            throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
        }
        useNative = setupNative(sSdkVersion, ctx);
        synchronized(lock) {
            if (sInitialized == false) {
                try {
                    Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
                    Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
                    sRuntime = get_runtime.invoke(null);
                    Class<?> argClass = android.os.Build.VERSION.SDK_INT >= 29 ? Long.TYPE : Integer.TYPE;
                    // The int version is (so far) always defined, but deprecated for APIs >= 29.
                    registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", argClass);
                    registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", argClass);
                    sUseGCHooks = true;
                } catch (Exception e) {
                    Log.e(LOG_TAG, "No GC methods");
                    sUseGCHooks = false;
                }
                try {
                    // For API 9 - 22, always use the absolute path of librsjni.so
                    // http://b/25226912
                    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
                        rs.mNativeLibDir != null) {
                        System.load(rs.mNativeLibDir + "/librsjni.so");
                    } else {
                        System.loadLibrary("rsjni");
                    }
                    sInitialized = true;
                    sPointerSize = rsnSystemGetPointerSize();
                } catch (UnsatisfiedLinkError e) {
                    Log.e(LOG_TAG, "Error loading RS jni library: " + e);
                    throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION);
                }
            }
        }

        if (useNative) {
            android.util.Log.v(LOG_TAG, "RS native mode");
        } else {
            android.util.Log.v(LOG_TAG, "RS compat mode");
        }

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            useIOlib = true;
        }

        // The target API level used to init dispatchTable.
        int dispatchAPI = sdkVersion;
        if (sdkVersion < android.os.Build.VERSION.SDK_INT) {
            // If the device API is higher than target API level, init dispatch table based on device API.
            dispatchAPI = android.os.Build.VERSION.SDK_INT;
        }

        String rssupportPath = null;
        // For API 9 - 22, always use the absolute path of libRSSupport.so
        // http://b/25226912
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
            rs.mNativeLibDir != null) {
            rssupportPath = rs.mNativeLibDir + "/libRSSupport.so";
        }
        if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) {
            if (useNative) {
                android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode");
                useNative = false;
            }
            try {
                if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
                    rs.mNativeLibDir != null) {
                    System.load(rssupportPath);
                } else {
                    System.loadLibrary("RSSupport");
                }
            } catch (UnsatisfiedLinkError e) {
                Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
                throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
            }
            if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) {
                Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION);
                throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION);
            }
        }

        if (useIOlib) {
            try {
                System.loadLibrary("RSSupportIO");
            } catch (UnsatisfiedLinkError e) {
                useIOlib = false;
            }
            if (!useIOlib || !rs.nLoadIOSO()) {
                android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported");
                useIOlib = false;
            }
        }

        // For old APIs with dlopen bug, need to load blas lib in Java first.
        // Only try load to blasV8 when the desired API level includes IntrinsicBLAS.
        if (dispatchAPI >= 23) {
            // Enable multi-input kernels only when diapatchAPI is M+.
            rs.mEnableMultiInput = true;
            try {
                System.loadLibrary("blasV8");
            } catch (UnsatisfiedLinkError e) {
                Log.v(LOG_TAG, "Unable to load BLAS lib, ONLY BNNM will be supported: " + e);
            }
        }

        long device = rs.nDeviceCreate();
        rs.mContext = rs.nContextCreate(device, 0, sdkVersion, ct.mID, rs.mNativeLibDir);
        rs.mContextType = ct;
        rs.mContextFlags = flags;
        rs.mContextSdkVersion = sdkVersion;
        rs.mDispatchAPILevel = dispatchAPI;
        if (rs.mContext == 0) {
            throw new RSDriverException("Failed to create RS context.");
        }
        rs.mMessageThread = new MessageThread(rs);
        rs.mMessageThread.start();
        return rs;
    }

    /**
     * Create a RenderScript context.
     *
     * See documentation for @create for details
     *
     * @param ctx The context.
     * @return RenderScript
     */
    public static RenderScript create(Context ctx) {
        return create(ctx, ContextType.NORMAL);
    }

    /**
     * calls create(ctx, ct, CREATE_FLAG_NONE)
     *
     * See documentation for @create for details
     *
     * @param ctx The context.
     * @param ct The type of context to be created.
     * @return RenderScript
     */
    public static RenderScript create(Context ctx, ContextType ct) {
        return create(ctx, ct, CREATE_FLAG_NONE);
    }

    /**
     * Gets or creates a RenderScript context of the specified type.
     *
     * The returned context will be cached for future reuse within
     * the process. When an application is finished using
     * RenderScript it should call releaseAllContexts()
     *
     * A process context is a context designed for easy creation and
     * lifecycle management.  Multiple calls to this function will
     * return the same object provided they are called with the same
     * options.  This allows it to be used any time a RenderScript
     * context is needed.
     *
     *
     * @param ctx The context.
     * @param ct The type of context to be created.
     * @param flags The OR of the CREATE_FLAG_* options desired
     * @return RenderScript
     */
    public static RenderScript create(Context ctx, ContextType ct, int flags) {
        int v = ctx.getApplicationInfo().targetSdkVersion;
        return create(ctx, v, ct, flags);
    }

    /**
     * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE)
     *
     * Used by the RenderScriptThunker to maintain backward compatibility.
     *
     * @hide
     * @param ctx The context.
     * @param sdkVersion The target SDK Version.
     * @return RenderScript
     */
    public static RenderScript create(Context ctx, int sdkVersion) {
        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
    }


    /**
     * calls create(ctx, sdkVersion, ct, CREATE_FLAG_NONE)
     * Create a RenderScript context.
     *
     * @hide
     * @param ctx The context.
     * @return RenderScript
     */
    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
        return create(ctx, sdkVersion, ct, CREATE_FLAG_NONE);
    }

     /**
     * Gets or creates a RenderScript context of the specified type.
     *
     * @param ctx The context.
     * @param ct The type of context to be created.
     * @param sdkVersion The target SDK Version.
     * @param flags The OR of the CREATE_FLAG_* options desired
     * @return RenderScript
     */
    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
        synchronized (mProcessContextList) {
            for (RenderScript prs : mProcessContextList) {
                if ((prs.mContextType == ct) &&
                    (prs.mContextFlags == flags) &&
                    (prs.mContextSdkVersion == sdkVersion)) {

                    return prs;
                }
            }

            RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags);
            prs.mIsProcessContext = true;
            mProcessContextList.add(prs);
            return prs;
        }
    }

    /**
     *
     * Releases all the process contexts.  This is the same as
     * calling .destroy() on each unique context retreived with
     * create(...). If no contexts have been created this
     * function does nothing.
     *
     * Typically you call this when your application is losing focus
     * and will not be using a context for some time.
     *
     * This has no effect on a context created with
     * createMultiContext()
     */
    public static void releaseAllContexts() {
        ArrayList<RenderScript> oldList;
        synchronized (mProcessContextList) {
            oldList = mProcessContextList;
            mProcessContextList = new ArrayList<RenderScript>();
        }

        for (RenderScript prs : oldList) {
            prs.mIsProcessContext = false;
            prs.destroy();
        }
        oldList.clear();
    }



    /**
     * Create a RenderScript context.
     *
     * This is an advanced function intended for applications which
     * need to create more than one RenderScript context to be used
     * at the same time.
     *
     * If you need a single context please use create()
     *
     * @param ctx The context.
     * @return RenderScript
     */
    public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) {
        return internalCreate(ctx, API_number, ct, flags);
    }

    /**
     * Print the currently available debugging information about the state of
     * the RS context to the log.
     *
     */
    public void contextDump() {
        validate();
        nContextDump(0);
    }

    /**
     * Wait for any pending asynchronous opeations (such as copies to a RS
     * allocation or RS script executions) to complete.
     *
     */
    public void finish() {
        nContextFinish();
    }

    private void helpDestroy() {
        boolean shouldDestroy = false;
        synchronized(this) {
            if (!mDestroyed) {
                shouldDestroy = true;
                mDestroyed = true;
            }
        }

        if (shouldDestroy) {
            nContextFinish();
            if (mIncCon != 0) {
                nIncContextFinish();
                nIncContextDestroy();
                mIncCon = 0;
            }
            nContextDeinitToClient(mContext);
            mMessageThread.mRun = false;
            // Interrupt mMessageThread so it gets to see immediately that mRun is false
            // and exit rightaway.
            mMessageThread.interrupt();

            // Wait for mMessageThread to join.  Try in a loop, in case this thread gets interrupted
            // during the wait.  If interrupted, set the "interrupted" status of the current thread.
            boolean hasJoined = false, interrupted = false;
            while (!hasJoined) {
                try {
                    mMessageThread.join();
                    hasJoined = true;
                } catch (InterruptedException e) {
                    interrupted = true;
                }
            }
            if (interrupted) {
                Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join");
                Thread.currentThread().interrupt();
            }

            nContextDestroy();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        helpDestroy();
        super.finalize();
    }

    /**
     * Destroys this RenderScript context.  Once this function is called,
     * using this context or any objects belonging to this context is
     * illegal.
     *
     * This function is a NOP if the context was created
     * with create().  Please use releaseAllContexts() to clean up
     * contexts created with the create function.
     */
    public void destroy() {
        if (mIsProcessContext) {
            // users cannot destroy a process context
            return;
        }
        validate();
        helpDestroy();
    }

    boolean isAlive() {
        return mContext != 0;
    }

    long safeID(BaseObj o) {
        if(o != null) {
            return o.getID(this);
        }
        return 0;
    }
}
