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