Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2011-2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "libRS_jni"
     18 
     19 #include <stdlib.h>
     20 #include <stdio.h>
     21 #include <fcntl.h>
     22 #include <unistd.h>
     23 #include <math.h>
     24 #include <android/bitmap.h>
     25 #include <android/log.h>
     26 
     27 #include <rsEnv.h>
     28 #include "rsDispatch.h"
     29 #include <dlfcn.h>
     30 
     31 //#define LOG_API ALOG
     32 #define LOG_API(...)
     33 
     34 #define NELEM(m) (sizeof(m) / sizeof((m)[0]))
     35 
     36 template <typename... T>
     37 void UNUSED(T... t) {}
     38 #define PER_ARRAY_TYPE(flag, fnc, readonly, ...) {                                      \
     39     jint len = 0;                                                                       \
     40     void *ptr = nullptr;                                                                \
     41     void *srcPtr = nullptr;                                                             \
     42     size_t typeBytes = 0;                                                               \
     43     jint relFlag = 0;                                                                   \
     44     if (readonly) {                                                                     \
     45         /* The on-release mode should only be JNI_ABORT for read-only accesses. */      \
     46         /* readonly = true, also indicates we are copying to the allocation   . */      \
     47         relFlag = JNI_ABORT;                                                            \
     48     }                                                                                   \
     49     switch(dataType) {                                                                  \
     50     case RS_TYPE_FLOAT_32:                                                              \
     51         len = _env->GetArrayLength((jfloatArray)data);                                  \
     52         ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
     53         typeBytes = 4;                                                                  \
     54         if (usePadding) {                                                               \
     55             srcPtr = ptr;                                                               \
     56             len = len / 3 * 4;                                                          \
     57             if (count == 0) {                                                           \
     58                 count = len / 4;                                                        \
     59             }                                                                           \
     60             ptr = malloc (len * typeBytes);                                             \
     61             if (readonly) {                                                             \
     62                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
     63                 fnc(__VA_ARGS__);                                                       \
     64             } else {                                                                    \
     65                 fnc(__VA_ARGS__);                                                       \
     66                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
     67             }                                                                           \
     68             free(ptr);                                                                  \
     69             ptr = srcPtr;                                                               \
     70         } else {                                                                        \
     71             fnc(__VA_ARGS__);                                                           \
     72         }                                                                               \
     73         _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag);     \
     74         return;                                                                         \
     75     case RS_TYPE_FLOAT_64:                                                              \
     76         len = _env->GetArrayLength((jdoubleArray)data);                                 \
     77         ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
     78         typeBytes = 8;                                                                  \
     79         if (usePadding) {                                                               \
     80             srcPtr = ptr;                                                               \
     81             len = len / 3 * 4;                                                          \
     82             if (count == 0) {                                                           \
     83                 count = len / 4;                                                        \
     84             }                                                                           \
     85             ptr = malloc (len * typeBytes);                                             \
     86             if (readonly) {                                                             \
     87                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
     88                 fnc(__VA_ARGS__);                                                       \
     89             } else {                                                                    \
     90                 fnc(__VA_ARGS__);                                                       \
     91                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
     92             }                                                                           \
     93             free(ptr);                                                                  \
     94             ptr = srcPtr;                                                               \
     95         } else {                                                                        \
     96             fnc(__VA_ARGS__);                                                           \
     97         }                                                                               \
     98         _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag);  \
     99         return;                                                                         \
    100     case RS_TYPE_SIGNED_8:                                                              \
    101     case RS_TYPE_UNSIGNED_8:                                                            \
    102         len = _env->GetArrayLength((jbyteArray)data);                                   \
    103         ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
    104         typeBytes = 1;                                                                  \
    105         if (usePadding) {                                                               \
    106             srcPtr = ptr;                                                               \
    107             len = len / 3 * 4;                                                          \
    108             if (count == 0) {                                                           \
    109                 count = len / 4;                                                        \
    110             }                                                                           \
    111             ptr = malloc (len * typeBytes);                                             \
    112             if (readonly) {                                                             \
    113                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    114                 fnc(__VA_ARGS__);                                                       \
    115             } else {                                                                    \
    116                 fnc(__VA_ARGS__);                                                       \
    117                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    118             }                                                                           \
    119             free(ptr);                                                                  \
    120             ptr = srcPtr;                                                               \
    121         } else {                                                                        \
    122             fnc(__VA_ARGS__);                                                           \
    123         }                                                                               \
    124         _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag);         \
    125         return;                                                                         \
    126     case RS_TYPE_SIGNED_16:                                                             \
    127     case RS_TYPE_UNSIGNED_16:                                                           \
    128         len = _env->GetArrayLength((jshortArray)data);                                  \
    129         ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
    130         typeBytes = 2;                                                                  \
    131         if (usePadding) {                                                               \
    132             srcPtr = ptr;                                                               \
    133             len = len / 3 * 4;                                                          \
    134             if (count == 0) {                                                           \
    135                 count = len / 4;                                                        \
    136             }                                                                           \
    137             ptr = malloc (len * typeBytes);                                             \
    138             if (readonly) {                                                             \
    139                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    140                 fnc(__VA_ARGS__);                                                       \
    141             } else {                                                                    \
    142                 fnc(__VA_ARGS__);                                                       \
    143                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    144             }                                                                           \
    145             free(ptr);                                                                  \
    146             ptr = srcPtr;                                                               \
    147         } else {                                                                        \
    148             fnc(__VA_ARGS__);                                                           \
    149         }                                                                               \
    150         _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag);     \
    151         return;                                                                         \
    152     case RS_TYPE_SIGNED_32:                                                             \
    153     case RS_TYPE_UNSIGNED_32:                                                           \
    154         len = _env->GetArrayLength((jintArray)data);                                    \
    155         ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
    156         typeBytes = 4;                                                                  \
    157         if (usePadding) {                                                               \
    158             srcPtr = ptr;                                                               \
    159             len = len / 3 * 4;                                                          \
    160             if (count == 0) {                                                           \
    161                 count = len / 4;                                                        \
    162             }                                                                           \
    163             ptr = malloc (len * typeBytes);                                             \
    164             if (readonly) {                                                             \
    165                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    166                 fnc(__VA_ARGS__);                                                       \
    167             } else {                                                                    \
    168                 fnc(__VA_ARGS__);                                                       \
    169                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    170             }                                                                           \
    171             free(ptr);                                                                  \
    172             ptr = srcPtr;                                                               \
    173         } else {                                                                        \
    174             fnc(__VA_ARGS__);                                                           \
    175         }                                                                               \
    176         _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag);           \
    177         return;                                                                         \
    178     case RS_TYPE_SIGNED_64:                                                             \
    179     case RS_TYPE_UNSIGNED_64:                                                           \
    180         len = _env->GetArrayLength((jlongArray)data);                                   \
    181         ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
    182         typeBytes = 8;                                                                  \
    183         if (usePadding) {                                                               \
    184             srcPtr = ptr;                                                               \
    185             len = len / 3 * 4;                                                          \
    186             if (count == 0) {                                                           \
    187                 count = len / 4;                                                        \
    188             }                                                                           \
    189             ptr = malloc (len * typeBytes);                                             \
    190             if (readonly) {                                                             \
    191                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    192                 fnc(__VA_ARGS__);                                                       \
    193             } else {                                                                    \
    194                 fnc(__VA_ARGS__);                                                       \
    195                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    196             }                                                                           \
    197             free(ptr);                                                                  \
    198             ptr = srcPtr;                                                               \
    199         } else {                                                                        \
    200             fnc(__VA_ARGS__);                                                           \
    201         }                                                                               \
    202         _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag);        \
    203         return;                                                                         \
    204     default:                                                                            \
    205         break;                                                                          \
    206     }                                                                                   \
    207     UNUSED(len, ptr, srcPtr, typeBytes, relFlag);                                       \
    208 }
    209 
    210 
    211 class AutoJavaStringToUTF8 {
    212 public:
    213     AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
    214         fCStr = env->GetStringUTFChars(str, NULL);
    215         fLength = env->GetStringUTFLength(str);
    216     }
    217     ~AutoJavaStringToUTF8() {
    218         fEnv->ReleaseStringUTFChars(fJStr, fCStr);
    219     }
    220     const char* c_str() const { return fCStr; }
    221     jsize length() const { return fLength; }
    222 
    223 private:
    224     JNIEnv*     fEnv;
    225     jstring     fJStr;
    226     const char* fCStr;
    227     jsize       fLength;
    228 };
    229 
    230 class AutoJavaStringArrayToUTF8 {
    231 public:
    232     AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
    233     : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
    234         mCStrings = NULL;
    235         mSizeArray = NULL;
    236         if (stringsLength > 0) {
    237             mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
    238             mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
    239             for (jsize ct = 0; ct < stringsLength; ct ++) {
    240                 jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
    241                 mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
    242                 mSizeArray[ct] = mEnv->GetStringUTFLength(s);
    243             }
    244         }
    245     }
    246     ~AutoJavaStringArrayToUTF8() {
    247         for (jsize ct=0; ct < mStringsLength; ct++) {
    248             jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
    249             mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
    250         }
    251         free(mCStrings);
    252         free(mSizeArray);
    253     }
    254     const char **c_str() const { return mCStrings; }
    255     size_t *c_str_len() const { return mSizeArray; }
    256     jsize length() const { return mStringsLength; }
    257 
    258 private:
    259     JNIEnv      *mEnv;
    260     jobjectArray mStrings;
    261     const char **mCStrings;
    262     size_t      *mSizeArray;
    263     jsize        mStringsLength;
    264 };
    265 
    266 
    267 // ---------------------------------------------------------------------------
    268 static dispatchTable dispatchTab;
    269 // Incremental Support lib
    270 static dispatchTable dispatchTabInc;
    271 
    272 static jboolean nLoadSO(JNIEnv *_env, jobject _this, jboolean useNative, jint targetApi) {
    273     void* handle = NULL;
    274     if (useNative) {
    275         handle = dlopen("libRS.so", RTLD_LAZY | RTLD_LOCAL);
    276     } else {
    277         handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
    278     }
    279     if (handle == NULL) {
    280         LOG_API("couldn't dlopen %s, %s", filename, dlerror());
    281         return false;
    282     }
    283 
    284     if (loadSymbols(handle, dispatchTab, targetApi) == false) {
    285         LOG_API("%s init failed!", filename);
    286         return false;
    287     }
    288     LOG_API("Successfully loaded %s", filename);
    289     return true;
    290 }
    291 
    292 static ioSuppDT ioDispatch;
    293 static jboolean nLoadIOSO(JNIEnv *_env, jobject _this) {
    294     void* handleIO = NULL;
    295     handleIO = dlopen("libRSSupportIO.so", RTLD_LAZY | RTLD_LOCAL);
    296     if (handleIO == NULL) {
    297         LOG_API("Couldn't load libRSSupportIO.so");
    298         return false;
    299     }
    300     if (loadIOSuppSyms(handleIO, ioDispatch) == false) {
    301         LOG_API("libRSSupportIO init failed!");
    302         return false;
    303     }
    304     return true;
    305 }
    306 
    307 // ---------------------------------------------------------------------------
    308 
    309 static void copyWithPadding(void* ptr, void* srcPtr, int mSize, int count) {
    310     int sizeBytesPad = mSize * 4;
    311     int sizeBytes = mSize * 3;
    312     uint8_t *dst = static_cast<uint8_t *>(ptr);
    313     uint8_t *src = static_cast<uint8_t *>(srcPtr);
    314     for (int i = 0; i < count; i++) {
    315         memcpy(dst, src, sizeBytes);
    316         dst += sizeBytesPad;
    317         src += sizeBytes;
    318     }
    319 }
    320 
    321 static void copyWithUnPadding(void* ptr, void* srcPtr, int mSize, int count) {
    322     int sizeBytesPad = mSize * 4;
    323     int sizeBytes = mSize * 3;
    324     uint8_t *dst = static_cast<uint8_t *>(ptr);
    325     uint8_t *src = static_cast<uint8_t *>(srcPtr);
    326     for (int i = 0; i < count; i++) {
    327         memcpy(dst, src, sizeBytes);
    328         dst += sizeBytes;
    329         src += sizeBytesPad;
    330     }
    331 }
    332 
    333 
    334 // ---------------------------------------------------------------------------
    335 
    336 static void
    337 nContextFinish(JNIEnv *_env, jobject _this, jlong con)
    338 {
    339     LOG_API("nContextFinish, con(%p)", (RsContext)con);
    340     dispatchTab.ContextFinish((RsContext)con);
    341 }
    342 
    343 static jlong
    344 nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
    345                jlong returnValue, jlongArray fieldIDArray,
    346                jlongArray valueArray, jintArray sizeArray,
    347                jlongArray depClosureArray, jlongArray depFieldIDArray) {
    348   jlong ret = 0;
    349 
    350   jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
    351   jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
    352   jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
    353   jsize values_length = _env->GetArrayLength(valueArray);
    354   jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
    355   jsize sizes_length = _env->GetArrayLength(sizeArray);
    356   jlong* jDepClosures =
    357       _env->GetLongArrayElements(depClosureArray, nullptr);
    358   jsize depClosures_length = _env->GetArrayLength(depClosureArray);
    359   jlong* jDepFieldIDs =
    360       _env->GetLongArrayElements(depFieldIDArray, nullptr);
    361   jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
    362 
    363   size_t numValues, numDependencies;
    364   RsScriptFieldID* fieldIDs;
    365   uintptr_t* values;
    366   RsClosure* depClosures;
    367   RsScriptFieldID* depFieldIDs;
    368 
    369   if (fieldIDs_length != values_length || values_length != sizes_length) {
    370       LOG_API("Unmatched field IDs, values, and sizes in closure creation.");
    371       goto exit;
    372   }
    373 
    374   numValues = (size_t)fieldIDs_length;
    375 
    376   if (depClosures_length != depFieldIDs_length) {
    377       LOG_API("Unmatched closures and field IDs for dependencies in closure creation.");
    378       goto exit;
    379   }
    380 
    381   numDependencies = (size_t)depClosures_length;
    382 
    383   if (numDependencies > numValues) {
    384       LOG_API("Unexpected number of dependencies in closure creation");
    385       goto exit;
    386   }
    387 
    388   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
    389       LOG_API("Too many arguments or globals in closure creation");
    390       goto exit;
    391   }
    392 
    393   fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
    394   if (fieldIDs == nullptr) {
    395       goto exit;
    396   }
    397 
    398   for (size_t i = 0; i < numValues; i++) {
    399     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
    400   }
    401 
    402   values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues);
    403   if (values == nullptr) {
    404       goto exit;
    405   }
    406 
    407   for (size_t i = 0; i < numValues; i++) {
    408     values[i] = (uintptr_t)jValues[i];
    409   }
    410 
    411   depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies);
    412   if (depClosures == nullptr) {
    413       goto exit;
    414   }
    415 
    416   for (size_t i = 0; i < numDependencies; i++) {
    417     depClosures[i] = (RsClosure)jDepClosures[i];
    418   }
    419 
    420   depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies);
    421   if (depFieldIDs == nullptr) {
    422       goto exit;
    423   }
    424 
    425   for (size_t i = 0; i < numDependencies; i++) {
    426     depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
    427   }
    428 
    429   ret = (jlong)(uintptr_t)dispatchTab.ClosureCreate(
    430       (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
    431       fieldIDs, numValues, values, numValues,
    432       (int*)jSizes, numValues,
    433       depClosures, numDependencies,
    434       depFieldIDs, numDependencies);
    435 
    436 exit:
    437 
    438   _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT);
    439   _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT);
    440   _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
    441   _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
    442   _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
    443 
    444   return ret;
    445 }
    446 
    447 static jlong
    448 nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
    449                      jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
    450                      jintArray sizeArray) {
    451   jlong ret = 0;
    452 
    453   jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
    454   jsize jParamLength = _env->GetArrayLength(paramArray);
    455   jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
    456   jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
    457   jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
    458   jsize values_length = _env->GetArrayLength(valueArray);
    459   jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
    460   jsize sizes_length = _env->GetArrayLength(sizeArray);
    461 
    462   size_t numValues;
    463   RsScriptFieldID* fieldIDs;
    464   uintptr_t* values;
    465 
    466   if (fieldIDs_length != values_length || values_length != sizes_length) {
    467       LOG_API("Unmatched field IDs, values, and sizes in closure creation.");
    468       goto exit;
    469   }
    470 
    471   numValues = (size_t) fieldIDs_length;
    472 
    473   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
    474       LOG_API("Too many arguments or globals in closure creation");
    475       goto exit;
    476   }
    477 
    478   fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
    479   if (fieldIDs == nullptr) {
    480       goto exit;
    481   }
    482 
    483   for (size_t i = 0; i < numValues; i++) {
    484     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
    485   }
    486 
    487   values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues);
    488   if (values == nullptr) {
    489       goto exit;
    490   }
    491 
    492   for (size_t i = 0; i < numValues; i++) {
    493     values[i] = (uintptr_t)jValues[i];
    494   }
    495 
    496   ret = (jlong)(uintptr_t)dispatchTab.InvokeClosureCreate(
    497       (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
    498       fieldIDs, numValues, values, numValues,
    499       (int*)jSizes, numValues);
    500 
    501 exit:
    502 
    503   _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
    504   _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
    505   _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
    506   _env->ReleaseByteArrayElements(paramArray,      jParams,      JNI_ABORT);
    507 
    508   return ret;
    509 }
    510 
    511 static void
    512 nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
    513                jint index, jlong value, jint size) {
    514   dispatchTab.ClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
    515                   (uintptr_t)value, (size_t)size);
    516 }
    517 
    518 static void
    519 nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
    520                   jlong fieldID, jlong value, jint size) {
    521   dispatchTab.ClosureSetGlobal((RsContext)con, (RsClosure)closureID,
    522                      (RsScriptFieldID)fieldID, (uintptr_t)value, (size_t)size);
    523 }
    524 
    525 static long
    526 nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name,
    527                     jstring cacheDir, jlongArray closureArray) {
    528   jlong ret = 0;
    529 
    530   AutoJavaStringToUTF8 nameUTF(_env, name);
    531   AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
    532 
    533   jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
    534   jsize numClosures = _env->GetArrayLength(closureArray);
    535 
    536   RsClosure* closures;
    537 
    538   if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
    539     LOG_API("Too many closures in script group");
    540     goto exit;
    541   }
    542 
    543   closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
    544   if (closures == nullptr) {
    545       goto exit;
    546   }
    547 
    548   for (int i = 0; i < numClosures; i++) {
    549     closures[i] = (RsClosure)jClosures[i];
    550   }
    551 
    552   ret = (jlong)(uintptr_t)dispatchTab.ScriptGroup2Create(
    553       (RsContext)con, nameUTF.c_str(), nameUTF.length(),
    554       cacheDirUTF.c_str(), cacheDirUTF.length(),
    555       closures, numClosures);
    556 
    557 exit:
    558 
    559   _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT);
    560 
    561   return ret;
    562 }
    563 
    564 static void
    565 nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) {
    566   dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID);
    567 }
    568 
    569 static void
    570 nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
    571 {
    572     LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
    573     dispatchTab.ObjDestroy((RsContext)con, (void *)obj);
    574 }
    575 
    576 
    577 static void
    578 nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
    579                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    580                             jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY,
    581                             jint KL, jint KU, jboolean mUseInc) {
    582     RsBlasCall call;
    583     memset(&call, 0, sizeof(call));
    584     call.func = (RsBlasFunction)func;
    585     call.transA = (RsBlasTranspose)TransA;
    586     call.transB = (RsBlasTranspose)TransB;
    587     call.side = (RsBlasSide)Side;
    588     call.uplo = (RsBlasUplo)Uplo;
    589     call.diag = (RsBlasDiag)Diag;
    590     call.M = M;
    591     call.N = N;
    592     call.K = K;
    593     call.alpha.f = alpha;
    594     call.beta.f = beta;
    595     call.incX = incX;
    596     call.incY = incY;
    597     call.KL = KL;
    598     call.KU = KU;
    599 
    600     RsAllocation in_allocs[3];
    601     in_allocs[0] = (RsAllocation)A;
    602     in_allocs[1] = (RsAllocation)B;
    603     in_allocs[2] = (RsAllocation)C;
    604 
    605     if (mUseInc) {
    606         dispatchTab.ContextFinish((RsContext)con);
    607         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
    608                                           in_allocs, sizeof(in_allocs), nullptr,
    609                                           &call, sizeof(call), nullptr, 0);
    610     } else {
    611         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    612                                        in_allocs, sizeof(in_allocs), nullptr,
    613                                        &call, sizeof(call), nullptr, 0);
    614     }
    615 }
    616 
    617 static void
    618 nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
    619                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    620                             jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY,
    621                             jint KL, jint KU, jboolean mUseInc) {
    622     RsBlasCall call;
    623     memset(&call, 0, sizeof(call));
    624     call.func = (RsBlasFunction)func;
    625     call.transA = (RsBlasTranspose)TransA;
    626     call.transB = (RsBlasTranspose)TransB;
    627     call.side = (RsBlasSide)Side;
    628     call.uplo = (RsBlasUplo)Uplo;
    629     call.diag = (RsBlasDiag)Diag;
    630     call.M = M;
    631     call.N = N;
    632     call.K = K;
    633     call.alpha.d = alpha;
    634     call.beta.d = beta;
    635     call.incX = incX;
    636     call.incY = incY;
    637     call.KL = KL;
    638     call.KU = KU;
    639 
    640     RsAllocation in_allocs[3];
    641     in_allocs[0] = (RsAllocation)A;
    642     in_allocs[1] = (RsAllocation)B;
    643     in_allocs[2] = (RsAllocation)C;
    644 
    645     if (mUseInc) {
    646         dispatchTab.ContextFinish((RsContext)con);
    647         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
    648                                           in_allocs, sizeof(in_allocs), nullptr,
    649                                           &call, sizeof(call), nullptr, 0);
    650     } else {
    651         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    652                                         in_allocs, sizeof(in_allocs), nullptr,
    653                                         &call, sizeof(call), nullptr, 0);
    654     }
    655 }
    656 
    657 static void
    658 nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
    659                              jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    660                              jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX,
    661                              jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) {
    662     RsBlasCall call;
    663     memset(&call, 0, sizeof(call));
    664     call.func = (RsBlasFunction)func;
    665     call.transA = (RsBlasTranspose)TransA;
    666     call.transB = (RsBlasTranspose)TransB;
    667     call.side = (RsBlasSide)Side;
    668     call.uplo = (RsBlasUplo)Uplo;
    669     call.diag = (RsBlasDiag)Diag;
    670     call.M = M;
    671     call.N = N;
    672     call.K = K;
    673     call.alpha.c.r = alphaX;
    674     call.alpha.c.i = alphaY;
    675     call.beta.c.r = betaX;
    676     call.beta.c.i = betaY;
    677     call.incX = incX;
    678     call.incY = incY;
    679     call.KL = KL;
    680     call.KU = KU;
    681 
    682     RsAllocation in_allocs[3];
    683     in_allocs[0] = (RsAllocation)A;
    684     in_allocs[1] = (RsAllocation)B;
    685     in_allocs[2] = (RsAllocation)C;
    686 
    687 
    688     if (mUseInc) {
    689         dispatchTab.ContextFinish((RsContext)con);
    690         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
    691                                           in_allocs, sizeof(in_allocs), nullptr,
    692                                           &call, sizeof(call), nullptr, 0);
    693     } else {
    694         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    695                                        in_allocs, sizeof(in_allocs), nullptr,
    696                                        &call, sizeof(call), nullptr, 0);
    697     }
    698 }
    699 
    700 static void
    701 nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
    702                        jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    703                        jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX,
    704                        jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) {
    705     RsBlasCall call;
    706     memset(&call, 0, sizeof(call));
    707     call.func = (RsBlasFunction)func;
    708     call.transA = (RsBlasTranspose)TransA;
    709     call.transB = (RsBlasTranspose)TransB;
    710     call.side = (RsBlasSide)Side;
    711     call.uplo = (RsBlasUplo)Uplo;
    712     call.diag = (RsBlasDiag)Diag;
    713     call.M = M;
    714     call.N = N;
    715     call.K = K;
    716     call.alpha.z.r = alphaX;
    717     call.alpha.z.i = alphaY;
    718     call.beta.z.r = betaX;
    719     call.beta.z.i = betaY;
    720     call.incX = incX;
    721     call.incY = incY;
    722     call.KL = KL;
    723     call.KU = KU;
    724 
    725     RsAllocation in_allocs[3];
    726     in_allocs[0] = (RsAllocation)A;
    727     in_allocs[1] = (RsAllocation)B;
    728     in_allocs[2] = (RsAllocation)C;
    729 
    730 
    731     if (mUseInc) {
    732         dispatchTab.ContextFinish((RsContext)con);
    733         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
    734                                           in_allocs, sizeof(in_allocs), nullptr,
    735                                           &call, sizeof(call), nullptr, 0);
    736     } else {
    737         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    738                                         in_allocs, sizeof(in_allocs), nullptr,
    739                                         &call, sizeof(call), nullptr, 0);
    740     }
    741 }
    742 
    743 
    744 static void
    745 nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint M, jint N, jint K,
    746                           jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset,
    747                           jint c_mult_int, jboolean mUseInc) {
    748     RsBlasCall call;
    749     memset(&call, 0, sizeof(call));
    750     call.func = RsBlas_bnnm;
    751     call.M = M;
    752     call.N = N;
    753     call.K = K;
    754     call.a_offset = a_offset & 0xFF;
    755     call.b_offset = b_offset & 0xFF;
    756     call.c_offset = c_offset;
    757     call.c_mult_int = c_mult_int;
    758 
    759     RsAllocation in_allocs[3];
    760     in_allocs[0] = (RsAllocation)A;
    761     in_allocs[1] = (RsAllocation)B;
    762     in_allocs[2] = (RsAllocation)C;
    763 
    764     if (mUseInc) {
    765         dispatchTab.ContextFinish((RsContext)con);
    766         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
    767                                           in_allocs, sizeof(in_allocs), nullptr,
    768                                           &call, sizeof(call), nullptr, 0);
    769     } else {
    770         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    771                                         in_allocs, sizeof(in_allocs), nullptr,
    772                                         &call, sizeof(call), nullptr, 0);
    773     }
    774 }
    775 // ---------------------------------------------------------------------------
    776 static jlong
    777 nDeviceCreate(JNIEnv *_env, jobject _this)
    778 {
    779     LOG_API("nDeviceCreate");
    780     return (jlong)(uintptr_t)dispatchTab.DeviceCreate();
    781 }
    782 
    783 static void
    784 nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
    785 {
    786     LOG_API("nDeviceDestroy");
    787     return dispatchTab.DeviceDestroy((RsDevice)dev);
    788 }
    789 
    790 static void
    791 nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
    792 {
    793     LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
    794     return dispatchTab.DeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
    795 }
    796 
    797 static jlong
    798 nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
    799                jint ct, jstring nativeLibDirJava)
    800 {
    801     LOG_API("nContextCreate");
    802     // Access the NativeLibDir in the Java Context.
    803     const char * nativeLibDir = _env->GetStringUTFChars(nativeLibDirJava, JNI_FALSE);
    804     size_t length = (size_t)_env->GetStringUTFLength(nativeLibDirJava);
    805 
    806     jlong id = (jlong)(uintptr_t)dispatchTab.ContextCreate((RsDevice)dev, ver,
    807                                                            sdkVer,
    808                                                            (RsContextType)ct, 0);
    809     if (dispatchTab.SetNativeLibDir) {
    810         dispatchTab.SetNativeLibDir((RsContext)id, nativeLibDir, length);
    811     }
    812 
    813     _env->ReleaseStringUTFChars(nativeLibDirJava, nativeLibDir);
    814     return id;
    815 }
    816 
    817 
    818 static void
    819 nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
    820 {
    821     LOG_API("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
    822     dispatchTab.ContextSetPriority((RsContext)con, p);
    823 }
    824 
    825 
    826 
    827 static void
    828 nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
    829 {
    830     LOG_API("nContextDestroy, con(%p)", (RsContext)con);
    831     dispatchTab.ContextDestroy((RsContext)con);
    832 }
    833 
    834 static void
    835 nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
    836 {
    837     LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
    838     dispatchTab.ContextDump((RsContext)con, bits);
    839 }
    840 
    841 
    842 static jstring
    843 nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
    844 {
    845     LOG_API("nContextGetErrorMessage, con(%p)", (RsContext)con);
    846     char buf[1024];
    847 
    848     size_t receiveLen;
    849     uint32_t subID;
    850     int id = dispatchTab.ContextGetMessage((RsContext)con,
    851                                            buf, sizeof(buf),
    852                                            &receiveLen, sizeof(receiveLen),
    853                                            &subID, sizeof(subID));
    854     if (!id && receiveLen) {
    855         //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
    856         //            "message receive buffer too small.  %zu", receiveLen);
    857     }
    858     return _env->NewStringUTF(buf);
    859 }
    860 
    861 static jint
    862 nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
    863 {
    864     jint len = _env->GetArrayLength(data);
    865     LOG_API("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
    866     jint *ptr = _env->GetIntArrayElements(data, NULL);
    867     size_t receiveLen;
    868     uint32_t subID;
    869     int id = dispatchTab.ContextGetMessage((RsContext)con,
    870                                            ptr, len * 4,
    871                                            &receiveLen, sizeof(receiveLen),
    872                                            &subID, sizeof(subID));
    873     if (!id && receiveLen) {
    874         //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
    875         //            "message receive buffer too small.  %zu", receiveLen);
    876     }
    877     _env->ReleaseIntArrayElements(data, ptr, 0);
    878     return (jint)id;
    879 }
    880 
    881 static jint
    882 nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
    883 {
    884     LOG_API("nContextPeekMessage, con(%p)", (RsContext)con);
    885     jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
    886     size_t receiveLen;
    887     uint32_t subID;
    888     int id = dispatchTab.ContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
    889                                   &subID, sizeof(subID));
    890     auxDataPtr[0] = (jint)subID;
    891     auxDataPtr[1] = (jint)receiveLen;
    892     _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
    893     return (jint)id;
    894 }
    895 
    896 static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
    897 {
    898     LOG_API("nContextInitToClient, con(%p)", (RsContext)con);
    899     dispatchTab.ContextInitToClient((RsContext)con);
    900 }
    901 
    902 static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
    903 {
    904     LOG_API("nContextDeinitToClient, con(%p)", (RsContext)con);
    905     dispatchTab.ContextDeinitToClient((RsContext)con);
    906 }
    907 
    908 static void
    909 nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
    910 {
    911     jint *ptr = NULL;
    912     jint len = 0;
    913     if (data) {
    914         len = _env->GetArrayLength(data);
    915         jint *ptr = _env->GetIntArrayElements(data, NULL);
    916     }
    917     LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
    918     dispatchTab.ContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
    919     if (data) {
    920         _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
    921     }
    922 }
    923 
    924 
    925 
    926 static jlong
    927 nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind,
    928                jboolean norm, jint size)
    929 {
    930     LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
    931             type, kind, norm, size);
    932     return (jlong)(uintptr_t)dispatchTab.ElementCreate((RsContext)con,
    933                                                        (RsDataType)type,
    934                                                        (RsDataKind)kind,
    935                                                        norm, size);
    936 }
    937 
    938 static jlong
    939 nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
    940                 jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
    941 {
    942     int fieldCount = _env->GetArrayLength(_ids);
    943     LOG_API("nElementCreate2, con(%p)", (RsContext)con);
    944 
    945     jlong *jIds = _env->GetLongArrayElements(_ids, NULL);
    946     jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
    947 
    948     RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
    949     uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
    950 
    951     for(int i = 0; i < fieldCount; i ++) {
    952         ids[i] = (RsElement)jIds[i];
    953         arraySizes[i] = (uint32_t)jArraySizes[i];
    954     }
    955 
    956     AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
    957 
    958     const char **nameArray = names.c_str();
    959     size_t *sizeArray = names.c_str_len();
    960 
    961     jlong id = (jlong)(uintptr_t)dispatchTab.ElementCreate2((RsContext)con, (RsElement *)ids,
    962                                                             fieldCount, nameArray,
    963                                                             fieldCount * sizeof(size_t),  sizeArray,
    964                                                             (const uint32_t *)arraySizes, fieldCount);
    965 
    966     free(ids);
    967     free(arraySizes);
    968     _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
    969     _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
    970     return id;
    971 }
    972 
    973 
    974 
    975 
    976 static void
    977 nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
    978                        jlongArray _IDs,
    979                        jobjectArray _names,
    980                        jintArray _arraySizes)
    981 {
    982     uint32_t dataSize = _env->GetArrayLength(_IDs);
    983     LOG_API("nElementGetSubElements, con(%p)", (RsContext)con);
    984 
    985     uintptr_t *ids = (uintptr_t *)malloc(dataSize * sizeof(uintptr_t));
    986     const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
    987     uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
    988 
    989     dispatchTab.ElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
    990                                       (uint32_t)dataSize);
    991 
    992     for(uint32_t i = 0; i < dataSize; i++) {
    993         const jlong id = (jlong)(uintptr_t)ids[i];
    994         const jint arraySize = (jint)arraySizes[i];
    995         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
    996         _env->SetLongArrayRegion(_IDs, i, 1, &id);
    997         _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
    998     }
    999 
   1000     free(ids);
   1001     free(names);
   1002     free(arraySizes);
   1003 }
   1004 
   1005 // -----------------------------------
   1006 
   1007 static jlong
   1008 nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
   1009             jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
   1010 {
   1011     LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
   1012             (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
   1013 
   1014     return (jlong)(uintptr_t)dispatchTab.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
   1015                                                     dimz, mips, faces, yuv);
   1016 }
   1017 
   1018 // -----------------------------------
   1019 
   1020 static jlong
   1021 nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
   1022                        jlong pointer)
   1023 {
   1024     LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
   1025             (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
   1026     return (jlong)(uintptr_t) dispatchTab.AllocationCreateTyped((RsContext)con, (RsType)type,
   1027                                                                 (RsAllocationMipmapControl)mips,
   1028                                                                 (uint32_t)usage, (uintptr_t)pointer);
   1029 }
   1030 
   1031 static void
   1032 nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
   1033 {
   1034     LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a, bits);
   1035     dispatchTab.AllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
   1036 }
   1037 
   1038 static void
   1039 nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
   1040 {
   1041     ioDispatch.sAllocationSetSurface(_env, _this, (RsContext)con, (RsAllocation)alloc, sur, dispatchTab);
   1042 }
   1043 
   1044 static void
   1045 nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
   1046 {
   1047     dispatchTab.AllocationIoSend((RsContext)con, (RsAllocation)alloc);
   1048 }
   1049 
   1050 static void
   1051 nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
   1052 {
   1053     LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
   1054     dispatchTab.AllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
   1055 }
   1056 
   1057 static size_t GetBitmapSize(JNIEnv *env, jobject jbitmap) {
   1058     AndroidBitmapInfo info;
   1059     memset(&info, 0, sizeof(info));
   1060     AndroidBitmap_getInfo(env, jbitmap, &info);
   1061     size_t s = info.width * info.height;
   1062     switch (info.format) {
   1063         case ANDROID_BITMAP_FORMAT_RGBA_8888: s *= 4; break;
   1064         case ANDROID_BITMAP_FORMAT_RGB_565: s *= 2; break;
   1065         case ANDROID_BITMAP_FORMAT_RGBA_4444: s *= 2; break;
   1066     }
   1067     return s;
   1068 }
   1069 
   1070 static jlong
   1071 nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
   1072                             jobject jbitmap, jint usage)
   1073 {
   1074     jlong id = 0;
   1075     void *pixels = NULL;
   1076     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
   1077 
   1078     if (pixels != NULL) {
   1079         id = (jlong)(uintptr_t)dispatchTab.AllocationCreateFromBitmap((RsContext)con,
   1080                                                                       (RsType)type,
   1081                                                                       (RsAllocationMipmapControl)mip,
   1082                                                                       pixels,
   1083                                                                       GetBitmapSize(_env, jbitmap),
   1084                                                                       usage);
   1085         AndroidBitmap_unlockPixels(_env, jbitmap);
   1086     }
   1087     return id;
   1088 }
   1089 
   1090 static jlong
   1091 nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
   1092                                         jint mip, jobject jbitmap, jint usage)
   1093 {
   1094     jlong id = 0;
   1095     void *pixels = NULL;
   1096     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
   1097 
   1098     if (pixels != NULL) {
   1099         id = (jlong)(uintptr_t)dispatchTab.AllocationCreateTyped((RsContext)con,
   1100                                                                  (RsType)type,
   1101                                                                  (RsAllocationMipmapControl)mip,
   1102                                                                  (uint32_t)usage,
   1103                                                                  (uintptr_t)pixels);
   1104         AndroidBitmap_unlockPixels(_env, jbitmap);
   1105     }
   1106     return id;
   1107 }
   1108 
   1109 static jlong
   1110 nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type,
   1111                                 jint mip, jobject jbitmap, jint usage)
   1112 {
   1113     void *pixels = NULL;
   1114     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
   1115 
   1116     jlong id = 0;
   1117     if (pixels != NULL) {
   1118         id = (jlong)(uintptr_t)dispatchTab.AllocationCubeCreateFromBitmap((RsContext)con,
   1119                                                                           (RsType)type,
   1120                                                                           (RsAllocationMipmapControl)mip,
   1121                                                                           pixels,
   1122                                                                           GetBitmapSize(_env, jbitmap),
   1123                                                                           usage);
   1124         AndroidBitmap_unlockPixels(_env, jbitmap);
   1125     }
   1126     return id;
   1127 }
   1128 
   1129 static void
   1130 nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
   1131 {
   1132     AndroidBitmapInfo info;
   1133     memset(&info, 0, sizeof(info));
   1134     AndroidBitmap_getInfo(_env, jbitmap, &info);
   1135 
   1136     void *pixels = NULL;
   1137     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
   1138 
   1139     if (pixels != NULL) {
   1140         dispatchTab.Allocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0, 0,
   1141                                      RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, info.width,
   1142                                      info.height, pixels, GetBitmapSize(_env, jbitmap), 0);
   1143         AndroidBitmap_unlockPixels(_env, jbitmap);
   1144     }
   1145 }
   1146 
   1147 static void
   1148 nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
   1149 {
   1150     AndroidBitmapInfo info;
   1151     memset(&info, 0, sizeof(info));
   1152     AndroidBitmap_getInfo(_env, jbitmap, &info);
   1153 
   1154     void *pixels = NULL;
   1155     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
   1156 
   1157     if (pixels != NULL) {
   1158         dispatchTab.AllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, pixels,
   1159                                            GetBitmapSize(_env, jbitmap));
   1160         AndroidBitmap_unlockPixels(_env, jbitmap);
   1161     }
   1162     //bitmap.notifyPixelsChanged();
   1163 }
   1164 
   1165 // Copies from the Java object data into the Allocation pointed to by _alloc.
   1166 static void
   1167 nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
   1168                   jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
   1169                   jboolean usePadding)
   1170 {
   1171     RsAllocation *alloc = (RsAllocation *)_alloc;
   1172     LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
   1173             "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
   1174             dataType);
   1175     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation1DData, true,
   1176                    (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
   1177 }
   1178 
   1179 
   1180 static void
   1181 nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint xoff,
   1182                          jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
   1183 {
   1184     jint len = _env->GetArrayLength(data);
   1185     LOG_API("nAllocationElementData1D, con(%p), alloc(%p), xoff(%i), comp(%i), len(%i), "
   1186             "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, compIdx, len,
   1187             sizeBytes);
   1188     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1189     dispatchTab.Allocation1DElementData((RsContext)con, (RsAllocation)alloc, xoff,
   1190                                         lod, ptr, sizeBytes, compIdx);
   1191     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1192 }
   1193 
   1194 /*
   1195 static void
   1196 nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
   1197                        jint xoff, jint yoff, jint zoff,
   1198                        jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
   1199 {
   1200     jint len = _env->GetArrayLength(data);
   1201     LOG_API("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
   1202             "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
   1203             sizeBytes);
   1204     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1205     dispatchTab.AllocationElementData((RsContext)con, (RsAllocation)alloc,
   1206                                       xoff, yoff, zoff,
   1207                                       lod, ptr, sizeBytes, compIdx);
   1208     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1209 }
   1210 */
   1211 
   1212 // Copies from the Java object data into the Allocation pointed to by _alloc.
   1213 static void
   1214 nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
   1215                   jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
   1216                   jboolean usePadding)
   1217 {
   1218     RsAllocation *alloc = (RsAllocation *)_alloc;
   1219     RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
   1220     LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
   1221             "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
   1222     int count = w * h;
   1223     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation2DData, true,
   1224                    (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
   1225 }
   1226 
   1227 static void
   1228 nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
   1229                         jlong dstAlloc, jint dstXoff, jint dstYoff,
   1230                         jint dstMip, jint dstFace,
   1231                         jint width, jint height,
   1232                         jlong srcAlloc, jint srcXoff, jint srcYoff,
   1233                         jint srcMip, jint srcFace)
   1234 {
   1235     LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
   1236             " dstMip(%i), dstFace(%i), width(%i), height(%i),"
   1237             " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
   1238             (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
   1239             width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
   1240 
   1241     dispatchTab.AllocationCopy2DRange((RsContext)con,
   1242                                       (RsAllocation)dstAlloc,
   1243                                       dstXoff, dstYoff,
   1244                                       dstMip, dstFace,
   1245                                       width, height,
   1246                                       (RsAllocation)srcAlloc,
   1247                                       srcXoff, srcYoff,
   1248                                       srcMip, srcFace);
   1249 }
   1250 
   1251 // Copies from the Java object data into the Allocation pointed to by _alloc.
   1252 static void
   1253 nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
   1254                   jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
   1255                   jint mSize, jboolean usePadding)
   1256 {
   1257     RsAllocation *alloc = (RsAllocation *)_alloc;
   1258     LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
   1259             " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
   1260             lod, w, h, d, sizeBytes);
   1261     int count = w * h * d;
   1262     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DData, true,
   1263                    (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
   1264 }
   1265 
   1266 static void
   1267 nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
   1268                         jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
   1269                         jint dstMip,
   1270                         jint width, jint height, jint depth,
   1271                         jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
   1272                         jint srcMip)
   1273 {
   1274     LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
   1275             " dstMip(%i), width(%i), height(%i),"
   1276             " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
   1277             (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
   1278             width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
   1279 
   1280     dispatchTab.AllocationCopy3DRange((RsContext)con,
   1281                                       (RsAllocation)dstAlloc,
   1282                                       dstXoff, dstYoff, dstZoff, dstMip,
   1283                                       width, height, depth,
   1284                                       (RsAllocation)srcAlloc,
   1285                                       srcXoff, srcYoff, srcZoff, srcMip);
   1286 }
   1287 
   1288 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1289 static void
   1290 nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
   1291                 jint mSize, jboolean usePadding)
   1292 {
   1293     RsAllocation *alloc = (RsAllocation *)_alloc;
   1294     LOG_API("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
   1295     int count = 0;
   1296     PER_ARRAY_TYPE(0, dispatchTab.AllocationRead, false,
   1297                    (RsContext)con, alloc, ptr, len * typeBytes);
   1298 }
   1299 
   1300 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1301 static void
   1302 nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
   1303                   jint count, jobject data, jint sizeBytes, jint dataType,
   1304                   jint mSize, jboolean usePadding)
   1305 {
   1306     RsAllocation *alloc = (RsAllocation *)_alloc;
   1307     LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
   1308               "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
   1309     PER_ARRAY_TYPE(0, dispatchTab.Allocation1DRead, false,
   1310                    (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
   1311 }
   1312 
   1313 // Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
   1314 /*
   1315 static void
   1316 nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc,
   1317                        jint xoff, jint yoff, jint zoff,
   1318                        jint lod, jint compIdx, jobject data, jint sizeBytes)
   1319 {
   1320     jint len = _env->GetArrayLength(data);
   1321     LOG_API("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
   1322             "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
   1323             sizeBytes);
   1324     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1325     dispatchTab.AllocationElementRead((RsContext)con, (RsAllocation)alloc,
   1326                                       xoff, yoff, zoff,
   1327                                       lod, ptr, sizeBytes, compIdx);
   1328     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1329 }
   1330 */
   1331 
   1332 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1333 static void
   1334 nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
   1335                   jint w, jint h, jobject data, jint sizeBytes, jint dataType,
   1336                   jint mSize, jboolean usePadding)
   1337 {
   1338     RsAllocation *alloc = (RsAllocation *)_alloc;
   1339     RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
   1340     LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
   1341               "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
   1342     int count = w * h;
   1343     PER_ARRAY_TYPE(0, dispatchTab.Allocation2DRead, false,
   1344                    (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
   1345 }
   1346 
   1347 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1348 /*
   1349 static void
   1350 nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
   1351                   jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
   1352                   jint mSize, jboolean usePadding)
   1353 {
   1354     RsAllocation *alloc = (RsAllocation *)_alloc;
   1355     LOG_API("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
   1356             " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
   1357             lod, w, h, d, sizeBytes);
   1358     int count = w * h * d;
   1359     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DRead, false,
   1360                    (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
   1361 }
   1362 */
   1363 
   1364 static jlong
   1365 nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
   1366 {
   1367     LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
   1368     return (jlong)(uintptr_t) dispatchTab.AllocationGetType((RsContext)con, (RsAllocation)a);
   1369 }
   1370 
   1371 static void
   1372 nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
   1373 {
   1374     LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
   1375             (RsAllocation)alloc, dimX);
   1376     dispatchTab.AllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
   1377 }
   1378 
   1379 // -----------------------------------
   1380 
   1381 static void
   1382 nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot, jboolean mUseInc)
   1383 {
   1384     LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)",
   1385             (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
   1386     if (mUseInc) {
   1387         dispatchTabInc.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
   1388     } else {
   1389         dispatchTab.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
   1390     }
   1391 }
   1392 
   1393 static void
   1394 nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val, jboolean mUseInc)
   1395 {
   1396     LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
   1397             (void *)script, slot, val);
   1398     if (mUseInc) {
   1399         dispatchTabInc.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
   1400     } else {
   1401         dispatchTab.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
   1402     }
   1403 }
   1404 
   1405 static void
   1406 nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
   1407 {
   1408     LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
   1409             (void *)script, slot, val);
   1410     if (mUseInc) {
   1411         dispatchTabInc.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
   1412     } else {
   1413         dispatchTab.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
   1414     }
   1415 }
   1416 
   1417 static void
   1418 nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
   1419 {
   1420     LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con,
   1421             (void *)script, slot, val);
   1422     if (mUseInc) {
   1423         dispatchTabInc.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
   1424     } else {
   1425         dispatchTab.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
   1426     }
   1427 }
   1428 
   1429 static void
   1430 nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val, jboolean mUseInc)
   1431 {
   1432     LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con,
   1433             (void *)script, slot, val);
   1434     if (mUseInc) {
   1435         dispatchTabInc.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
   1436     } else {
   1437         dispatchTab.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
   1438     }
   1439 }
   1440 
   1441 static void
   1442 nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val, jboolean mUseInc)
   1443 {
   1444     LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con,
   1445             (void *)script, slot, val);
   1446     if (mUseInc) {
   1447         dispatchTabInc.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
   1448     } else {
   1449         dispatchTab.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
   1450     }
   1451 }
   1452 
   1453 static void
   1454 nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
   1455 {
   1456     LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1457     jint len = _env->GetArrayLength(data);
   1458     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
   1459     if (mUseInc) {
   1460         dispatchTabInc.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
   1461     } else {
   1462         dispatchTab.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
   1463     }
   1464     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1465 }
   1466 
   1467 static void
   1468 nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
   1469                 jlong elem, jintArray dims, jboolean mUseInc)
   1470 {
   1471     LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1472     jint len = _env->GetArrayLength(data);
   1473     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
   1474     jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
   1475     jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
   1476     if (mUseInc) {
   1477         dispatchTabInc.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
   1478                                       (const uint32_t *)dimsPtr, dimsLen);
   1479     } else {
   1480         dispatchTab.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
   1481                                    (const uint32_t *)dimsPtr, dimsLen);
   1482     }
   1483     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1484     _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
   1485 }
   1486 
   1487 
   1488 static void
   1489 nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone, jboolean mUseInc)
   1490 {
   1491     LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", (RsContext)con,
   1492             (void *)script, (const char *)timeZone);
   1493 
   1494     jint length = _env->GetArrayLength(timeZone);
   1495     jbyte* timeZone_ptr;
   1496     timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
   1497     if (mUseInc) {
   1498         dispatchTabInc.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
   1499     } else {
   1500         dispatchTab.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
   1501     }
   1502 
   1503     if (timeZone_ptr) {
   1504         _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
   1505     }
   1506 }
   1507 
   1508 static void
   1509 nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot, jboolean mUseInc)
   1510 {
   1511     LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
   1512     if (mUseInc) {
   1513         dispatchTabInc.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
   1514     } else {
   1515         dispatchTab.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
   1516     }
   1517 }
   1518 
   1519 static void
   1520 nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
   1521 {
   1522     LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1523     jint len = _env->GetArrayLength(data);
   1524     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
   1525     if (mUseInc) {
   1526         dispatchTabInc.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
   1527     } else {
   1528         dispatchTab.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
   1529     }
   1530     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1531 }
   1532 
   1533 static void
   1534 nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
   1535                jlong script, jint slot, jlong ain, jlong aout, jboolean mUseInc)
   1536 {
   1537     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1538     if (mUseInc) {
   1539         dispatchTab.ContextFinish((RsContext)con);
   1540         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
   1541                                      (RsAllocation)ain, (RsAllocation)aout,
   1542                                      NULL, 0, NULL, 0);
   1543     } else {
   1544         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
   1545                                   (RsAllocation)ain, (RsAllocation)aout,
   1546                                   NULL, 0, NULL, 0);
   1547     }
   1548 }
   1549 static void
   1550 nScriptForEachV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
   1551                 jlong script, jint slot, jlong ain, jlong aout, jbyteArray params, jboolean mUseInc)
   1552 {
   1553     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1554     jint len = _env->GetArrayLength(params);
   1555     jbyte *ptr = _env->GetByteArrayElements(params, NULL);
   1556     if (mUseInc) {
   1557         dispatchTab.ContextFinish((RsContext)con);
   1558         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
   1559                                      (RsAllocation)ain, (RsAllocation)aout,
   1560                                      ptr, len, NULL, 0);
   1561     } else {
   1562         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
   1563                                   (RsAllocation)ain, (RsAllocation)aout,
   1564                                   ptr, len, NULL, 0);
   1565     }
   1566     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
   1567 }
   1568 
   1569 static void
   1570 nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
   1571                       jlong script, jint slot, jlong ain, jlong aout,
   1572                       jint xstart, jint xend,
   1573                       jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
   1574 {
   1575     LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1576     RsScriptCall sc;
   1577     sc.xStart = xstart;
   1578     sc.xEnd = xend;
   1579     sc.yStart = ystart;
   1580     sc.yEnd = yend;
   1581     sc.zStart = zstart;
   1582     sc.zEnd = zend;
   1583     sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
   1584     sc.arrayStart = 0;
   1585     sc.arrayEnd = 0;
   1586     if (mUseInc) {
   1587         dispatchTab.ContextFinish((RsContext)con);
   1588         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
   1589                                      (RsAllocation)ain, (RsAllocation)aout,
   1590                                      NULL, 0, &sc, sizeof(sc));
   1591     } else {
   1592         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
   1593                                   (RsAllocation)ain, (RsAllocation)aout,
   1594                                   NULL, 0, &sc, sizeof(sc));
   1595     }
   1596 }
   1597 
   1598 static void
   1599 nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
   1600                        jlong script, jint slot, jlong ain, jlong aout,
   1601                        jbyteArray params, jint xstart, jint xend,
   1602                        jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
   1603 {
   1604     LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1605     jint len = _env->GetArrayLength(params);
   1606     jbyte *ptr = _env->GetByteArrayElements(params, NULL);
   1607     RsScriptCall sc;
   1608     sc.xStart = xstart;
   1609     sc.xEnd = xend;
   1610     sc.yStart = ystart;
   1611     sc.yEnd = yend;
   1612     sc.zStart = zstart;
   1613     sc.zEnd = zend;
   1614     sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
   1615     sc.arrayStart = 0;
   1616     sc.arrayEnd = 0;
   1617     if (mUseInc) {
   1618         dispatchTab.ContextFinish((RsContext)con);
   1619         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
   1620                                      (RsAllocation)ain, (RsAllocation)aout,
   1621                                      ptr, len, &sc, sizeof(sc));
   1622     } else {
   1623         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
   1624                                   (RsAllocation)ain, (RsAllocation)aout,
   1625                                   ptr, len, &sc, sizeof(sc));
   1626     }
   1627     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
   1628 }
   1629 
   1630 // -----------------------------------
   1631 
   1632 static jlong
   1633 nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
   1634                jstring resName, jstring cacheDir,
   1635                jbyteArray scriptRef, jint length)
   1636 {
   1637     LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
   1638 
   1639     AutoJavaStringToUTF8 resNameUTF(_env, resName);
   1640     AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
   1641     jlong ret = 0;
   1642     jbyte* script_ptr = NULL;
   1643     jint _exception = 0;
   1644     jint remaining;
   1645     if (!scriptRef) {
   1646         _exception = 1;
   1647         //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
   1648         goto exit;
   1649     }
   1650     if (length < 0) {
   1651         _exception = 1;
   1652         //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
   1653         goto exit;
   1654     }
   1655     remaining = _env->GetArrayLength(scriptRef);
   1656     if (remaining < length) {
   1657         _exception = 1;
   1658         //jniThrowException(_env, "java/lang/IllegalArgumentException",
   1659         //        "length > script.length - offset");
   1660         goto exit;
   1661     }
   1662     script_ptr = (jbyte *)
   1663         _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
   1664 
   1665     //rsScriptCSetText(con, (const char *)script_ptr, length);
   1666 
   1667     ret = (jlong)(uintptr_t)dispatchTab.ScriptCCreate((RsContext)con,
   1668                                                       resNameUTF.c_str(), resNameUTF.length(),
   1669                                                       cacheDirUTF.c_str(), cacheDirUTF.length(),
   1670                                                       (const char *)script_ptr, length);
   1671 
   1672 exit:
   1673     if (script_ptr) {
   1674         _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
   1675                 _exception ? JNI_ABORT: 0);
   1676     }
   1677 
   1678     return (jlong)(uintptr_t)ret;
   1679 }
   1680 
   1681 static jlong
   1682 nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid, jboolean mUseInc)
   1683 {
   1684     LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
   1685     if (mUseInc) {
   1686         return (jlong)(uintptr_t)dispatchTabInc.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
   1687     } else {
   1688         return (jlong)(uintptr_t)dispatchTab.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
   1689     }
   1690 }
   1691 
   1692 static jlong
   1693 nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig, jboolean mUseInc)
   1694 {
   1695     LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
   1696             (void *)sid, slot, sig);
   1697     if (mUseInc) {
   1698         return (jlong)(uintptr_t)dispatchTabInc.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
   1699                                                                      slot, sig);
   1700     } else {
   1701         return (jlong)(uintptr_t)dispatchTab.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
   1702                                                                   slot, sig);
   1703     }
   1704 }
   1705 
   1706 static jlong
   1707 nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
   1708 {
   1709     LOG_API("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con,
   1710             (void *)sid, slot);
   1711     return (jlong)dispatchTab.ScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
   1712 }
   1713 
   1714 static jlong
   1715 nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jboolean mUseInc)
   1716 {
   1717     LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
   1718     if (mUseInc) {
   1719         return (jlong)(uintptr_t)dispatchTabInc.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
   1720     } else {
   1721         return (jlong)(uintptr_t)dispatchTab.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
   1722     }
   1723 }
   1724 
   1725 static jlong
   1726 nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
   1727     jlongArray _dstk, jlongArray _dstf, jlongArray _types)
   1728 {
   1729     LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
   1730 
   1731     jint kernelsLen = _env->GetArrayLength(_kernels);
   1732     jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
   1733     RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
   1734     for(int i = 0; i < kernelsLen; ++i) {
   1735         kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
   1736     }
   1737 
   1738     jint srcLen = _env->GetArrayLength(_src);
   1739     jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
   1740     RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
   1741     for(int i = 0; i < srcLen; ++i) {
   1742         srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
   1743     }
   1744 
   1745     jint dstkLen = _env->GetArrayLength(_dstk);
   1746     jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
   1747     RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
   1748     for(int i = 0; i < dstkLen; ++i) {
   1749         dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
   1750     }
   1751 
   1752     jint dstfLen = _env->GetArrayLength(_dstf);
   1753     jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
   1754     RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
   1755     for(int i = 0; i < dstfLen; ++i) {
   1756         dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
   1757     }
   1758 
   1759     jint typesLen = _env->GetArrayLength(_types);
   1760     jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
   1761     RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
   1762     for(int i = 0; i < typesLen; ++i) {
   1763         typesPtr[i] = (RsType)jTypesPtr[i];
   1764     }
   1765 
   1766     jlong id = (jlong)(uintptr_t) dispatchTab.ScriptGroupCreate((RsContext)con,
   1767                                (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
   1768                                (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
   1769                                (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
   1770                                (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
   1771                                (RsType *)typesPtr, typesLen * sizeof(RsType));
   1772 
   1773     free(kernelsPtr);
   1774     free(srcPtr);
   1775     free(dstkPtr);
   1776     free(dstfPtr);
   1777     free(typesPtr);
   1778     _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
   1779     _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
   1780     _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
   1781     _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
   1782     _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
   1783     return id;
   1784 }
   1785 
   1786 static void
   1787 nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
   1788 {
   1789     LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
   1790             (void *)gid, (void *)kid, (void *)alloc);
   1791     dispatchTab.ScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
   1792                                     (RsAllocation)alloc);
   1793 }
   1794 
   1795 static void
   1796 nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
   1797 {
   1798     LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
   1799             (void *)gid, (void *)kid, (void *)alloc);
   1800     dispatchTab.ScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
   1801                                      (RsAllocation)alloc);
   1802 }
   1803 
   1804 static void
   1805 nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
   1806 {
   1807     LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
   1808     dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
   1809 }
   1810 
   1811 // ---------------------------------------------------------------------------
   1812 
   1813 static jlong
   1814 nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
   1815                jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
   1816 {
   1817     LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
   1818     return (jlong)(uintptr_t)dispatchTab.SamplerCreate((RsContext)con,
   1819                                                        (RsSamplerValue)magFilter,
   1820                                                        (RsSamplerValue)minFilter,
   1821                                                        (RsSamplerValue)wrapS,
   1822                                                        (RsSamplerValue)wrapT,
   1823                                                        (RsSamplerValue)wrapR,
   1824                                                        aniso);
   1825 }
   1826 
   1827 static jint
   1828 nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
   1829     return (jint)sizeof(void*);
   1830 }
   1831 
   1832 // ---------------------------------------------------------------------------
   1833 // For Incremental Intrinsic Support
   1834 static jboolean nIncLoadSO(JNIEnv *_env, jobject _this, jint deviceApi) {
   1835     void* handle = NULL;
   1836     handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
   1837     if (handle == NULL) {
   1838         LOG_API("couldn't dlopen %s, %s", filename, dlerror());
   1839         return false;
   1840     }
   1841 
   1842     if (loadSymbols(handle, dispatchTabInc, deviceApi) == false) {
   1843         LOG_API("%s init failed!", filename);
   1844         return false;
   1845     }
   1846     LOG_API("Successfully loaded %s", filename);
   1847     return true;
   1848 }
   1849 
   1850 // -----------------------------------
   1851 // To create/destroy a dummy context
   1852 static void
   1853 nIncObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
   1854 {
   1855     LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
   1856     dispatchTabInc.ObjDestroy((RsContext)con, (void *)obj);
   1857 }
   1858 
   1859 
   1860 static jlong
   1861 nIncDeviceCreate(JNIEnv *_env, jobject _this)
   1862 {
   1863     LOG_API("nDeviceCreate");
   1864     return (jlong)(uintptr_t)dispatchTabInc.DeviceCreate();
   1865 }
   1866 
   1867 static void
   1868 nIncDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
   1869 {
   1870     LOG_API("nDeviceDestroy");
   1871     return dispatchTabInc.DeviceDestroy((RsDevice)dev);
   1872 }
   1873 
   1874 static jlong
   1875 nIncContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
   1876 {
   1877     LOG_API("nContextCreate");
   1878     //The compat context for incremental support will be synchronous.
   1879     return (jlong)(uintptr_t)dispatchTabInc.ContextCreate((RsDevice)dev, ver, sdkVer,
   1880                                                           (RsContextType)ct,
   1881                                                           RS_CONTEXT_SYNCHRONOUS);
   1882 }
   1883 
   1884 static void
   1885 nIncContextFinish(JNIEnv *_env, jobject _this, jlong con)
   1886 {
   1887     LOG_API("nContextFinish, con(%p)", (RsContext)con);
   1888     dispatchTabInc.ContextFinish((RsContext)con);
   1889 }
   1890 
   1891 static void
   1892 nIncContextDestroy(JNIEnv *_env, jobject _this, jlong con)
   1893 {
   1894     LOG_API("nContextDestroy, con(%p)", (RsContext)con);
   1895     dispatchTabInc.ContextDestroy((RsContext)con);
   1896 }
   1897 
   1898 // -----------------------------------
   1899 // Create dummy Element
   1900 static jlong
   1901 nIncElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
   1902 {
   1903     LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
   1904             type, kind, norm, size);
   1905     return (jlong)(uintptr_t)dispatchTabInc.ElementCreate((RsContext)con, (RsDataType)type,
   1906                                                           (RsDataKind)kind, norm, size);
   1907 }
   1908 // -----------------------------------
   1909 // Create dummy Type
   1910 static jlong
   1911 nIncTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
   1912             jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
   1913 {
   1914     LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
   1915             incCon, eid, dimx, dimy, dimz, mips, faces, yuv);
   1916 
   1917     return (jlong)(uintptr_t)dispatchTabInc.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
   1918                                                        dimz, mips, faces, yuv);
   1919 }
   1920 
   1921 // -----------------------------------
   1922 // Create Allocation from pointer
   1923 static jlong
   1924 nIncAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong alloc, jlong type)
   1925 {
   1926     LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
   1927             incCon, (RsElement)type, mips, usage, (void *)pointer);
   1928     size_t strideIn;
   1929     void* pIn = NULL;
   1930     RsAllocation ainI = NULL;
   1931     if (alloc != 0) {
   1932         pIn = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
   1933                                                RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
   1934                                                &strideIn, sizeof(size_t));
   1935         ainI = dispatchTabInc.AllocationCreateTyped((RsContext)incCon, (RsType)type,
   1936                                                     RS_ALLOCATION_MIPMAP_NONE,
   1937                                                     RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED,
   1938                                                     (uintptr_t)pIn);
   1939     }
   1940     return (jlong)(uintptr_t) ainI;
   1941 }
   1942 
   1943 // ---------------------------------------------------------------------------
   1944 
   1945 
   1946 static const char *classPathName = "android/support/v8/renderscript/RenderScript";
   1947 
   1948 static JNINativeMethod methods[] = {
   1949 {"nLoadSO",                        "(ZI)Z",                                   (bool*)nLoadSO },
   1950 {"nLoadIOSO",                      "()Z",                                     (bool*)nLoadIOSO },
   1951 {"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
   1952 {"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
   1953 {"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
   1954 {"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
   1955 {"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
   1956 {"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
   1957 {"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
   1958 {"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
   1959 
   1960 
   1961 // All methods below are thread protected in java.
   1962 {"rsnContextCreate",                 "(JIIILjava/lang/String;)J",             (void*)nContextCreate },
   1963 {"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
   1964 {"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
   1965 {"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
   1966 {"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
   1967 {"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
   1968 {"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
   1969 {"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
   1970 {"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
   1971 {"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
   1972 {"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
   1973 
   1974 {"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
   1975 {"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
   1976 {"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
   1977 
   1978 {"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
   1979 
   1980 {"rsnAllocationCreateTyped",         "(JJIIJ)J",                              (void*)nAllocationCreateTyped },
   1981 {"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
   1982 {"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
   1983 {"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
   1984 
   1985 {"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
   1986 {"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
   1987 
   1988 {"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
   1989 {"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
   1990 {"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
   1991 {"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
   1992 {"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
   1993 //{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
   1994 {"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
   1995 {"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
   1996 {"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
   1997 {"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
   1998 {"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
   1999 {"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
   2000 //{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
   2001 {"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
   2002 //{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",  (void*)nAllocationRead3D },
   2003 {"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
   2004 {"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
   2005 {"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
   2006 
   2007 {"rsnScriptBindAllocation",          "(JJJIZ)V",                              (void*)nScriptBindAllocation },
   2008 {"rsnScriptSetTimeZone",             "(JJ[BZ)V",                              (void*)nScriptSetTimeZone },
   2009 {"rsnScriptInvoke",                  "(JJIZ)V",                               (void*)nScriptInvoke },
   2010 {"rsnScriptInvokeV",                 "(JJI[BZ)V",                             (void*)nScriptInvokeV },
   2011 {"rsnScriptForEach",                 "(JJJIJJZ)V",                            (void*)nScriptForEach },
   2012 {"rsnScriptForEach",                 "(JJJIJJ[BZ)V",                          (void*)nScriptForEachV },
   2013 {"rsnScriptForEachClipped",          "(JJJIJJIIIIIIZ)V",                      (void*)nScriptForEachClipped },
   2014 {"rsnScriptForEachClipped",          "(JJJIJJ[BIIIIIIZ)V",                    (void*)nScriptForEachClippedV },
   2015 {"rsnScriptSetVarI",                 "(JJIIZ)V",                              (void*)nScriptSetVarI },
   2016 {"rsnScriptSetVarJ",                 "(JJIJZ)V",                              (void*)nScriptSetVarJ },
   2017 {"rsnScriptSetVarF",                 "(JJIFZ)V",                              (void*)nScriptSetVarF },
   2018 {"rsnScriptSetVarD",                 "(JJIDZ)V",                              (void*)nScriptSetVarD },
   2019 {"rsnScriptSetVarV",                 "(JJI[BZ)V",                             (void*)nScriptSetVarV },
   2020 {"rsnScriptSetVarVE",                "(JJI[BJ[IZ)V",                          (void*)nScriptSetVarVE },
   2021 {"rsnScriptSetVarObj",               "(JJIJZ)V",                              (void*)nScriptSetVarObj },
   2022 
   2023 {"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
   2024 {"rsnScriptIntrinsicCreate",         "(JIJZ)J",                               (void*)nScriptIntrinsicCreate },
   2025 {"rsnScriptKernelIDCreate",          "(JJIIZ)J",                              (void*)nScriptKernelIDCreate },
   2026 {"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
   2027 {"rsnScriptFieldIDCreate",           "(JJIZ)J",                               (void*)nScriptFieldIDCreate },
   2028 {"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
   2029 {"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
   2030 {"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
   2031 {"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
   2032 {"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
   2033 {"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
   2034 
   2035 {"rsnScriptIntrinsicBLAS_Single",    "(JJJIIIIIIIIIFJJFJIIIIZ)V",             (void*)nScriptIntrinsicBLAS_Single },
   2036 {"rsnScriptIntrinsicBLAS_Double",    "(JJJIIIIIIIIIDJJDJIIIIZ)V",             (void*)nScriptIntrinsicBLAS_Double },
   2037 {"rsnScriptIntrinsicBLAS_Complex",   "(JJJIIIIIIIIIFFJJFFJIIIIZ)V",           (void*)nScriptIntrinsicBLAS_Complex },
   2038 {"rsnScriptIntrinsicBLAS_Z",         "(JJJIIIIIIIIIDDJJDDJIIIIZ)V",           (void*)nScriptIntrinsicBLAS_Z },
   2039 
   2040 {"rsnScriptIntrinsicBLAS_BNNM",      "(JJJIIIJIJIJIIZ)V",                     (void*)nScriptIntrinsicBLAS_BNNM },
   2041 
   2042 {"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
   2043 
   2044 {"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
   2045 
   2046 // Entry points for Inc libRSSupport
   2047 {"nIncLoadSO",                       "(I)Z",                                  (bool*)nIncLoadSO },
   2048 {"nIncDeviceCreate",                 "()J",                                   (void*)nIncDeviceCreate },
   2049 {"nIncDeviceDestroy",                "(J)V",                                  (void*)nIncDeviceDestroy },
   2050 {"rsnIncContextCreate",              "(JIII)J",                               (void*)nIncContextCreate },
   2051 {"rsnIncContextFinish",              "(J)V",                                  (void*)nIncContextFinish },
   2052 {"rsnIncContextDestroy",             "(J)V",                                  (void*)nIncContextDestroy },
   2053 {"rsnIncObjDestroy",                 "(JJ)V",                                 (void*)nIncObjDestroy },
   2054 {"rsnIncElementCreate",              "(JJIZI)J",                              (void*)nIncElementCreate },
   2055 {"rsnIncTypeCreate",                 "(JJIIIZZI)J",                           (void*)nIncTypeCreate },
   2056 {"rsnIncAllocationCreateTyped",      "(JJJJ)J",                               (void*)nIncAllocationCreateTyped },
   2057 };
   2058 
   2059 // ---------------------------------------------------------------------------
   2060 
   2061 jint JNI_OnLoad(JavaVM* vm, void* reserved)
   2062 {
   2063     JNIEnv* env = NULL;
   2064     jclass clazz = NULL;
   2065     jint result = -1;
   2066 
   2067     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
   2068         //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
   2069         //            "ERROR: GetEnv failed\n");
   2070         goto bail;
   2071     }
   2072     if (env == NULL) {
   2073         //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
   2074         goto bail;
   2075     }
   2076 
   2077     clazz = env->FindClass(classPathName);
   2078     if (clazz == NULL) {
   2079         goto bail;
   2080     }
   2081 
   2082     if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) {
   2083         //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
   2084         //            "ERROR: MediaPlayer native registration failed\n");
   2085         goto bail;
   2086     }
   2087 
   2088     /* success -- return valid version number */
   2089     result = JNI_VERSION_1_4;
   2090 
   2091 bail:
   2092     return result;
   2093 }
   2094