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