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 "RenderScript_jni"
     18 
     19 #include <stdlib.h>
     20 #include <stdio.h>
     21 #include <fcntl.h>
     22 #include <unistd.h>
     23 #include <math.h>
     24 #include <utils/misc.h>
     25 #include <inttypes.h>
     26 
     27 #include <android-base/macros.h>
     28 #include <androidfw/Asset.h>
     29 #include <androidfw/AssetManager2.h>
     30 #include <androidfw/ResourceTypes.h>
     31 #include <android-base/macros.h>
     32 
     33 #include "jni.h"
     34 #include <nativehelper/JNIHelp.h>
     35 #include "android_runtime/AndroidRuntime.h"
     36 #include "android_runtime/android_view_Surface.h"
     37 #include "android_runtime/android_util_AssetManager.h"
     38 #include "android/graphics/GraphicsJNI.h"
     39 #include "android/native_window.h"
     40 #include "android/native_window_jni.h"
     41 
     42 #include <rsEnv.h>
     43 #include <rsApiStubs.h>
     44 #include <gui/Surface.h>
     45 #include <gui/GLConsumer.h>
     46 #include <android_runtime/android_graphics_SurfaceTexture.h>
     47 
     48 //#define LOG_API ALOGE
     49 static constexpr bool kLogApi = false;
     50 
     51 using namespace android;
     52 
     53 #define PER_ARRAY_TYPE(flag, fnc, readonly, ...) {                                      \
     54     jint len = 0;                                                                       \
     55     void *ptr = nullptr;                                                                \
     56     void *srcPtr = nullptr;                                                             \
     57     size_t typeBytes = 0;                                                               \
     58     jint relFlag = 0;                                                                   \
     59     if (readonly) {                                                                     \
     60         /* The on-release mode should only be JNI_ABORT for read-only accesses. */      \
     61         /* readonly = true, also indicates we are copying to the allocation   . */      \
     62         relFlag = JNI_ABORT;                                                            \
     63     }                                                                                   \
     64     switch(dataType) {                                                                  \
     65     case RS_TYPE_FLOAT_32:                                                              \
     66         len = _env->GetArrayLength((jfloatArray)data);                                  \
     67         ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
     68         if (ptr == nullptr) {                                                           \
     69             ALOGE("Failed to get Java array elements.");                                \
     70             return;                                                                     \
     71         }                                                                               \
     72         typeBytes = 4;                                                                  \
     73         if (usePadding) {                                                               \
     74             srcPtr = ptr;                                                               \
     75             len = len / 3 * 4;                                                          \
     76             if (count == 0) {                                                           \
     77                 count = len / 4;                                                        \
     78             }                                                                           \
     79             ptr = malloc (len * typeBytes);                                             \
     80             if (readonly) {                                                             \
     81                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
     82                 fnc(__VA_ARGS__);                                                       \
     83             } else {                                                                    \
     84                 fnc(__VA_ARGS__);                                                       \
     85                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
     86             }                                                                           \
     87             free(ptr);                                                                  \
     88             ptr = srcPtr;                                                               \
     89         } else {                                                                        \
     90             fnc(__VA_ARGS__);                                                           \
     91         }                                                                               \
     92         _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag);     \
     93         return;                                                                         \
     94     case RS_TYPE_FLOAT_64:                                                              \
     95         len = _env->GetArrayLength((jdoubleArray)data);                                 \
     96         ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
     97         if (ptr == nullptr) {                                                           \
     98             ALOGE("Failed to get Java array elements.");                                \
     99             return;                                                                     \
    100         }                                                                               \
    101         typeBytes = 8;                                                                  \
    102         if (usePadding) {                                                               \
    103             srcPtr = ptr;                                                               \
    104             len = len / 3 * 4;                                                          \
    105             if (count == 0) {                                                           \
    106                 count = len / 4;                                                        \
    107             }                                                                           \
    108             ptr = malloc (len * typeBytes);                                             \
    109             if (readonly) {                                                             \
    110                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    111                 fnc(__VA_ARGS__);                                                       \
    112             } else {                                                                    \
    113                 fnc(__VA_ARGS__);                                                       \
    114                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    115             }                                                                           \
    116             free(ptr);                                                                  \
    117             ptr = srcPtr;                                                               \
    118         } else {                                                                        \
    119             fnc(__VA_ARGS__);                                                           \
    120         }                                                                               \
    121         _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag);  \
    122         return;                                                                         \
    123     case RS_TYPE_SIGNED_8:                                                              \
    124     case RS_TYPE_UNSIGNED_8:                                                            \
    125         len = _env->GetArrayLength((jbyteArray)data);                                   \
    126         ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
    127         if (ptr == nullptr) {                                                           \
    128             ALOGE("Failed to get Java array elements.");                                \
    129             return;                                                                     \
    130         }                                                                               \
    131         typeBytes = 1;                                                                  \
    132         if (usePadding) {                                                               \
    133             srcPtr = ptr;                                                               \
    134             len = len / 3 * 4;                                                          \
    135             if (count == 0) {                                                           \
    136                 count = len / 4;                                                        \
    137             }                                                                           \
    138             ptr = malloc (len * typeBytes);                                             \
    139             if (readonly) {                                                             \
    140                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    141                 fnc(__VA_ARGS__);                                                       \
    142             } else {                                                                    \
    143                 fnc(__VA_ARGS__);                                                       \
    144                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    145             }                                                                           \
    146             free(ptr);                                                                  \
    147             ptr = srcPtr;                                                               \
    148         } else {                                                                        \
    149             fnc(__VA_ARGS__);                                                           \
    150         }                                                                               \
    151         _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag);         \
    152         return;                                                                         \
    153     case RS_TYPE_SIGNED_16:                                                             \
    154     case RS_TYPE_UNSIGNED_16:                                                           \
    155     case RS_TYPE_FLOAT_16:                                                              \
    156         len = _env->GetArrayLength((jshortArray)data);                                  \
    157         ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
    158         if (ptr == nullptr) {                                                           \
    159             ALOGE("Failed to get Java array elements.");                                \
    160             return;                                                                     \
    161         }                                                                               \
    162         typeBytes = 2;                                                                  \
    163         if (usePadding) {                                                               \
    164             srcPtr = ptr;                                                               \
    165             len = len / 3 * 4;                                                          \
    166             if (count == 0) {                                                           \
    167                 count = len / 4;                                                        \
    168             }                                                                           \
    169             ptr = malloc (len * typeBytes);                                             \
    170             if (readonly) {                                                             \
    171                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    172                 fnc(__VA_ARGS__);                                                       \
    173             } else {                                                                    \
    174                 fnc(__VA_ARGS__);                                                       \
    175                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    176             }                                                                           \
    177             free(ptr);                                                                  \
    178             ptr = srcPtr;                                                               \
    179         } else {                                                                        \
    180             fnc(__VA_ARGS__);                                                           \
    181         }                                                                               \
    182         _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag);     \
    183         return;                                                                         \
    184     case RS_TYPE_SIGNED_32:                                                             \
    185     case RS_TYPE_UNSIGNED_32:                                                           \
    186         len = _env->GetArrayLength((jintArray)data);                                    \
    187         ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
    188         if (ptr == nullptr) {                                                           \
    189             ALOGE("Failed to get Java array elements.");                                \
    190             return;                                                                     \
    191         }                                                                               \
    192         typeBytes = 4;                                                                  \
    193         if (usePadding) {                                                               \
    194             srcPtr = ptr;                                                               \
    195             len = len / 3 * 4;                                                          \
    196             if (count == 0) {                                                           \
    197                 count = len / 4;                                                        \
    198             }                                                                           \
    199             ptr = malloc (len * typeBytes);                                             \
    200             if (readonly) {                                                             \
    201                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    202                 fnc(__VA_ARGS__);                                                       \
    203             } else {                                                                    \
    204                 fnc(__VA_ARGS__);                                                       \
    205                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    206             }                                                                           \
    207             free(ptr);                                                                  \
    208             ptr = srcPtr;                                                               \
    209         } else {                                                                        \
    210             fnc(__VA_ARGS__);                                                           \
    211         }                                                                               \
    212         _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag);           \
    213         return;                                                                         \
    214     case RS_TYPE_SIGNED_64:                                                             \
    215     case RS_TYPE_UNSIGNED_64:                                                           \
    216         len = _env->GetArrayLength((jlongArray)data);                                   \
    217         ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
    218         if (ptr == nullptr) {                                                           \
    219             ALOGE("Failed to get Java array elements.");                                \
    220             return;                                                                     \
    221         }                                                                               \
    222         typeBytes = 8;                                                                  \
    223         if (usePadding) {                                                               \
    224             srcPtr = ptr;                                                               \
    225             len = len / 3 * 4;                                                          \
    226             if (count == 0) {                                                           \
    227                 count = len / 4;                                                        \
    228             }                                                                           \
    229             ptr = malloc (len * typeBytes);                                             \
    230             if (readonly) {                                                             \
    231                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
    232                 fnc(__VA_ARGS__);                                                       \
    233             } else {                                                                    \
    234                 fnc(__VA_ARGS__);                                                       \
    235                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
    236             }                                                                           \
    237             free(ptr);                                                                  \
    238             ptr = srcPtr;                                                               \
    239         } else {                                                                        \
    240             fnc(__VA_ARGS__);                                                           \
    241         }                                                                               \
    242         _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag);        \
    243         return;                                                                         \
    244     default:                                                                            \
    245         break;                                                                          \
    246     }                                                                                   \
    247     UNUSED(len, ptr, srcPtr, typeBytes, relFlag);                                       \
    248 }
    249 
    250 
    251 class AutoJavaStringToUTF8 {
    252 public:
    253     AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
    254         fCStr = env->GetStringUTFChars(str, nullptr);
    255         fLength = env->GetStringUTFLength(str);
    256     }
    257     ~AutoJavaStringToUTF8() {
    258         fEnv->ReleaseStringUTFChars(fJStr, fCStr);
    259     }
    260     const char* c_str() const { return fCStr; }
    261     jsize length() const { return fLength; }
    262 
    263 private:
    264     JNIEnv*     fEnv;
    265     jstring     fJStr;
    266     const char* fCStr;
    267     jsize       fLength;
    268 };
    269 
    270 class AutoJavaStringArrayToUTF8 {
    271 public:
    272     AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
    273     : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
    274         mCStrings = nullptr;
    275         mSizeArray = nullptr;
    276         if (stringsLength > 0) {
    277             mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
    278             mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
    279             for (jsize ct = 0; ct < stringsLength; ct ++) {
    280                 jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
    281                 mCStrings[ct] = mEnv->GetStringUTFChars(s, nullptr);
    282                 mSizeArray[ct] = mEnv->GetStringUTFLength(s);
    283             }
    284         }
    285     }
    286     ~AutoJavaStringArrayToUTF8() {
    287         for (jsize ct=0; ct < mStringsLength; ct++) {
    288             jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
    289             mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
    290         }
    291         free(mCStrings);
    292         free(mSizeArray);
    293     }
    294     const char **c_str() const { return mCStrings; }
    295     size_t *c_str_len() const { return mSizeArray; }
    296     jsize length() const { return mStringsLength; }
    297 
    298 private:
    299     JNIEnv      *mEnv;
    300     jobjectArray mStrings;
    301     const char **mCStrings;
    302     size_t      *mSizeArray;
    303     jsize        mStringsLength;
    304 };
    305 
    306 // ---------------------------------------------------------------------------
    307 
    308 static jfieldID gContextId = 0;
    309 
    310 static void _nInit(JNIEnv *_env, jclass _this)
    311 {
    312     gContextId             = _env->GetFieldID(_this, "mContext", "J");
    313 }
    314 
    315 // ---------------------------------------------------------------------------
    316 
    317 static void copyWithPadding(void* ptr, void* srcPtr, int mSize, int count) {
    318     int sizeBytesPad = mSize * 4;
    319     int sizeBytes = mSize * 3;
    320     uint8_t *dst = static_cast<uint8_t *>(ptr);
    321     uint8_t *src = static_cast<uint8_t *>(srcPtr);
    322     for (int i = 0; i < count; i++) {
    323         memcpy(dst, src, sizeBytes);
    324         dst += sizeBytesPad;
    325         src += sizeBytes;
    326     }
    327 }
    328 
    329 static void copyWithUnPadding(void* ptr, void* srcPtr, int mSize, int count) {
    330     int sizeBytesPad = mSize * 4;
    331     int sizeBytes = mSize * 3;
    332     uint8_t *dst = static_cast<uint8_t *>(ptr);
    333     uint8_t *src = static_cast<uint8_t *>(srcPtr);
    334     for (int i = 0; i < count; i++) {
    335         memcpy(dst, src, sizeBytes);
    336         dst += sizeBytes;
    337         src += sizeBytesPad;
    338     }
    339 }
    340 
    341 
    342 // ---------------------------------------------------------------------------
    343 static void
    344 nContextFinish(JNIEnv *_env, jobject _this, jlong con)
    345 {
    346     if (kLogApi) {
    347         ALOGD("nContextFinish, con(%p)", (RsContext)con);
    348     }
    349     rsContextFinish((RsContext)con);
    350 }
    351 
    352 static jlong
    353 nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
    354                jlong returnValue, jlongArray fieldIDArray,
    355                jlongArray valueArray, jintArray sizeArray,
    356                jlongArray depClosureArray, jlongArray depFieldIDArray) {
    357   jlong ret = 0;
    358 
    359   jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
    360   jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
    361   if (jFieldIDs == nullptr) {
    362       ALOGE("Failed to get Java array elements: fieldIDs.");
    363       return ret;
    364   }
    365 
    366   jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
    367   jsize values_length = _env->GetArrayLength(valueArray);
    368   if (jValues == nullptr) {
    369       ALOGE("Failed to get Java array elements: values.");
    370       return ret;
    371   }
    372 
    373   jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
    374   jsize sizes_length = _env->GetArrayLength(sizeArray);
    375   if (jSizes == nullptr) {
    376       ALOGE("Failed to get Java array elements: sizes.");
    377       return ret;
    378   }
    379 
    380   jlong* jDepClosures =
    381       _env->GetLongArrayElements(depClosureArray, nullptr);
    382   jsize depClosures_length = _env->GetArrayLength(depClosureArray);
    383   if (jDepClosures == nullptr) {
    384       ALOGE("Failed to get Java array elements: depClosures.");
    385       return ret;
    386   }
    387 
    388   jlong* jDepFieldIDs =
    389       _env->GetLongArrayElements(depFieldIDArray, nullptr);
    390   jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
    391   if (jDepFieldIDs == nullptr) {
    392       ALOGE("Failed to get Java array elements: depFieldIDs.");
    393       return ret;
    394   }
    395 
    396   size_t numValues, numDependencies;
    397   RsScriptFieldID* fieldIDs;
    398   RsClosure* depClosures;
    399   RsScriptFieldID* depFieldIDs;
    400 
    401   if (fieldIDs_length != values_length || values_length != sizes_length) {
    402       ALOGE("Unmatched field IDs, values, and sizes in closure creation.");
    403       goto exit;
    404   }
    405 
    406   numValues = (size_t)fieldIDs_length;
    407 
    408   if (depClosures_length != depFieldIDs_length) {
    409       ALOGE("Unmatched closures and field IDs for dependencies in closure creation.");
    410       goto exit;
    411   }
    412 
    413   numDependencies = (size_t)depClosures_length;
    414 
    415   if (numDependencies > numValues) {
    416       ALOGE("Unexpected number of dependencies in closure creation");
    417       goto exit;
    418   }
    419 
    420   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
    421       ALOGE("Too many arguments or globals in closure creation");
    422       goto exit;
    423   }
    424 
    425   if (numValues > 0) {
    426       fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
    427       if (fieldIDs == nullptr) {
    428           goto exit;
    429       }
    430   } else {
    431       // numValues == 0
    432       // alloca(0) implementation is platform-dependent.
    433       fieldIDs = nullptr;
    434   }
    435 
    436   for (size_t i = 0; i < numValues; i++) {
    437     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
    438   }
    439 
    440   if (numDependencies > 0) {
    441       depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies);
    442       if (depClosures == nullptr) {
    443           goto exit;
    444       }
    445 
    446       for (size_t i = 0; i < numDependencies; i++) {
    447           depClosures[i] = (RsClosure)jDepClosures[i];
    448       }
    449 
    450       depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies);
    451       if (depFieldIDs == nullptr) {
    452           goto exit;
    453       }
    454 
    455       for (size_t i = 0; i < numDependencies; i++) {
    456           depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
    457       }
    458   } else {
    459       // alloca(0) implementation is platform-dependent.
    460       depClosures = nullptr;
    461       depFieldIDs = nullptr;
    462   }
    463 
    464   ret = (jlong)(uintptr_t)rsClosureCreate(
    465       (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
    466       fieldIDs, numValues, jValues, numValues,
    467       (int*)jSizes, numValues,
    468       depClosures, numDependencies,
    469       depFieldIDs, numDependencies);
    470 
    471 exit:
    472 
    473   _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT);
    474   _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT);
    475   _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
    476   _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
    477   _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
    478 
    479   return ret;
    480 }
    481 
    482 static jlong
    483 nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
    484                      jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
    485                      jintArray sizeArray) {
    486   jlong ret = 0;
    487 
    488   jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
    489   jsize jParamLength = _env->GetArrayLength(paramArray);
    490   if (jParams == nullptr) {
    491       ALOGE("Failed to get Java array elements: params.");
    492       return ret;
    493   }
    494 
    495   jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
    496   jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
    497   if (jFieldIDs == nullptr) {
    498       ALOGE("Failed to get Java array elements: fieldIDs.");
    499       return ret;
    500   }
    501 
    502   jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
    503   jsize values_length = _env->GetArrayLength(valueArray);
    504   if (jValues == nullptr) {
    505       ALOGE("Failed to get Java array elements: values.");
    506       return ret;
    507   }
    508 
    509   jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
    510   jsize sizes_length = _env->GetArrayLength(sizeArray);
    511   if (jSizes == nullptr) {
    512       ALOGE("Failed to get Java array elements: sizes.");
    513       return ret;
    514   }
    515 
    516   size_t numValues;
    517   RsScriptFieldID* fieldIDs;
    518 
    519   if (fieldIDs_length != values_length || values_length != sizes_length) {
    520       ALOGE("Unmatched field IDs, values, and sizes in closure creation.");
    521       goto exit;
    522   }
    523 
    524   numValues = (size_t) fieldIDs_length;
    525 
    526   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
    527       ALOGE("Too many arguments or globals in closure creation");
    528       goto exit;
    529   }
    530 
    531   fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
    532   if (fieldIDs == nullptr) {
    533       goto exit;
    534   }
    535 
    536   for (size_t i = 0; i< numValues; i++) {
    537     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
    538   }
    539 
    540   ret = (jlong)(uintptr_t)rsInvokeClosureCreate(
    541       (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
    542       fieldIDs, numValues, jValues, numValues,
    543       (int*)jSizes, numValues);
    544 
    545 exit:
    546 
    547   _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
    548   _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
    549   _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
    550   _env->ReleaseByteArrayElements(paramArray,      jParams,      JNI_ABORT);
    551 
    552   return ret;
    553 }
    554 
    555 static void
    556 nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
    557                jint index, jlong value, jint size) {
    558   // Size is signed with -1 indicating the value is an Allocation
    559   rsClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
    560                   (uintptr_t)value, size);
    561 }
    562 
    563 static void
    564 nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
    565                   jlong fieldID, jlong value, jint size) {
    566   // Size is signed with -1 indicating the value is an Allocation
    567   rsClosureSetGlobal((RsContext)con, (RsClosure)closureID,
    568                      (RsScriptFieldID)fieldID, (int64_t)value, size);
    569 }
    570 
    571 static long
    572 nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name,
    573                     jstring cacheDir, jlongArray closureArray) {
    574   jlong ret = 0;
    575 
    576   AutoJavaStringToUTF8 nameUTF(_env, name);
    577   AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
    578 
    579   jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
    580   jsize numClosures = _env->GetArrayLength(closureArray);
    581   if (jClosures == nullptr) {
    582       ALOGE("Failed to get Java array elements: closures.");
    583       return ret;
    584   }
    585 
    586   RsClosure* closures;
    587 
    588   if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
    589     ALOGE("Too many closures in script group");
    590     goto exit;
    591   }
    592 
    593   closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
    594   if (closures == nullptr) {
    595       goto exit;
    596   }
    597 
    598   for (int i = 0; i < numClosures; i++) {
    599     closures[i] = (RsClosure)jClosures[i];
    600   }
    601 
    602   ret = (jlong)(uintptr_t)rsScriptGroup2Create(
    603       (RsContext)con, nameUTF.c_str(), nameUTF.length(),
    604       cacheDirUTF.c_str(), cacheDirUTF.length(),
    605       closures, numClosures);
    606 
    607 exit:
    608 
    609   _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT);
    610 
    611   return ret;
    612 }
    613 
    614 static void
    615 nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) {
    616   rsScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID);
    617 }
    618 
    619 static void
    620 nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
    621                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    622                             jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY,
    623                             jint KL, jint KU) {
    624     RsBlasCall call;
    625     memset(&call, 0, sizeof(call));
    626     call.func = (RsBlasFunction)func;
    627     call.transA = (RsBlasTranspose)TransA;
    628     call.transB = (RsBlasTranspose)TransB;
    629     call.side = (RsBlasSide)Side;
    630     call.uplo = (RsBlasUplo)Uplo;
    631     call.diag = (RsBlasDiag)Diag;
    632     call.M = M;
    633     call.N = N;
    634     call.K = K;
    635     call.alpha.f = alpha;
    636     call.beta.f = beta;
    637     call.incX = incX;
    638     call.incY = incY;
    639     call.KL = KL;
    640     call.KU = KU;
    641 
    642     RsAllocation in_allocs[3];
    643     in_allocs[0] = (RsAllocation)A;
    644     in_allocs[1] = (RsAllocation)B;
    645     in_allocs[2] = (RsAllocation)C;
    646 
    647     rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    648                          in_allocs, NELEM(in_allocs), nullptr,
    649                          &call, sizeof(call), nullptr, 0);
    650 }
    651 
    652 static void
    653 nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
    654                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    655                             jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY,
    656                             jint KL, jint KU) {
    657     RsBlasCall call;
    658     memset(&call, 0, sizeof(call));
    659     call.func = (RsBlasFunction)func;
    660     call.transA = (RsBlasTranspose)TransA;
    661     call.transB = (RsBlasTranspose)TransB;
    662     call.side = (RsBlasSide)Side;
    663     call.uplo = (RsBlasUplo)Uplo;
    664     call.diag = (RsBlasDiag)Diag;
    665     call.M = M;
    666     call.N = N;
    667     call.K = K;
    668     call.alpha.d = alpha;
    669     call.beta.d = beta;
    670     call.incX = incX;
    671     call.incY = incY;
    672     call.KL = KL;
    673     call.KU = KU;
    674 
    675     RsAllocation in_allocs[3];
    676     in_allocs[0] = (RsAllocation)A;
    677     in_allocs[1] = (RsAllocation)B;
    678     in_allocs[2] = (RsAllocation)C;
    679 
    680     rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    681                          in_allocs, NELEM(in_allocs), nullptr,
    682                          &call, sizeof(call), nullptr, 0);
    683 }
    684 
    685 static void
    686 nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
    687                              jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    688                              jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX,
    689                              jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU) {
    690     RsBlasCall call;
    691     memset(&call, 0, sizeof(call));
    692     call.func = (RsBlasFunction)func;
    693     call.transA = (RsBlasTranspose)TransA;
    694     call.transB = (RsBlasTranspose)TransB;
    695     call.side = (RsBlasSide)Side;
    696     call.uplo = (RsBlasUplo)Uplo;
    697     call.diag = (RsBlasDiag)Diag;
    698     call.M = M;
    699     call.N = N;
    700     call.K = K;
    701     call.alpha.c.r = alphaX;
    702     call.alpha.c.i = alphaY;
    703     call.beta.c.r = betaX;
    704     call.beta.c.i = betaY;
    705     call.incX = incX;
    706     call.incY = incY;
    707     call.KL = KL;
    708     call.KU = KU;
    709 
    710     RsAllocation in_allocs[3];
    711     in_allocs[0] = (RsAllocation)A;
    712     in_allocs[1] = (RsAllocation)B;
    713     in_allocs[2] = (RsAllocation)C;
    714 
    715     rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    716                          in_allocs, NELEM(in_allocs), nullptr,
    717                          &call, sizeof(call), nullptr, 0);
    718 }
    719 
    720 static void
    721 nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
    722                        jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
    723                        jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX,
    724                        jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU) {
    725     RsBlasCall call;
    726     memset(&call, 0, sizeof(call));
    727     call.func = (RsBlasFunction)func;
    728     call.transA = (RsBlasTranspose)TransA;
    729     call.transB = (RsBlasTranspose)TransB;
    730     call.side = (RsBlasSide)Side;
    731     call.uplo = (RsBlasUplo)Uplo;
    732     call.diag = (RsBlasDiag)Diag;
    733     call.M = M;
    734     call.N = N;
    735     call.K = K;
    736     call.alpha.z.r = alphaX;
    737     call.alpha.z.i = alphaY;
    738     call.beta.z.r = betaX;
    739     call.beta.z.i = betaY;
    740     call.incX = incX;
    741     call.incY = incY;
    742     call.KL = KL;
    743     call.KU = KU;
    744 
    745     RsAllocation in_allocs[3];
    746     in_allocs[0] = (RsAllocation)A;
    747     in_allocs[1] = (RsAllocation)B;
    748     in_allocs[2] = (RsAllocation)C;
    749 
    750     rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    751                          in_allocs, NELEM(in_allocs), nullptr,
    752                          &call, sizeof(call), nullptr, 0);
    753 }
    754 
    755 
    756 static void
    757 nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong id, jint M, jint N, jint K,
    758                                              jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset,
    759                                              jint c_mult_int) {
    760     RsBlasCall call;
    761     memset(&call, 0, sizeof(call));
    762     call.func = RsBlas_bnnm;
    763     call.M = M;
    764     call.N = N;
    765     call.K = K;
    766     call.a_offset = a_offset & 0xFF;
    767     call.b_offset = b_offset & 0xFF;
    768     call.c_offset = c_offset;
    769     call.c_mult_int = c_mult_int;
    770 
    771     RsAllocation in_allocs[3];
    772     in_allocs[0] = (RsAllocation)A;
    773     in_allocs[1] = (RsAllocation)B;
    774     in_allocs[2] = (RsAllocation)C;
    775 
    776     rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
    777                          in_allocs, NELEM(in_allocs), nullptr,
    778                          &call, sizeof(call), nullptr, 0);
    779 }
    780 
    781 
    782 static void
    783 nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str)
    784 {
    785     if (kLogApi) {
    786         ALOGD("nAssignName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
    787     }
    788     jint len = _env->GetArrayLength(str);
    789     jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
    790     if (cptr == nullptr) {
    791         ALOGE("Failed to get Java array elements");
    792         return;
    793     }
    794 
    795     rsAssignName((RsContext)con, (void *)obj, (const char *)cptr, len);
    796     _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
    797 }
    798 
    799 static jstring
    800 nGetName(JNIEnv *_env, jobject _this, jlong con, jlong obj)
    801 {
    802     if (kLogApi) {
    803         ALOGD("nGetName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
    804     }
    805     const char *name = nullptr;
    806     rsaGetName((RsContext)con, (void *)obj, &name);
    807     if(name == nullptr || strlen(name) == 0) {
    808         return nullptr;
    809     }
    810     return _env->NewStringUTF(name);
    811 }
    812 
    813 static void
    814 nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
    815 {
    816     if (kLogApi) {
    817         ALOGD("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
    818     }
    819     rsObjDestroy((RsContext)con, (void *)obj);
    820 }
    821 
    822 // ---------------------------------------------------------------------------
    823 
    824 static jlong
    825 nDeviceCreate(JNIEnv *_env, jobject _this)
    826 {
    827     if (kLogApi) {
    828         ALOGD("nDeviceCreate");
    829     }
    830     return (jlong)(uintptr_t)rsDeviceCreate();
    831 }
    832 
    833 static void
    834 nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
    835 {
    836     if (kLogApi) {
    837         ALOGD("nDeviceDestroy");
    838     }
    839     return rsDeviceDestroy((RsDevice)dev);
    840 }
    841 
    842 static void
    843 nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
    844 {
    845     if (kLogApi) {
    846         ALOGD("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
    847     }
    848     return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
    849 }
    850 
    851 static jlong
    852 nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint flags, jint sdkVer, jint contextType)
    853 {
    854     if (kLogApi) {
    855         ALOGD("nContextCreate");
    856     }
    857     return (jlong)(uintptr_t)rsContextCreate((RsDevice)dev, 0, sdkVer, (RsContextType)contextType, flags);
    858 }
    859 
    860 static jlong
    861 nContextCreateGL(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
    862                  jint colorMin, jint colorPref,
    863                  jint alphaMin, jint alphaPref,
    864                  jint depthMin, jint depthPref,
    865                  jint stencilMin, jint stencilPref,
    866                  jint samplesMin, jint samplesPref, jfloat samplesQ,
    867                  jint dpi)
    868 {
    869     RsSurfaceConfig sc = {};
    870     sc.alphaMin = alphaMin;
    871     sc.alphaPref = alphaPref;
    872     sc.colorMin = colorMin;
    873     sc.colorPref = colorPref;
    874     sc.depthMin = depthMin;
    875     sc.depthPref = depthPref;
    876     sc.samplesMin = samplesMin;
    877     sc.samplesPref = samplesPref;
    878     sc.samplesQ = samplesQ;
    879 
    880     if (kLogApi) {
    881         ALOGD("nContextCreateGL");
    882     }
    883     return (jlong)(uintptr_t)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
    884 }
    885 
    886 static void
    887 nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
    888 {
    889     if (kLogApi) {
    890         ALOGD("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
    891     }
    892     rsContextSetPriority((RsContext)con, p);
    893 }
    894 
    895 static void
    896 nContextSetCacheDir(JNIEnv *_env, jobject _this, jlong con, jstring cacheDir)
    897 {
    898     AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
    899 
    900     if (kLogApi) {
    901         ALOGD("ContextSetCacheDir, con(%p), cacheDir(%s)", (RsContext)con, cacheDirUTF.c_str());
    902     }
    903     rsContextSetCacheDir((RsContext)con, cacheDirUTF.c_str(), cacheDirUTF.length());
    904 }
    905 
    906 
    907 
    908 static void
    909 nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd)
    910 {
    911     if (kLogApi) {
    912         ALOGD("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", (RsContext)con,
    913               width, height, (Surface *)wnd);
    914     }
    915 
    916     ANativeWindow * window = nullptr;
    917     if (wnd == nullptr) {
    918 
    919     } else {
    920         window = android_view_Surface_getNativeWindow(_env, wnd).get();
    921     }
    922 
    923     rsContextSetSurface((RsContext)con, width, height, window);
    924 }
    925 
    926 static void
    927 nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
    928 {
    929     if (kLogApi) {
    930         ALOGD("nContextDestroy, con(%p)", (RsContext)con);
    931     }
    932     rsContextDestroy((RsContext)con);
    933 }
    934 
    935 static void
    936 nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
    937 {
    938     if (kLogApi) {
    939         ALOGD("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
    940     }
    941     rsContextDump((RsContext)con, bits);
    942 }
    943 
    944 static void
    945 nContextPause(JNIEnv *_env, jobject _this, jlong con)
    946 {
    947     if (kLogApi) {
    948         ALOGD("nContextPause, con(%p)", (RsContext)con);
    949     }
    950     rsContextPause((RsContext)con);
    951 }
    952 
    953 static void
    954 nContextResume(JNIEnv *_env, jobject _this, jlong con)
    955 {
    956     if (kLogApi) {
    957         ALOGD("nContextResume, con(%p)", (RsContext)con);
    958     }
    959     rsContextResume((RsContext)con);
    960 }
    961 
    962 
    963 static jstring
    964 nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
    965 {
    966     if (kLogApi) {
    967         ALOGD("nContextGetErrorMessage, con(%p)", (RsContext)con);
    968     }
    969     char buf[1024];
    970 
    971     size_t receiveLen;
    972     uint32_t subID;
    973     int id = rsContextGetMessage((RsContext)con,
    974                                  buf, sizeof(buf),
    975                                  &receiveLen, sizeof(receiveLen),
    976                                  &subID, sizeof(subID));
    977     if (!id && receiveLen) {
    978         ALOGV("message receive buffer too small.  %zu", receiveLen);
    979     }
    980     return _env->NewStringUTF(buf);
    981 }
    982 
    983 static jint
    984 nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
    985 {
    986     jint len = _env->GetArrayLength(data);
    987     if (kLogApi) {
    988         ALOGD("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
    989     }
    990     jint *ptr = _env->GetIntArrayElements(data, nullptr);
    991     if (ptr == nullptr) {
    992         ALOGE("Failed to get Java array elements");
    993         return 0;
    994     }
    995     size_t receiveLen;
    996     uint32_t subID;
    997     int id = rsContextGetMessage((RsContext)con,
    998                                  ptr, len * 4,
    999                                  &receiveLen, sizeof(receiveLen),
   1000                                  &subID, sizeof(subID));
   1001     if (!id && receiveLen) {
   1002         ALOGV("message receive buffer too small.  %zu", receiveLen);
   1003     }
   1004     _env->ReleaseIntArrayElements(data, ptr, 0);
   1005     return (jint)id;
   1006 }
   1007 
   1008 static jint
   1009 nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
   1010 {
   1011     if (kLogApi) {
   1012         ALOGD("nContextPeekMessage, con(%p)", (RsContext)con);
   1013     }
   1014     jint *auxDataPtr = _env->GetIntArrayElements(auxData, nullptr);
   1015     if (auxDataPtr == nullptr) {
   1016         ALOGE("Failed to get Java array elements");
   1017         return 0;
   1018     }
   1019     size_t receiveLen;
   1020     uint32_t subID;
   1021     int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
   1022                                   &subID, sizeof(subID));
   1023     auxDataPtr[0] = (jint)subID;
   1024     auxDataPtr[1] = (jint)receiveLen;
   1025     _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
   1026     return (jint)id;
   1027 }
   1028 
   1029 static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
   1030 {
   1031     if (kLogApi) {
   1032         ALOGD("nContextInitToClient, con(%p)", (RsContext)con);
   1033     }
   1034     rsContextInitToClient((RsContext)con);
   1035 }
   1036 
   1037 static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
   1038 {
   1039     if (kLogApi) {
   1040         ALOGD("nContextDeinitToClient, con(%p)", (RsContext)con);
   1041     }
   1042     rsContextDeinitToClient((RsContext)con);
   1043 }
   1044 
   1045 static void
   1046 nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
   1047 {
   1048     jint *ptr = nullptr;
   1049     jint len = 0;
   1050     if (data) {
   1051         len = _env->GetArrayLength(data);
   1052         ptr = _env->GetIntArrayElements(data, nullptr);
   1053         if (ptr == nullptr) {
   1054             ALOGE("Failed to get Java array elements");
   1055             return;
   1056         }
   1057     }
   1058     if (kLogApi) {
   1059         ALOGD("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
   1060     }
   1061     rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
   1062     if (data) {
   1063         _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
   1064     }
   1065 }
   1066 
   1067 
   1068 
   1069 static jlong
   1070 nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm,
   1071                jint size)
   1072 {
   1073     if (kLogApi) {
   1074         ALOGD("nElementCreate, con(%p), type(%" PRId64 "), kind(%i), norm(%i), size(%i)", (RsContext)con,
   1075               type, kind, norm, size);
   1076     }
   1077     return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind,
   1078                                              norm, size);
   1079 }
   1080 
   1081 static jlong
   1082 nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
   1083                 jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
   1084 {
   1085     int fieldCount = _env->GetArrayLength(_ids);
   1086     if (kLogApi) {
   1087         ALOGD("nElementCreate2, con(%p)", (RsContext)con);
   1088     }
   1089 
   1090     jlong *jIds = _env->GetLongArrayElements(_ids, nullptr);
   1091     if (jIds == nullptr) {
   1092         ALOGE("Failed to get Java array elements: ids");
   1093         return 0;
   1094     }
   1095     jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, nullptr);
   1096     if (jArraySizes == nullptr) {
   1097         ALOGE("Failed to get Java array elements: arraySizes");
   1098         return 0;
   1099     }
   1100 
   1101     RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
   1102     uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
   1103 
   1104     for(int i = 0; i < fieldCount; i ++) {
   1105         ids[i] = (RsElement)jIds[i];
   1106         arraySizes[i] = (uint32_t)jArraySizes[i];
   1107     }
   1108 
   1109     AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
   1110 
   1111     const char **nameArray = names.c_str();
   1112     size_t *sizeArray = names.c_str_len();
   1113 
   1114     jlong id = (jlong)(uintptr_t)rsElementCreate2((RsContext)con,
   1115                                      (const RsElement *)ids, fieldCount,
   1116                                      nameArray, fieldCount * sizeof(size_t),  sizeArray,
   1117                                      (const uint32_t *)arraySizes, fieldCount);
   1118 
   1119     free(ids);
   1120     free(arraySizes);
   1121     _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
   1122     _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
   1123 
   1124     return (jlong)(uintptr_t)id;
   1125 }
   1126 
   1127 static void
   1128 nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData)
   1129 {
   1130     int dataSize = _env->GetArrayLength(_elementData);
   1131     if (kLogApi) {
   1132         ALOGD("nElementGetNativeData, con(%p)", (RsContext)con);
   1133     }
   1134 
   1135     // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
   1136     assert(dataSize == 5);
   1137 
   1138     uint32_t elementData[5];
   1139     rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize);
   1140 
   1141     for(jint i = 0; i < dataSize; i ++) {
   1142         const jint data = (jint)elementData[i];
   1143         _env->SetIntArrayRegion(_elementData, i, 1, &data);
   1144     }
   1145 }
   1146 
   1147 
   1148 static void
   1149 nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
   1150                        jlongArray _IDs,
   1151                        jobjectArray _names,
   1152                        jintArray _arraySizes)
   1153 {
   1154     uint32_t dataSize = _env->GetArrayLength(_IDs);
   1155     if (kLogApi) {
   1156         ALOGD("nElementGetSubElements, con(%p)", (RsContext)con);
   1157     }
   1158 
   1159     uintptr_t *ids = (uintptr_t*)malloc(dataSize * sizeof(uintptr_t));
   1160     const char **names = (const char **)malloc(dataSize * sizeof(const char *));
   1161     size_t *arraySizes = (size_t *)malloc(dataSize * sizeof(size_t));
   1162 
   1163     rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
   1164                              (uint32_t)dataSize);
   1165 
   1166     for(uint32_t i = 0; i < dataSize; i++) {
   1167         const jlong id = (jlong)(uintptr_t)ids[i];
   1168         const jint arraySize = (jint)arraySizes[i];
   1169         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
   1170         _env->SetLongArrayRegion(_IDs, i, 1, &id);
   1171         _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
   1172     }
   1173 
   1174     free(ids);
   1175     free(names);
   1176     free(arraySizes);
   1177 }
   1178 
   1179 // -----------------------------------
   1180 
   1181 static jlong
   1182 nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
   1183             jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
   1184 {
   1185     if (kLogApi) {
   1186         ALOGD("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
   1187               (RsContext)con, (void*)eid, dimx, dimy, dimz, mips, faces, yuv);
   1188     }
   1189 
   1190     return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips,
   1191                                           faces, yuv);
   1192 }
   1193 
   1194 static void
   1195 nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jlongArray _typeData)
   1196 {
   1197     // We are packing 6 items: mDimX; mDimY; mDimZ;
   1198     // mDimLOD; mDimFaces; mElement; into typeData
   1199     int elementCount = _env->GetArrayLength(_typeData);
   1200 
   1201     assert(elementCount == 6);
   1202     if (kLogApi) {
   1203         ALOGD("nTypeGetNativeData, con(%p)", (RsContext)con);
   1204     }
   1205 
   1206     uintptr_t typeData[6];
   1207     rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
   1208 
   1209     for(jint i = 0; i < elementCount; i ++) {
   1210         const jlong data = (jlong)(uintptr_t)typeData[i];
   1211         _env->SetLongArrayRegion(_typeData, i, 1, &data);
   1212     }
   1213 }
   1214 
   1215 // -----------------------------------
   1216 
   1217 static jlong
   1218 nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
   1219                        jlong pointer)
   1220 {
   1221     if (kLogApi) {
   1222         ALOGD("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
   1223               (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
   1224     }
   1225     return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type,
   1226                                                       (RsAllocationMipmapControl)mips,
   1227                                                       (uint32_t)usage, (uintptr_t)pointer);
   1228 }
   1229 
   1230 static void
   1231 nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
   1232 {
   1233     if (kLogApi) {
   1234         ALOGD("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a,
   1235               bits);
   1236     }
   1237     rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
   1238 }
   1239 
   1240 static void
   1241 nAllocationSetupBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint numAlloc)
   1242 {
   1243     if (kLogApi) {
   1244         ALOGD("nAllocationSetupBufferQueue, con(%p), alloc(%p), numAlloc(%d)", (RsContext)con,
   1245               (RsAllocation)alloc, numAlloc);
   1246     }
   1247     rsAllocationSetupBufferQueue((RsContext)con, (RsAllocation)alloc, (uint32_t)numAlloc);
   1248 }
   1249 
   1250 static void
   1251 nAllocationShareBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc1, jlong alloc2)
   1252 {
   1253     if (kLogApi) {
   1254         ALOGD("nAllocationShareBufferQueue, con(%p), alloc1(%p), alloc2(%p)", (RsContext)con,
   1255               (RsAllocation)alloc1, (RsAllocation)alloc2);
   1256     }
   1257 
   1258     rsAllocationShareBufferQueue((RsContext)con, (RsAllocation)alloc1, (RsAllocation)alloc2);
   1259 }
   1260 
   1261 static jobject
   1262 nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
   1263 {
   1264     if (kLogApi) {
   1265         ALOGD("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
   1266     }
   1267 
   1268     ANativeWindow *anw = (ANativeWindow *)rsAllocationGetSurface((RsContext)con, (RsAllocation)a);
   1269 
   1270     sp<Surface> surface(static_cast<Surface*>(anw));
   1271     sp<IGraphicBufferProducer> bp = surface->getIGraphicBufferProducer();
   1272 
   1273     jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp);
   1274     return o;
   1275 }
   1276 
   1277 static void
   1278 nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
   1279 {
   1280     if (kLogApi) {
   1281         ALOGD("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)", (RsContext)con,
   1282               (RsAllocation)alloc, (Surface *)sur);
   1283     }
   1284 
   1285     ANativeWindow *anw = nullptr;
   1286     if (sur != 0) {
   1287         // Connect the native window handle to buffer queue.
   1288         anw = ANativeWindow_fromSurface(_env, sur);
   1289         native_window_api_connect(anw, NATIVE_WINDOW_API_CPU);
   1290     }
   1291 
   1292     rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, anw);
   1293 }
   1294 
   1295 static void
   1296 nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
   1297 {
   1298     if (kLogApi) {
   1299         ALOGD("nAllocationIoSend, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
   1300     }
   1301     rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
   1302 }
   1303 
   1304 static jlong
   1305 nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
   1306 {
   1307     if (kLogApi) {
   1308         ALOGD("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
   1309     }
   1310     return (jlong) rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
   1311 }
   1312 
   1313 static void
   1314 nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
   1315 {
   1316     if (kLogApi) {
   1317         ALOGD("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
   1318     }
   1319     rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
   1320 }
   1321 
   1322 static jlong
   1323 nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
   1324                             jobject jbitmap, jint usage)
   1325 {
   1326     SkBitmap bitmap;
   1327     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
   1328 
   1329     const void* ptr = bitmap.getPixels();
   1330     jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
   1331                                                   (RsType)type, (RsAllocationMipmapControl)mip,
   1332                                                   ptr, bitmap.computeByteSize(), usage);
   1333     return id;
   1334 }
   1335 
   1336 static jlong
   1337 nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
   1338                                         jint mip, jobject jbitmap, jint usage)
   1339 {
   1340     SkBitmap bitmap;
   1341     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
   1342 
   1343     const void* ptr = bitmap.getPixels();
   1344     jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
   1345                                             (RsType)type, (RsAllocationMipmapControl)mip,
   1346                                             (uint32_t)usage, (uintptr_t)ptr);
   1347     return id;
   1348 }
   1349 
   1350 static jlong
   1351 nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
   1352                                 jobject jbitmap, jint usage)
   1353 {
   1354     SkBitmap bitmap;
   1355     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
   1356 
   1357     const void* ptr = bitmap.getPixels();
   1358     jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
   1359                                                       (RsType)type, (RsAllocationMipmapControl)mip,
   1360                                                       ptr, bitmap.computeByteSize(), usage);
   1361     return id;
   1362 }
   1363 
   1364 static void
   1365 nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
   1366 {
   1367     SkBitmap bitmap;
   1368     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
   1369     int w = bitmap.width();
   1370     int h = bitmap.height();
   1371 
   1372     const void* ptr = bitmap.getPixels();
   1373     rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
   1374                        0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
   1375                        w, h, ptr, bitmap.computeByteSize(), 0);
   1376 }
   1377 
   1378 static void
   1379 nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
   1380 {
   1381     SkBitmap bitmap;
   1382     GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
   1383 
   1384     void* ptr = bitmap.getPixels();
   1385     rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.computeByteSize());
   1386     bitmap.notifyPixelsChanged();
   1387 }
   1388 
   1389 // Copies from the Java object data into the Allocation pointed to by _alloc.
   1390 static void
   1391 nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
   1392                   jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
   1393                   jboolean usePadding)
   1394 {
   1395     RsAllocation *alloc = (RsAllocation *)_alloc;
   1396     if (kLogApi) {
   1397         ALOGD("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
   1398               "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
   1399               dataType);
   1400     }
   1401     PER_ARRAY_TYPE(nullptr, rsAllocation1DData, true,
   1402                    (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
   1403 }
   1404 
   1405 static void
   1406 nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
   1407                        jint xoff, jint yoff, jint zoff,
   1408                        jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
   1409 {
   1410     if (kLogApi) {
   1411         jint len = _env->GetArrayLength(data);
   1412         ALOGD("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
   1413               "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
   1414               sizeBytes);
   1415     }
   1416     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1417     if (ptr == nullptr) {
   1418         ALOGE("Failed to get Java array elements");
   1419         return;
   1420     }
   1421     rsAllocationElementData((RsContext)con, (RsAllocation)alloc,
   1422                             xoff, yoff, zoff,
   1423                             lod, ptr, sizeBytes, compIdx);
   1424     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1425 }
   1426 
   1427 
   1428 // Copies from the Java object data into the Allocation pointed to by _alloc.
   1429 static void
   1430 nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
   1431                   jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
   1432                   jboolean usePadding)
   1433 {
   1434     RsAllocation *alloc = (RsAllocation *)_alloc;
   1435     RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
   1436     if (kLogApi) {
   1437         ALOGD("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
   1438               "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
   1439     }
   1440     int count = w * h;
   1441     PER_ARRAY_TYPE(nullptr, rsAllocation2DData, true,
   1442                    (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
   1443 }
   1444 
   1445 // Copies from the Allocation pointed to by srcAlloc into the Allocation
   1446 // pointed to by dstAlloc.
   1447 static void
   1448 nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
   1449                         jlong dstAlloc, jint dstXoff, jint dstYoff,
   1450                         jint dstMip, jint dstFace,
   1451                         jint width, jint height,
   1452                         jlong srcAlloc, jint srcXoff, jint srcYoff,
   1453                         jint srcMip, jint srcFace)
   1454 {
   1455     if (kLogApi) {
   1456         ALOGD("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
   1457               " dstMip(%i), dstFace(%i), width(%i), height(%i),"
   1458               " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
   1459               (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
   1460               width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
   1461     }
   1462 
   1463     rsAllocationCopy2DRange((RsContext)con,
   1464                             (RsAllocation)dstAlloc,
   1465                             dstXoff, dstYoff,
   1466                             dstMip, dstFace,
   1467                             width, height,
   1468                             (RsAllocation)srcAlloc,
   1469                             srcXoff, srcYoff,
   1470                             srcMip, srcFace);
   1471 }
   1472 
   1473 // Copies from the Java object data into the Allocation pointed to by _alloc.
   1474 static void
   1475 nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
   1476                   jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
   1477                   jint mSize, jboolean usePadding)
   1478 {
   1479     RsAllocation *alloc = (RsAllocation *)_alloc;
   1480     if (kLogApi) {
   1481         ALOGD("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
   1482               " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
   1483               lod, w, h, d, sizeBytes);
   1484     }
   1485     int count = w * h * d;
   1486     PER_ARRAY_TYPE(nullptr, rsAllocation3DData, true,
   1487                    (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
   1488 }
   1489 
   1490 // Copies from the Allocation pointed to by srcAlloc into the Allocation
   1491 // pointed to by dstAlloc.
   1492 static void
   1493 nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
   1494                         jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
   1495                         jint dstMip,
   1496                         jint width, jint height, jint depth,
   1497                         jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
   1498                         jint srcMip)
   1499 {
   1500     if (kLogApi) {
   1501         ALOGD("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
   1502               " dstMip(%i), width(%i), height(%i),"
   1503               " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
   1504               (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip,
   1505               width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip);
   1506     }
   1507 
   1508     rsAllocationCopy3DRange((RsContext)con,
   1509                             (RsAllocation)dstAlloc,
   1510                             dstXoff, dstYoff, dstZoff, dstMip,
   1511                             width, height, depth,
   1512                             (RsAllocation)srcAlloc,
   1513                             srcXoff, srcYoff, srcZoff, srcMip);
   1514 }
   1515 
   1516 
   1517 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1518 static void
   1519 nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
   1520                 jint mSize, jboolean usePadding)
   1521 {
   1522     RsAllocation *alloc = (RsAllocation *)_alloc;
   1523     if (kLogApi) {
   1524         ALOGD("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
   1525     }
   1526     int count = 0;
   1527     PER_ARRAY_TYPE(0, rsAllocationRead, false,
   1528                    (RsContext)con, alloc, ptr, len * typeBytes);
   1529 }
   1530 
   1531 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1532 static void
   1533 nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
   1534                   jint count, jobject data, jint sizeBytes, jint dataType,
   1535                   jint mSize, jboolean usePadding)
   1536 {
   1537     RsAllocation *alloc = (RsAllocation *)_alloc;
   1538     if (kLogApi) {
   1539         ALOGD("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
   1540               "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
   1541     }
   1542     PER_ARRAY_TYPE(0, rsAllocation1DRead, false,
   1543                    (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
   1544 }
   1545 
   1546 // Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
   1547 static void
   1548 nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
   1549                        jint xoff, jint yoff, jint zoff,
   1550                        jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
   1551 {
   1552     if (kLogApi) {
   1553         jint len = _env->GetArrayLength(data);
   1554         ALOGD("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
   1555               "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
   1556               sizeBytes);
   1557     }
   1558     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1559     if (ptr == nullptr) {
   1560         ALOGE("Failed to get Java array elements");
   1561         return;
   1562     }
   1563     rsAllocationElementRead((RsContext)con, (RsAllocation)alloc,
   1564                             xoff, yoff, zoff,
   1565                             lod, ptr, sizeBytes, compIdx);
   1566     _env->ReleaseByteArrayElements(data, ptr, 0);
   1567 }
   1568 
   1569 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1570 static void
   1571 nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
   1572                   jint w, jint h, jobject data, jint sizeBytes, jint dataType,
   1573                   jint mSize, jboolean usePadding)
   1574 {
   1575     RsAllocation *alloc = (RsAllocation *)_alloc;
   1576     RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
   1577     if (kLogApi) {
   1578         ALOGD("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
   1579               "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
   1580     }
   1581     int count = w * h;
   1582     PER_ARRAY_TYPE(0, rsAllocation2DRead, false,
   1583                    (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
   1584 }
   1585 
   1586 // Copies from the Allocation pointed to by _alloc into the Java object data.
   1587 static void
   1588 nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
   1589                   jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
   1590                   jint mSize, jboolean usePadding)
   1591 {
   1592     RsAllocation *alloc = (RsAllocation *)_alloc;
   1593     if (kLogApi) {
   1594         ALOGD("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
   1595               " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
   1596               lod, w, h, d, sizeBytes);
   1597     }
   1598     int count = w * h * d;
   1599     PER_ARRAY_TYPE(nullptr, rsAllocation3DRead, false,
   1600                    (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
   1601 }
   1602 
   1603 static jlong
   1604 nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
   1605 {
   1606     if (kLogApi) {
   1607         ALOGD("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
   1608     }
   1609     return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
   1610 }
   1611 
   1612 static void
   1613 nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
   1614 {
   1615     if (kLogApi) {
   1616         ALOGD("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
   1617               (RsAllocation)alloc, dimX);
   1618     }
   1619     rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
   1620 }
   1621 
   1622 
   1623 static jlong
   1624 nAllocationAdapterCreate(JNIEnv *_env, jobject _this, jlong con, jlong basealloc, jlong type)
   1625 {
   1626     if (kLogApi) {
   1627         ALOGD("nAllocationAdapterCreate, con(%p), base(%p), type(%p)",
   1628               (RsContext)con, (RsAllocation)basealloc, (RsElement)type);
   1629     }
   1630     return (jlong)(uintptr_t) rsAllocationAdapterCreate((RsContext)con, (RsType)type,
   1631                                                         (RsAllocation)basealloc);
   1632 
   1633 }
   1634 
   1635 static void
   1636 nAllocationAdapterOffset(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
   1637                         jint x, jint y, jint z, jint face, jint lod,
   1638                         jint a1, jint a2, jint a3, jint a4)
   1639 {
   1640     uint32_t params[] = {
   1641         (uint32_t)x, (uint32_t)y, (uint32_t)z, (uint32_t)face,
   1642         (uint32_t)lod, (uint32_t)a1, (uint32_t)a2, (uint32_t)a3, (uint32_t)a4
   1643     };
   1644     if (kLogApi) {
   1645         ALOGD("nAllocationAdapterOffset, con(%p), alloc(%p), x(%i), y(%i), z(%i), face(%i), lod(%i), arrays(%i %i %i %i)",
   1646               (RsContext)con, (RsAllocation)alloc, x, y, z, face, lod, a1, a2, a3, a4);
   1647     }
   1648     rsAllocationAdapterOffset((RsContext)con, (RsAllocation)alloc,
   1649                               params, sizeof(params));
   1650 }
   1651 
   1652 
   1653 // -----------------------------------
   1654 
   1655 static jlong
   1656 nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset)
   1657 {
   1658     Asset* asset = reinterpret_cast<Asset*>(native_asset);
   1659     ALOGV("______nFileA3D %p", asset);
   1660 
   1661     jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
   1662     return id;
   1663 }
   1664 
   1665 static jlong
   1666 nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
   1667 {
   1668     Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(_env, _assetMgr);
   1669     if (mgr == nullptr) {
   1670         return 0;
   1671     }
   1672 
   1673     AutoJavaStringToUTF8 str(_env, _path);
   1674     std::unique_ptr<Asset> asset;
   1675     {
   1676         ScopedLock<AssetManager2> locked_mgr(*mgr);
   1677         asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER);
   1678         if (asset == nullptr) {
   1679             return 0;
   1680         }
   1681     }
   1682 
   1683     jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset.release());
   1684     return id;
   1685 }
   1686 
   1687 static jlong
   1688 nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
   1689 {
   1690     AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
   1691     jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
   1692 
   1693     return id;
   1694 }
   1695 
   1696 static jint
   1697 nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D)
   1698 {
   1699     int32_t numEntries = 0;
   1700     rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D);
   1701     return (jint)numEntries;
   1702 }
   1703 
   1704 static void
   1705 nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
   1706 {
   1707     ALOGV("______nFileA3D %p", (RsFile) fileA3D);
   1708     RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
   1709 
   1710     rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
   1711 
   1712     for(jint i = 0; i < numEntries; i ++) {
   1713         _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
   1714         _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
   1715     }
   1716 
   1717     free(fileEntries);
   1718 }
   1719 
   1720 static jlong
   1721 nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
   1722 {
   1723     ALOGV("______nFileA3D %p", (RsFile) fileA3D);
   1724     jlong id = (jlong)(uintptr_t)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
   1725     return id;
   1726 }
   1727 
   1728 // -----------------------------------
   1729 
   1730 static jlong
   1731 nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con,
   1732                     jstring fileName, jfloat fontSize, jint dpi)
   1733 {
   1734     AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
   1735     jlong id = (jlong)(uintptr_t)rsFontCreateFromFile((RsContext)con,
   1736                                          fileNameUTF.c_str(), fileNameUTF.length(),
   1737                                          fontSize, dpi);
   1738 
   1739     return id;
   1740 }
   1741 
   1742 static jlong
   1743 nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con,
   1744                            jstring name, jfloat fontSize, jint dpi, jlong native_asset)
   1745 {
   1746     Asset* asset = reinterpret_cast<Asset*>(native_asset);
   1747     AutoJavaStringToUTF8 nameUTF(_env, name);
   1748 
   1749     jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
   1750                                            nameUTF.c_str(), nameUTF.length(),
   1751                                            fontSize, dpi,
   1752                                            asset->getBuffer(false), asset->getLength());
   1753     return id;
   1754 }
   1755 
   1756 static jlong
   1757 nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
   1758                      jfloat fontSize, jint dpi)
   1759 {
   1760     Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(_env, _assetMgr);
   1761     if (mgr == nullptr) {
   1762         return 0;
   1763     }
   1764 
   1765     AutoJavaStringToUTF8 str(_env, _path);
   1766     std::unique_ptr<Asset> asset;
   1767     {
   1768         ScopedLock<AssetManager2> locked_mgr(*mgr);
   1769         asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER);
   1770         if (asset == nullptr) {
   1771             return 0;
   1772         }
   1773     }
   1774 
   1775     jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
   1776                                            str.c_str(), str.length(),
   1777                                            fontSize, dpi,
   1778                                            asset->getBuffer(false), asset->getLength());
   1779     return id;
   1780 }
   1781 
   1782 // -----------------------------------
   1783 
   1784 static void
   1785 nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
   1786 {
   1787     if (kLogApi) {
   1788         ALOGD("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con,
   1789               (RsScript)script, (RsAllocation)alloc, slot);
   1790     }
   1791     rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
   1792 }
   1793 
   1794 static void
   1795 nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
   1796 {
   1797     if (kLogApi) {
   1798         ALOGD("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script,
   1799               slot, val);
   1800     }
   1801     rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
   1802 }
   1803 
   1804 static jint
   1805 nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
   1806 {
   1807     if (kLogApi) {
   1808         ALOGD("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1809     }
   1810     int value = 0;
   1811     rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
   1812     return value;
   1813 }
   1814 
   1815 static void
   1816 nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
   1817 {
   1818     if (kLogApi) {
   1819         ALOGD("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
   1820               slot, val);
   1821     }
   1822     rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
   1823 }
   1824 
   1825 static void
   1826 nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
   1827 {
   1828     if (kLogApi) {
   1829         ALOGD("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
   1830               slot, val);
   1831     }
   1832     rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
   1833 }
   1834 
   1835 static jlong
   1836 nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
   1837 {
   1838     if (kLogApi) {
   1839         ALOGD("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1840     }
   1841     jlong value = 0;
   1842     rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
   1843     return value;
   1844 }
   1845 
   1846 static void
   1847 nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
   1848 {
   1849     if (kLogApi) {
   1850         ALOGD("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script,
   1851               slot, val);
   1852     }
   1853     rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
   1854 }
   1855 
   1856 static jfloat
   1857 nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
   1858 {
   1859     if (kLogApi) {
   1860         ALOGD("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1861     }
   1862     jfloat value = 0;
   1863     rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
   1864     return value;
   1865 }
   1866 
   1867 static void
   1868 nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
   1869 {
   1870     if (kLogApi) {
   1871         ALOGD("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script,
   1872               slot, val);
   1873     }
   1874     rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
   1875 }
   1876 
   1877 static jdouble
   1878 nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
   1879 {
   1880     if (kLogApi) {
   1881         ALOGD("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1882     }
   1883     jdouble value = 0;
   1884     rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
   1885     return value;
   1886 }
   1887 
   1888 static void
   1889 nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
   1890 {
   1891     if (kLogApi) {
   1892         ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1893     }
   1894     jint len = _env->GetArrayLength(data);
   1895     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1896     if (ptr == nullptr) {
   1897         ALOGE("Failed to get Java array elements");
   1898         return;
   1899     }
   1900     rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
   1901     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1902 }
   1903 
   1904 static void
   1905 nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
   1906 {
   1907     if (kLogApi) {
   1908         ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1909     }
   1910     jint len = _env->GetArrayLength(data);
   1911     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1912     if (ptr == nullptr) {
   1913         ALOGE("Failed to get Java array elements");
   1914         return;
   1915     }
   1916     rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
   1917     _env->ReleaseByteArrayElements(data, ptr, 0);
   1918 }
   1919 
   1920 static void
   1921 nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
   1922                 jlong elem, jintArray dims)
   1923 {
   1924     if (kLogApi) {
   1925         ALOGD("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1926     }
   1927     jint len = _env->GetArrayLength(data);
   1928     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1929     if (ptr == nullptr) {
   1930         ALOGE("Failed to get Java array elements");
   1931         return;
   1932     }
   1933     jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
   1934     jint *dimsPtr = _env->GetIntArrayElements(dims, nullptr);
   1935     if (dimsPtr == nullptr) {
   1936         ALOGE("Failed to get Java array elements");
   1937         return;
   1938     }
   1939     rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
   1940                      (const uint32_t*) dimsPtr, dimsLen);
   1941     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1942     _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
   1943 }
   1944 
   1945 
   1946 static void
   1947 nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
   1948 {
   1949     if (kLogApi) {
   1950         ALOGD("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
   1951     }
   1952 
   1953     jint length = _env->GetArrayLength(timeZone);
   1954     jbyte* timeZone_ptr;
   1955     timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
   1956     if (timeZone_ptr == nullptr) {
   1957         ALOGE("Failed to get Java array elements");
   1958         return;
   1959     }
   1960 
   1961     rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
   1962 
   1963     if (timeZone_ptr) {
   1964         _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
   1965     }
   1966 }
   1967 
   1968 static void
   1969 nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
   1970 {
   1971     if (kLogApi) {
   1972         ALOGD("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
   1973     }
   1974     rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
   1975 }
   1976 
   1977 static void
   1978 nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
   1979 {
   1980     if (kLogApi) {
   1981         ALOGD("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
   1982     }
   1983     jint len = _env->GetArrayLength(data);
   1984     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
   1985     if (ptr == nullptr) {
   1986         ALOGE("Failed to get Java array elements");
   1987         return;
   1988     }
   1989     rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
   1990     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
   1991 }
   1992 
   1993 static void
   1994 nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
   1995                jlongArray ains, jlong aout, jbyteArray params,
   1996                jintArray limits)
   1997 {
   1998     if (kLogApi) {
   1999         ALOGD("nScriptForEach, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
   2000     }
   2001 
   2002     jint   in_len = 0;
   2003     jlong *in_ptr = nullptr;
   2004 
   2005     RsAllocation *in_allocs = nullptr;
   2006 
   2007     if (ains != nullptr) {
   2008         in_len = _env->GetArrayLength(ains);
   2009         if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
   2010             ALOGE("Too many arguments in kernel launch.");
   2011             // TODO (b/20758983): Report back to Java and throw an exception
   2012             return;
   2013         }
   2014 
   2015         in_ptr = _env->GetLongArrayElements(ains, nullptr);
   2016         if (in_ptr == nullptr) {
   2017             ALOGE("Failed to get Java array elements");
   2018             return;
   2019         }
   2020 
   2021         if (sizeof(RsAllocation) == sizeof(jlong)) {
   2022             in_allocs = (RsAllocation*)in_ptr;
   2023         } else {
   2024             // Convert from 64-bit jlong types to the native pointer type.
   2025 
   2026             in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
   2027             if (in_allocs == nullptr) {
   2028                 ALOGE("Failed launching kernel for lack of memory.");
   2029                 _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
   2030                 return;
   2031             }
   2032 
   2033             for (int index = in_len; --index >= 0;) {
   2034                 in_allocs[index] = (RsAllocation)in_ptr[index];
   2035             }
   2036         }
   2037     }
   2038 
   2039     jint   param_len = 0;
   2040     jbyte *param_ptr = nullptr;
   2041 
   2042     if (params != nullptr) {
   2043         param_len = _env->GetArrayLength(params);
   2044         param_ptr = _env->GetByteArrayElements(params, nullptr);
   2045         if (param_ptr == nullptr) {
   2046             ALOGE("Failed to get Java array elements");
   2047             return;
   2048         }
   2049     }
   2050 
   2051     RsScriptCall sc, *sca = nullptr;
   2052     uint32_t sc_size = 0;
   2053 
   2054     jint  limit_len = 0;
   2055     jint *limit_ptr = nullptr;
   2056 
   2057     if (limits != nullptr) {
   2058         limit_len = _env->GetArrayLength(limits);
   2059         limit_ptr = _env->GetIntArrayElements(limits, nullptr);
   2060         if (limit_ptr == nullptr) {
   2061             ALOGE("Failed to get Java array elements");
   2062             return;
   2063         }
   2064 
   2065         assert(limit_len == 6);
   2066         UNUSED(limit_len);  // As the assert might not be compiled.
   2067 
   2068         sc.xStart     = limit_ptr[0];
   2069         sc.xEnd       = limit_ptr[1];
   2070         sc.yStart     = limit_ptr[2];
   2071         sc.yEnd       = limit_ptr[3];
   2072         sc.zStart     = limit_ptr[4];
   2073         sc.zEnd       = limit_ptr[5];
   2074         sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
   2075         sc.arrayStart = 0;
   2076         sc.arrayEnd = 0;
   2077         sc.array2Start = 0;
   2078         sc.array2End = 0;
   2079         sc.array3Start = 0;
   2080         sc.array3End = 0;
   2081         sc.array4Start = 0;
   2082         sc.array4End = 0;
   2083 
   2084         sca = &sc;
   2085         // sc_size is required, but unused, by the runtime and drivers.
   2086         sc_size = sizeof(sc);
   2087     }
   2088 
   2089     rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
   2090                          in_allocs, in_len, (RsAllocation)aout,
   2091                          param_ptr, param_len, sca, sc_size);
   2092 
   2093     if (ains != nullptr) {
   2094         _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
   2095     }
   2096 
   2097     if (params != nullptr) {
   2098         _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
   2099     }
   2100 
   2101     if (limits != nullptr) {
   2102         _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
   2103     }
   2104 }
   2105 
   2106 static void
   2107 nScriptReduce(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
   2108               jlongArray ains, jlong aout, jintArray limits)
   2109 {
   2110     if (kLogApi) {
   2111         ALOGD("nScriptReduce, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
   2112     }
   2113 
   2114     if (ains == nullptr) {
   2115         ALOGE("At least one input required.");
   2116         // TODO (b/20758983): Report back to Java and throw an exception
   2117         return;
   2118     }
   2119     jint in_len = _env->GetArrayLength(ains);
   2120     if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
   2121         ALOGE("Too many arguments in kernel launch.");
   2122         // TODO (b/20758983): Report back to Java and throw an exception
   2123         return;
   2124     }
   2125 
   2126     jlong *in_ptr = _env->GetLongArrayElements(ains, nullptr);
   2127     if (in_ptr == nullptr) {
   2128         ALOGE("Failed to get Java array elements");
   2129         // TODO (b/20758983): Report back to Java and throw an exception
   2130         return;
   2131     }
   2132 
   2133     RsAllocation *in_allocs = nullptr;
   2134     if (sizeof(RsAllocation) == sizeof(jlong)) {
   2135         in_allocs = (RsAllocation*)in_ptr;
   2136     } else {
   2137         // Convert from 64-bit jlong types to the native pointer type.
   2138 
   2139         in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
   2140         if (in_allocs == nullptr) {
   2141             ALOGE("Failed launching kernel for lack of memory.");
   2142             // TODO (b/20758983): Report back to Java and throw an exception
   2143             _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
   2144             return;
   2145         }
   2146 
   2147         for (int index = in_len; --index >= 0;) {
   2148             in_allocs[index] = (RsAllocation)in_ptr[index];
   2149         }
   2150     }
   2151 
   2152     RsScriptCall sc, *sca = nullptr;
   2153     uint32_t sc_size = 0;
   2154 
   2155     jint  limit_len = 0;
   2156     jint *limit_ptr = nullptr;
   2157 
   2158     if (limits != nullptr) {
   2159         limit_len = _env->GetArrayLength(limits);
   2160         limit_ptr = _env->GetIntArrayElements(limits, nullptr);
   2161         if (limit_ptr == nullptr) {
   2162             ALOGE("Failed to get Java array elements");
   2163             // TODO (b/20758983): Report back to Java and throw an exception
   2164             return;
   2165         }
   2166 
   2167         assert(limit_len == 6);
   2168         UNUSED(limit_len);  // As the assert might not be compiled.
   2169 
   2170         sc.xStart     = limit_ptr[0];
   2171         sc.xEnd       = limit_ptr[1];
   2172         sc.yStart     = limit_ptr[2];
   2173         sc.yEnd       = limit_ptr[3];
   2174         sc.zStart     = limit_ptr[4];
   2175         sc.zEnd       = limit_ptr[5];
   2176         sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
   2177         sc.arrayStart = 0;
   2178         sc.arrayEnd = 0;
   2179         sc.array2Start = 0;
   2180         sc.array2End = 0;
   2181         sc.array3Start = 0;
   2182         sc.array3End = 0;
   2183         sc.array4Start = 0;
   2184         sc.array4End = 0;
   2185 
   2186         sca = &sc;
   2187         sc_size = sizeof(sc);
   2188     }
   2189 
   2190     rsScriptReduce((RsContext)con, (RsScript)script, slot,
   2191                    in_allocs, in_len, (RsAllocation)aout,
   2192                    sca, sc_size);
   2193 
   2194     _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
   2195 
   2196     if (limits != nullptr) {
   2197         _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
   2198     }
   2199 }
   2200 
   2201 // -----------------------------------
   2202 
   2203 static jlong
   2204 nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
   2205                jstring resName, jstring cacheDir,
   2206                jbyteArray scriptRef, jint length)
   2207 {
   2208     if (kLogApi) {
   2209         ALOGD("nScriptCCreate, con(%p)", (RsContext)con);
   2210     }
   2211 
   2212     AutoJavaStringToUTF8 resNameUTF(_env, resName);
   2213     AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
   2214     jlong ret = 0;
   2215     jbyte* script_ptr = nullptr;
   2216     jint _exception = 0;
   2217     jint remaining;
   2218     if (!scriptRef) {
   2219         _exception = 1;
   2220         //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
   2221         goto exit;
   2222     }
   2223     if (length < 0) {
   2224         _exception = 1;
   2225         //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
   2226         goto exit;
   2227     }
   2228     remaining = _env->GetArrayLength(scriptRef);
   2229     if (remaining < length) {
   2230         _exception = 1;
   2231         //jniThrowException(_env, "java/lang/IllegalArgumentException",
   2232         //        "length > script.length - offset");
   2233         goto exit;
   2234     }
   2235     script_ptr = (jbyte *)
   2236         _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
   2237     if (script_ptr == nullptr) {
   2238         ALOGE("Failed to get Java array elements");
   2239         return ret;
   2240     }
   2241 
   2242     //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
   2243 
   2244     ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
   2245                                 resNameUTF.c_str(), resNameUTF.length(),
   2246                                 cacheDirUTF.c_str(), cacheDirUTF.length(),
   2247                                 (const char *)script_ptr, length);
   2248 
   2249 exit:
   2250     if (script_ptr) {
   2251         _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
   2252                 _exception ? JNI_ABORT: 0);
   2253     }
   2254 
   2255     return (jlong)(uintptr_t)ret;
   2256 }
   2257 
   2258 static jlong
   2259 nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
   2260 {
   2261     if (kLogApi) {
   2262         ALOGD("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id,
   2263               (void *)eid);
   2264     }
   2265     return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
   2266 }
   2267 
   2268 static jlong
   2269 nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
   2270 {
   2271     if (kLogApi) {
   2272         ALOGD("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
   2273               (void *)sid, slot, sig);
   2274     }
   2275     return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
   2276 }
   2277 
   2278 static jlong
   2279 nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
   2280 {
   2281     if (kLogApi) {
   2282         ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con,
   2283               (void *)sid, slot);
   2284     }
   2285     return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
   2286 }
   2287 
   2288 static jlong
   2289 nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
   2290 {
   2291     if (kLogApi) {
   2292         ALOGD("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid,
   2293               slot);
   2294     }
   2295     return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
   2296 }
   2297 
   2298 static jlong
   2299 nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
   2300     jlongArray _dstk, jlongArray _dstf, jlongArray _types)
   2301 {
   2302     if (kLogApi) {
   2303         ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
   2304     }
   2305 
   2306     jlong id = 0;
   2307 
   2308     RsScriptKernelID* kernelsPtr;
   2309     jint kernelsLen = _env->GetArrayLength(_kernels);
   2310     jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
   2311 
   2312     RsScriptKernelID* srcPtr;
   2313     jint srcLen = _env->GetArrayLength(_src);
   2314     jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
   2315 
   2316     RsScriptKernelID* dstkPtr;
   2317     jint dstkLen = _env->GetArrayLength(_dstk);
   2318     jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
   2319 
   2320     RsScriptKernelID* dstfPtr;
   2321     jint dstfLen = _env->GetArrayLength(_dstf);
   2322     jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
   2323 
   2324     RsType* typesPtr;
   2325     jint typesLen = _env->GetArrayLength(_types);
   2326     jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
   2327 
   2328     if (jKernelsPtr == nullptr) {
   2329         ALOGE("Failed to get Java array elements: kernels");
   2330         goto cleanup;
   2331     }
   2332     if (jSrcPtr == nullptr) {
   2333         ALOGE("Failed to get Java array elements: src");
   2334         goto cleanup;
   2335     }
   2336     if (jDstkPtr == nullptr) {
   2337         ALOGE("Failed to get Java array elements: dstk");
   2338         goto cleanup;
   2339     }
   2340     if (jDstfPtr == nullptr) {
   2341         ALOGE("Failed to get Java array elements: dstf");
   2342         goto cleanup;
   2343     }
   2344     if (jTypesPtr == nullptr) {
   2345         ALOGE("Failed to get Java array elements: types");
   2346         goto cleanup;
   2347     }
   2348 
   2349     kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
   2350     for(int i = 0; i < kernelsLen; ++i) {
   2351         kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
   2352     }
   2353 
   2354     srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
   2355     for(int i = 0; i < srcLen; ++i) {
   2356         srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
   2357     }
   2358 
   2359     dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
   2360     for(int i = 0; i < dstkLen; ++i) {
   2361         dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
   2362     }
   2363 
   2364     dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
   2365     for(int i = 0; i < dstfLen; ++i) {
   2366         dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
   2367     }
   2368 
   2369     typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
   2370     for(int i = 0; i < typesLen; ++i) {
   2371         typesPtr[i] = (RsType)jTypesPtr[i];
   2372     }
   2373 
   2374     id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
   2375                                (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
   2376                                (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
   2377                                (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
   2378                                (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
   2379                                (RsType *)typesPtr, typesLen * sizeof(RsType));
   2380 
   2381     free(kernelsPtr);
   2382     free(srcPtr);
   2383     free(dstkPtr);
   2384     free(dstfPtr);
   2385     free(typesPtr);
   2386 
   2387 cleanup:
   2388     if (jKernelsPtr != nullptr) {
   2389         _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
   2390     }
   2391     if (jSrcPtr != nullptr) {
   2392         _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
   2393     }
   2394     if (jDstkPtr != nullptr) {
   2395         _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
   2396     }
   2397     if (jDstfPtr != nullptr) {
   2398         _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
   2399     }
   2400     if (jTypesPtr != nullptr) {
   2401         _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
   2402     }
   2403 
   2404     return id;
   2405 }
   2406 
   2407 static void
   2408 nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
   2409 {
   2410     if (kLogApi) {
   2411         ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
   2412               (void *)gid, (void *)kid, (void *)alloc);
   2413     }
   2414     rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
   2415 }
   2416 
   2417 static void
   2418 nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
   2419 {
   2420     if (kLogApi) {
   2421         ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
   2422               (void *)gid, (void *)kid, (void *)alloc);
   2423     }
   2424     rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
   2425 }
   2426 
   2427 static void
   2428 nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
   2429 {
   2430     if (kLogApi) {
   2431         ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
   2432     }
   2433     rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
   2434 }
   2435 
   2436 // ---------------------------------------------------------------------------
   2437 
   2438 static jlong
   2439 nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
   2440                     jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
   2441                     jboolean depthMask, jboolean ditherEnable,
   2442                     jint srcFunc, jint destFunc,
   2443                     jint depthFunc)
   2444 {
   2445     if (kLogApi) {
   2446         ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
   2447     }
   2448     return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
   2449                                       depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
   2450                                       (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
   2451 }
   2452 
   2453 // ---------------------------------------------------------------------------
   2454 
   2455 static void
   2456 nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
   2457 {
   2458     if (kLogApi) {
   2459         ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
   2460               (RsProgramVertex)vpv, slot, (RsAllocation)a);
   2461     }
   2462     rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
   2463 }
   2464 
   2465 static void
   2466 nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
   2467 {
   2468     if (kLogApi) {
   2469         ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
   2470               (RsProgramFragment)vpf, slot, (RsAllocation)a);
   2471     }
   2472     rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
   2473 }
   2474 
   2475 static void
   2476 nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
   2477 {
   2478     if (kLogApi) {
   2479         ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
   2480               (RsProgramFragment)vpf, slot, (RsSampler)a);
   2481     }
   2482     rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
   2483 }
   2484 
   2485 // ---------------------------------------------------------------------------
   2486 
   2487 static jlong
   2488 nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
   2489                        jobjectArray texNames, jlongArray params)
   2490 {
   2491     AutoJavaStringToUTF8 shaderUTF(_env, shader);
   2492     jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
   2493     jint paramLen = _env->GetArrayLength(params);
   2494     if (jParamPtr == nullptr) {
   2495         ALOGE("Failed to get Java array elements");
   2496         return 0;
   2497     }
   2498 
   2499     int texCount = _env->GetArrayLength(texNames);
   2500     AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
   2501     const char ** nameArray = names.c_str();
   2502     size_t* sizeArray = names.c_str_len();
   2503 
   2504     if (kLogApi) {
   2505         ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
   2506     }
   2507 
   2508     uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
   2509     for(int i = 0; i < paramLen; ++i) {
   2510         paramPtr[i] = (uintptr_t)jParamPtr[i];
   2511     }
   2512     jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
   2513                                              nameArray, texCount, sizeArray,
   2514                                              paramPtr, paramLen);
   2515 
   2516     free(paramPtr);
   2517     _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
   2518     return ret;
   2519 }
   2520 
   2521 
   2522 // ---------------------------------------------------------------------------
   2523 
   2524 static jlong
   2525 nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
   2526                      jobjectArray texNames, jlongArray params)
   2527 {
   2528     AutoJavaStringToUTF8 shaderUTF(_env, shader);
   2529     jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
   2530     jint paramLen = _env->GetArrayLength(params);
   2531     if (jParamPtr == nullptr) {
   2532         ALOGE("Failed to get Java array elements");
   2533         return 0;
   2534     }
   2535 
   2536     if (kLogApi) {
   2537         ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
   2538     }
   2539 
   2540     int texCount = _env->GetArrayLength(texNames);
   2541     AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
   2542     const char ** nameArray = names.c_str();
   2543     size_t* sizeArray = names.c_str_len();
   2544 
   2545     uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
   2546     for(int i = 0; i < paramLen; ++i) {
   2547         paramPtr[i] = (uintptr_t)jParamPtr[i];
   2548     }
   2549 
   2550     jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
   2551                                            nameArray, texCount, sizeArray,
   2552                                            paramPtr, paramLen);
   2553 
   2554     free(paramPtr);
   2555     _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
   2556     return ret;
   2557 }
   2558 
   2559 // ---------------------------------------------------------------------------
   2560 
   2561 static jlong
   2562 nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
   2563 {
   2564     if (kLogApi) {
   2565         ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
   2566               pointSprite, cull);
   2567     }
   2568     return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
   2569 }
   2570 
   2571 
   2572 // ---------------------------------------------------------------------------
   2573 
   2574 static void
   2575 nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
   2576 {
   2577     if (kLogApi) {
   2578         ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
   2579     }
   2580     rsContextBindRootScript((RsContext)con, (RsScript)script);
   2581 }
   2582 
   2583 static void
   2584 nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
   2585 {
   2586     if (kLogApi) {
   2587         ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
   2588     }
   2589     rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
   2590 }
   2591 
   2592 static void
   2593 nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
   2594 {
   2595     if (kLogApi) {
   2596         ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
   2597               (RsProgramFragment)pf);
   2598     }
   2599     rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
   2600 }
   2601 
   2602 static void
   2603 nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
   2604 {
   2605     if (kLogApi) {
   2606         ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
   2607     }
   2608     rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
   2609 }
   2610 
   2611 static void
   2612 nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
   2613 {
   2614     if (kLogApi) {
   2615         ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
   2616     }
   2617     rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
   2618 }
   2619 
   2620 
   2621 // ---------------------------------------------------------------------------
   2622 
   2623 static jlong
   2624 nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
   2625                jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
   2626 {
   2627     if (kLogApi) {
   2628         ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
   2629     }
   2630     return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
   2631                                  (RsSamplerValue)magFilter,
   2632                                  (RsSamplerValue)minFilter,
   2633                                  (RsSamplerValue)wrapS,
   2634                                  (RsSamplerValue)wrapT,
   2635                                  (RsSamplerValue)wrapR,
   2636                                  aniso);
   2637 }
   2638 
   2639 // ---------------------------------------------------------------------------
   2640 
   2641 static jlong
   2642 nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
   2643 {
   2644     if (kLogApi) {
   2645         ALOGD("nMeshCreate, con(%p)", (RsContext)con);
   2646     }
   2647 
   2648     jlong id = 0;
   2649 
   2650     RsAllocation* vtxPtr;
   2651     jint vtxLen = _env->GetArrayLength(_vtx);
   2652     jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
   2653 
   2654     RsAllocation* idxPtr;
   2655     jint idxLen = _env->GetArrayLength(_idx);
   2656     jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
   2657 
   2658     jint primLen = _env->GetArrayLength(_prim);
   2659     jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
   2660 
   2661     if (jVtxPtr == nullptr) {
   2662         ALOGE("Failed to get Java array elements: vtx");
   2663         goto cleanupMesh;
   2664     }
   2665     if (jIdxPtr == nullptr) {
   2666         ALOGE("Failed to get Java array elements: idx");
   2667         goto cleanupMesh;
   2668     }
   2669     if (primPtr == nullptr) {
   2670         ALOGE("Failed to get Java array elements: prim");
   2671         goto cleanupMesh;
   2672     }
   2673 
   2674     vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
   2675     for(int i = 0; i < vtxLen; ++i) {
   2676         vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
   2677     }
   2678 
   2679     idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
   2680     for(int i = 0; i < idxLen; ++i) {
   2681         idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
   2682     }
   2683 
   2684     id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
   2685                                         (RsAllocation *)vtxPtr, vtxLen,
   2686                                         (RsAllocation *)idxPtr, idxLen,
   2687                                         (uint32_t *)primPtr, primLen);
   2688 
   2689     free(vtxPtr);
   2690     free(idxPtr);
   2691 
   2692 cleanupMesh:
   2693     if (jVtxPtr != nullptr) {
   2694         _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
   2695     }
   2696     if (jIdxPtr != nullptr) {
   2697         _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
   2698     }
   2699     if (primPtr != nullptr) {
   2700         _env->ReleaseIntArrayElements(_prim, primPtr, 0);
   2701     }
   2702 
   2703     return id;
   2704 }
   2705 
   2706 static jint
   2707 nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
   2708 {
   2709     if (kLogApi) {
   2710         ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
   2711     }
   2712     jint vtxCount = 0;
   2713     rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
   2714     return vtxCount;
   2715 }
   2716 
   2717 static jint
   2718 nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
   2719 {
   2720     if (kLogApi) {
   2721         ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
   2722     }
   2723     jint idxCount = 0;
   2724     rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
   2725     return idxCount;
   2726 }
   2727 
   2728 static void
   2729 nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
   2730 {
   2731     if (kLogApi) {
   2732         ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
   2733     }
   2734 
   2735     RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
   2736     rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
   2737 
   2738     for(jint i = 0; i < numVtxIDs; i ++) {
   2739         const jlong alloc = (jlong)(uintptr_t)allocs[i];
   2740         _env->SetLongArrayRegion(_ids, i, 1, &alloc);
   2741     }
   2742 
   2743     free(allocs);
   2744 }
   2745 
   2746 static void
   2747 nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
   2748 {
   2749     if (kLogApi) {
   2750         ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
   2751     }
   2752 
   2753     RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
   2754     uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
   2755 
   2756     rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
   2757 
   2758     for(jint i = 0; i < numIndices; i ++) {
   2759         const jlong alloc = (jlong)(uintptr_t)allocs[i];
   2760         const jint prim = (jint)prims[i];
   2761         _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
   2762         _env->SetIntArrayRegion(_primitives, i, 1, &prim);
   2763     }
   2764 
   2765     free(allocs);
   2766     free(prims);
   2767 }
   2768 
   2769 static jint
   2770 nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
   2771     return (jint)sizeof(void*);
   2772 }
   2773 
   2774 static jobject
   2775 nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
   2776                         jlongArray strideArr, jint xBytesSize,
   2777                         jint dimY, jint dimZ) {
   2778     if (kLogApi) {
   2779         ALOGD("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
   2780     }
   2781 
   2782     jlong *jStridePtr = _env->GetLongArrayElements(strideArr, nullptr);
   2783     if (jStridePtr == nullptr) {
   2784         ALOGE("Failed to get Java array elements: strideArr");
   2785         return 0;
   2786     }
   2787 
   2788     size_t strideIn = xBytesSize;
   2789     void* ptr = nullptr;
   2790     if (alloc != 0) {
   2791         ptr = rsAllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
   2792                                      RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
   2793                                      &strideIn, sizeof(size_t));
   2794     }
   2795 
   2796     jobject byteBuffer = nullptr;
   2797     if (ptr != nullptr) {
   2798         size_t bufferSize = strideIn;
   2799         jStridePtr[0] = strideIn;
   2800         if (dimY > 0) {
   2801             bufferSize *= dimY;
   2802         }
   2803         if (dimZ > 0) {
   2804             bufferSize *= dimZ;
   2805         }
   2806         byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize);
   2807     }
   2808     _env->ReleaseLongArrayElements(strideArr, jStridePtr, 0);
   2809     return byteBuffer;
   2810 }
   2811 // ---------------------------------------------------------------------------
   2812 
   2813 
   2814 static const char *classPathName = "android/renderscript/RenderScript";
   2815 
   2816 static const JNINativeMethod methods[] = {
   2817 {"_nInit",                         "()V",                                     (void*)_nInit },
   2818 
   2819 {"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
   2820 {"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
   2821 {"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
   2822 {"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
   2823 {"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
   2824 {"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
   2825 
   2826 {"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
   2827 {"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
   2828 
   2829 
   2830 // All methods below are thread protected in java.
   2831 {"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
   2832 {"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
   2833 {"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
   2834 {"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
   2835 {"rsnContextSetCacheDir",            "(JLjava/lang/String;)V",                (void*)nContextSetCacheDir },
   2836 {"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
   2837 {"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
   2838 {"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
   2839 {"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
   2840 {"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
   2841 {"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
   2842 {"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
   2843 {"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
   2844 {"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
   2845 {"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
   2846 {"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
   2847 {"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
   2848 {"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
   2849 
   2850 {"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
   2851 {"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
   2852 {"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
   2853 {"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
   2854 {"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
   2855 {"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
   2856 
   2857 {"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
   2858 {"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
   2859 {"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
   2860 
   2861 {"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
   2862 {"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
   2863 {"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
   2864 {"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
   2865 
   2866 {"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
   2867 {"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
   2868 
   2869 {"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
   2870 {"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
   2871 {"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
   2872 {"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
   2873 
   2874 {"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
   2875 {"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
   2876 
   2877 {"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
   2878 {"rsnAllocationSetupBufferQueue",    "(JJI)V",                                (void*)nAllocationSetupBufferQueue },
   2879 {"rsnAllocationShareBufferQueue",    "(JJJ)V",                                (void*)nAllocationShareBufferQueue },
   2880 {"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
   2881 {"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
   2882 {"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
   2883 {"rsnAllocationIoReceive",           "(JJ)J",                                 (void*)nAllocationIoReceive },
   2884 {"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
   2885 {"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
   2886 {"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
   2887 {"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
   2888 {"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
   2889 {"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
   2890 {"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
   2891 {"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
   2892 {"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
   2893 {"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
   2894 {"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationRead3D },
   2895 {"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
   2896 {"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
   2897 {"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
   2898 
   2899 {"rsnAllocationAdapterCreate",       "(JJJ)J",                                (void*)nAllocationAdapterCreate },
   2900 {"rsnAllocationAdapterOffset",       "(JJIIIIIIIII)V",                        (void*)nAllocationAdapterOffset },
   2901 
   2902 {"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
   2903 {"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
   2904 {"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
   2905 {"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
   2906 
   2907 {"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
   2908 {"rsnScriptReduce",                  "(JJI[JJ[I)V",                           (void*)nScriptReduce },
   2909 
   2910 {"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
   2911 {"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
   2912 {"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
   2913 {"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
   2914 {"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
   2915 {"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
   2916 {"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
   2917 {"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
   2918 {"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
   2919 {"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
   2920 {"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
   2921 {"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
   2922 
   2923 {"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
   2924 {"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
   2925 {"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
   2926 {"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
   2927 {"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
   2928 {"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
   2929 {"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
   2930 {"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
   2931 {"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
   2932 {"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
   2933 {"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
   2934 
   2935 {"rsnScriptIntrinsicBLAS_Single",    "(JJIIIIIIIIIFJJFJIIII)V",               (void*)nScriptIntrinsicBLAS_Single },
   2936 {"rsnScriptIntrinsicBLAS_Double",    "(JJIIIIIIIIIDJJDJIIII)V",               (void*)nScriptIntrinsicBLAS_Double },
   2937 {"rsnScriptIntrinsicBLAS_Complex",   "(JJIIIIIIIIIFFJJFFJIIII)V",             (void*)nScriptIntrinsicBLAS_Complex },
   2938 {"rsnScriptIntrinsicBLAS_Z",         "(JJIIIIIIIIIDDJJDDJIIII)V",             (void*)nScriptIntrinsicBLAS_Z },
   2939 
   2940 {"rsnScriptIntrinsicBLAS_BNNM",      "(JJIIIJIJIJII)V",                       (void*)nScriptIntrinsicBLAS_BNNM },
   2941 
   2942 {"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
   2943 
   2944 {"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
   2945 {"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
   2946 {"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
   2947 
   2948 {"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
   2949 {"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
   2950 {"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
   2951 
   2952 {"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
   2953 {"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
   2954 {"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
   2955 {"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
   2956 {"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
   2957 
   2958 {"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
   2959 
   2960 {"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
   2961 
   2962 {"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
   2963 {"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
   2964 {"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
   2965 {"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
   2966 
   2967 {"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
   2968 {"rsnAllocationGetByteBuffer",       "(JJ[JIII)Ljava/nio/ByteBuffer;",        (void*)nAllocationGetByteBuffer },
   2969 };
   2970 
   2971 static int registerFuncs(JNIEnv *_env)
   2972 {
   2973     return android::AndroidRuntime::registerNativeMethods(
   2974             _env, classPathName, methods, NELEM(methods));
   2975 }
   2976 
   2977 // ---------------------------------------------------------------------------
   2978 
   2979 jint JNI_OnLoad(JavaVM* vm, void* reserved)
   2980 {
   2981     JNIEnv* env = nullptr;
   2982     jint result = -1;
   2983 
   2984     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
   2985         ALOGE("ERROR: GetEnv failed\n");
   2986         goto bail;
   2987     }
   2988     assert(env != nullptr);
   2989 
   2990     if (registerFuncs(env) < 0) {
   2991         ALOGE("ERROR: Renderscript native registration failed\n");
   2992         goto bail;
   2993     }
   2994 
   2995     /* success -- return valid version number */
   2996     result = JNI_VERSION_1_4;
   2997 
   2998 bail:
   2999     return result;
   3000 }
   3001