android_renderscript_RenderScript.cpp revision 059fede7f200350b6131fc131f76248085485722
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) {
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) == 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  LOG_API("nClosureCreate: con(%p)", con);
349  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
350  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
351  RsScriptFieldID* fieldIDs =
352      (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length);
353  for (int i = 0; i< fieldIDs_length; i++) {
354    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
355  }
356
357  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
358  jsize values_length = _env->GetArrayLength(valueArray);
359  uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length);
360  for (int i = 0; i < values_length; i++) {
361    values[i] = (uintptr_t)jValues[i];
362  }
363
364  jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr);
365  jsize sizes_length = _env->GetArrayLength(sizeArray);
366
367  jlong* jDepClosures =
368      _env->GetLongArrayElements(depClosureArray, nullptr);
369  jsize depClosures_length = _env->GetArrayLength(depClosureArray);
370  RsClosure* depClosures =
371      (RsClosure*)alloca(sizeof(RsClosure) * depClosures_length);
372  for (int i = 0; i < depClosures_length; i++) {
373    depClosures[i] = (RsClosure)jDepClosures[i];
374  }
375
376  jlong* jDepFieldIDs =
377      _env->GetLongArrayElements(depFieldIDArray, nullptr);
378  jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
379  RsScriptFieldID* depFieldIDs =
380      (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * depFieldIDs_length);
381  for (int i = 0; i < depClosures_length; i++) {
382    depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
383  }
384
385  return (jlong)(uintptr_t)dispatchTab.ClosureCreate(
386      (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
387      fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length,
388      (size_t*)sizes, (size_t)sizes_length,
389      depClosures, (size_t)depClosures_length,
390      depFieldIDs, (size_t)depFieldIDs_length);
391}
392
393static void
394nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
395               jint index, jlong value, jint size) {
396  dispatchTab.ClosureSetArg((RsContext)con, (RsClosure)closureID,
397                            (uint32_t)index, (uintptr_t)value, (size_t)size);
398}
399
400static void
401nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
402                  jlong fieldID, jlong value, jint size) {
403  dispatchTab.ClosureSetGlobal((RsContext)con, (RsClosure)closureID,
404                               (RsScriptFieldID)fieldID, (uintptr_t)value,
405                               (size_t)size);
406}
407
408static long
409nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con,
410                    jlongArray closureArray) {
411  jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
412  jsize numClosures = _env->GetArrayLength(closureArray);
413  RsClosure* closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
414  for (int i = 0; i < numClosures; i++) {
415    closures[i] = (RsClosure)jClosures[i];
416  }
417
418  return (jlong)(uintptr_t)dispatchTab.ScriptGroup2Create((RsContext)con,
419                                                          closures,
420                                                          numClosures);
421}
422
423static void
424nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
425{
426    LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
427    dispatchTab.ObjDestroy((RsContext)con, (void *)obj);
428}
429
430// ---------------------------------------------------------------------------
431static jlong
432nDeviceCreate(JNIEnv *_env, jobject _this)
433{
434    LOG_API("nDeviceCreate");
435    return (jlong)(uintptr_t)dispatchTab.DeviceCreate();
436}
437
438static void
439nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
440{
441    LOG_API("nDeviceDestroy");
442    return dispatchTab.DeviceDestroy((RsDevice)dev);
443}
444
445static void
446nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
447{
448    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
449    return dispatchTab.DeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
450}
451
452static jlong
453nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
454               jint ct, jstring nativeLibDirJava)
455{
456    LOG_API("nContextCreate");
457    // Access the NativeLibDir in the Java Context.
458    const char * nativeLibDir = _env->GetStringUTFChars(nativeLibDirJava, JNI_FALSE);
459    size_t length = (size_t)_env->GetStringUTFLength(nativeLibDirJava);
460
461    jlong id = (jlong)(uintptr_t)dispatchTab.ContextCreate((RsDevice)dev, ver,
462                                                           sdkVer,
463                                                           (RsContextType)ct, 0);
464    if (dispatchTab.SetNativeLibDir) {
465        dispatchTab.SetNativeLibDir((RsContext)id, nativeLibDir, length);
466    }
467
468    _env->ReleaseStringUTFChars(nativeLibDirJava, nativeLibDir);
469    return id;
470}
471
472
473static void
474nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
475{
476    LOG_API("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
477    dispatchTab.ContextSetPriority((RsContext)con, p);
478}
479
480
481
482static void
483nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
484{
485    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
486    dispatchTab.ContextDestroy((RsContext)con);
487}
488
489static void
490nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
491{
492    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
493    dispatchTab.ContextDump((RsContext)con, bits);
494}
495
496
497static jstring
498nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
499{
500    LOG_API("nContextGetErrorMessage, con(%p)", (RsContext)con);
501    char buf[1024];
502
503    size_t receiveLen;
504    uint32_t subID;
505    int id = dispatchTab.ContextGetMessage((RsContext)con,
506                                           buf, sizeof(buf),
507                                           &receiveLen, sizeof(receiveLen),
508                                           &subID, sizeof(subID));
509    if (!id && receiveLen) {
510        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
511        //            "message receive buffer too small.  %zu", receiveLen);
512    }
513    return _env->NewStringUTF(buf);
514}
515
516static jint
517nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
518{
519    jint len = _env->GetArrayLength(data);
520    LOG_API("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
521    jint *ptr = _env->GetIntArrayElements(data, NULL);
522    size_t receiveLen;
523    uint32_t subID;
524    int id = dispatchTab.ContextGetMessage((RsContext)con,
525                                           ptr, len * 4,
526                                           &receiveLen, sizeof(receiveLen),
527                                           &subID, sizeof(subID));
528    if (!id && receiveLen) {
529        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
530        //            "message receive buffer too small.  %zu", receiveLen);
531    }
532    _env->ReleaseIntArrayElements(data, ptr, 0);
533    return (jint)id;
534}
535
536static jint
537nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
538{
539    LOG_API("nContextPeekMessage, con(%p)", (RsContext)con);
540    jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
541    size_t receiveLen;
542    uint32_t subID;
543    int id = dispatchTab.ContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
544                                  &subID, sizeof(subID));
545    auxDataPtr[0] = (jint)subID;
546    auxDataPtr[1] = (jint)receiveLen;
547    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
548    return (jint)id;
549}
550
551static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
552{
553    LOG_API("nContextInitToClient, con(%p)", (RsContext)con);
554    dispatchTab.ContextInitToClient((RsContext)con);
555}
556
557static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
558{
559    LOG_API("nContextDeinitToClient, con(%p)", (RsContext)con);
560    dispatchTab.ContextDeinitToClient((RsContext)con);
561}
562
563static void
564nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
565{
566    jint *ptr = NULL;
567    jint len = 0;
568    if (data) {
569        len = _env->GetArrayLength(data);
570        jint *ptr = _env->GetIntArrayElements(data, NULL);
571    }
572    LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
573    dispatchTab.ContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
574    if (data) {
575        _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
576    }
577}
578
579
580
581static jlong
582nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind,
583               jboolean norm, jint size)
584{
585    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
586            type, kind, norm, size);
587    return (jlong)(uintptr_t)dispatchTab.ElementCreate((RsContext)con,
588                                                       (RsDataType)type,
589                                                       (RsDataKind)kind,
590                                                       norm, size);
591}
592
593static jlong
594nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
595                jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
596{
597    int fieldCount = _env->GetArrayLength(_ids);
598    LOG_API("nElementCreate2, con(%p)", (RsContext)con);
599
600    jlong *jIds = _env->GetLongArrayElements(_ids, NULL);
601    jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
602
603    RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
604    uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
605
606    for(int i = 0; i < fieldCount; i ++) {
607        ids[i] = (RsElement)jIds[i];
608        arraySizes[i] = (uint32_t)jArraySizes[i];
609    }
610
611    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
612
613    const char **nameArray = names.c_str();
614    size_t *sizeArray = names.c_str_len();
615
616    jlong id = (jlong)(uintptr_t)dispatchTab.ElementCreate2((RsContext)con, (RsElement *)ids,
617                                                            fieldCount, nameArray,
618                                                            fieldCount * sizeof(size_t),  sizeArray,
619                                                            (const uint32_t *)arraySizes, fieldCount);
620
621    free(ids);
622    free(arraySizes);
623    _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
624    _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
625    return id;
626}
627
628
629
630
631static void
632nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
633                       jlongArray _IDs,
634                       jobjectArray _names,
635                       jintArray _arraySizes)
636{
637    uint32_t dataSize = _env->GetArrayLength(_IDs);
638    LOG_API("nElementGetSubElements, con(%p)", (RsContext)con);
639
640    uintptr_t *ids = (uintptr_t *)malloc(dataSize * sizeof(uintptr_t));
641    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
642    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
643
644    dispatchTab.ElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
645                                      (uint32_t)dataSize);
646
647    for(uint32_t i = 0; i < dataSize; i++) {
648        const jlong id = (jlong)(uintptr_t)ids[i];
649        const jint arraySize = (jint)arraySizes[i];
650        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
651        _env->SetLongArrayRegion(_IDs, i, 1, &id);
652        _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
653    }
654
655    free(ids);
656    free(names);
657    free(arraySizes);
658}
659
660// -----------------------------------
661
662static jlong
663nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
664            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
665{
666    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
667            (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
668
669    return (jlong)(uintptr_t)dispatchTab.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
670                                                    dimz, mips, faces, yuv);
671}
672
673// -----------------------------------
674
675static jlong
676nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
677                       jlong pointer)
678{
679    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
680            (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
681    return (jlong)(uintptr_t) dispatchTab.AllocationCreateTyped((RsContext)con, (RsType)type,
682                                                                (RsAllocationMipmapControl)mips,
683                                                                (uint32_t)usage, (uintptr_t)pointer);
684}
685
686static void
687nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
688{
689    LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a, bits);
690    dispatchTab.AllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
691}
692
693static void
694nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
695{
696    ioDispatch.sAllocationSetSurface(_env, _this, (RsContext)con, (RsAllocation)alloc, sur, dispatchTab);
697}
698
699static void
700nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
701{
702    dispatchTab.AllocationIoSend((RsContext)con, (RsAllocation)alloc);
703}
704
705static void
706nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
707{
708    LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
709    dispatchTab.AllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
710}
711
712static size_t GetBitmapSize(JNIEnv *env, jobject jbitmap) {
713    AndroidBitmapInfo info;
714    memset(&info, 0, sizeof(info));
715    AndroidBitmap_getInfo(env, jbitmap, &info);
716    size_t s = info.width * info.height;
717    switch (info.format) {
718        case ANDROID_BITMAP_FORMAT_RGBA_8888: s *= 4; break;
719        case ANDROID_BITMAP_FORMAT_RGB_565: s *= 2; break;
720        case ANDROID_BITMAP_FORMAT_RGBA_4444: s *= 2; break;
721    }
722    return s;
723}
724
725static jlong
726nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
727                            jobject jbitmap, jint usage)
728{
729    jlong id = 0;
730    void *pixels = NULL;
731    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
732
733    if (pixels != NULL) {
734        id = (jlong)(uintptr_t)dispatchTab.AllocationCreateFromBitmap((RsContext)con,
735                                                                      (RsType)type,
736                                                                      (RsAllocationMipmapControl)mip,
737                                                                      pixels,
738                                                                      GetBitmapSize(_env, jbitmap),
739                                                                      usage);
740        AndroidBitmap_unlockPixels(_env, jbitmap);
741    }
742    return id;
743}
744
745static jlong
746nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
747                                        jint mip, jobject jbitmap, jint usage)
748{
749    jlong id = 0;
750    void *pixels = NULL;
751    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
752
753    if (pixels != NULL) {
754        id = (jlong)(uintptr_t)dispatchTab.AllocationCreateTyped((RsContext)con,
755                                                                 (RsType)type,
756                                                                 (RsAllocationMipmapControl)mip,
757                                                                 (uint32_t)usage,
758                                                                 (uintptr_t)pixels);
759        AndroidBitmap_unlockPixels(_env, jbitmap);
760    }
761    return id;
762}
763
764static jlong
765nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type,
766                                jint mip, jobject jbitmap, jint usage)
767{
768    void *pixels = NULL;
769    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
770
771    jlong id = 0;
772    if (pixels != NULL) {
773        id = (jlong)(uintptr_t)dispatchTab.AllocationCubeCreateFromBitmap((RsContext)con,
774                                                                          (RsType)type,
775                                                                          (RsAllocationMipmapControl)mip,
776                                                                          pixels,
777                                                                          GetBitmapSize(_env, jbitmap),
778                                                                          usage);
779        AndroidBitmap_unlockPixels(_env, jbitmap);
780    }
781    return id;
782}
783
784static void
785nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
786{
787    AndroidBitmapInfo info;
788    memset(&info, 0, sizeof(info));
789    AndroidBitmap_getInfo(_env, jbitmap, &info);
790
791    void *pixels = NULL;
792    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
793
794    if (pixels != NULL) {
795        dispatchTab.Allocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0, 0,
796                                     RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, info.width,
797                                     info.height, pixels, GetBitmapSize(_env, jbitmap), 0);
798        AndroidBitmap_unlockPixels(_env, jbitmap);
799    }
800}
801
802static void
803nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
804{
805    AndroidBitmapInfo info;
806    memset(&info, 0, sizeof(info));
807    AndroidBitmap_getInfo(_env, jbitmap, &info);
808
809    void *pixels = NULL;
810    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
811
812    if (pixels != NULL) {
813        dispatchTab.AllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, pixels,
814                                           GetBitmapSize(_env, jbitmap));
815        AndroidBitmap_unlockPixels(_env, jbitmap);
816    }
817    //bitmap.notifyPixelsChanged();
818}
819
820// Copies from the Java object data into the Allocation pointed to by _alloc.
821static void
822nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
823                  jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
824                  jboolean usePadding)
825{
826    RsAllocation *alloc = (RsAllocation *)_alloc;
827    LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
828            "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
829            dataType);
830    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation1DData, true,
831                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
832}
833
834
835static void
836nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint xoff,
837                         jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
838{
839    jint len = _env->GetArrayLength(data);
840    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), xoff(%i), comp(%i), len(%i), "
841            "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, compIdx, len,
842            sizeBytes);
843    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
844    dispatchTab.Allocation1DElementData((RsContext)con, (RsAllocation)alloc, xoff,
845                                        lod, ptr, sizeBytes, compIdx);
846    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
847}
848
849/*
850static void
851nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
852                       jint xoff, jint yoff, jint zoff,
853                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
854{
855    jint len = _env->GetArrayLength(data);
856    LOG_API("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
857            "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
858            sizeBytes);
859    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
860    dispatchTab.AllocationElementData((RsContext)con, (RsAllocation)alloc,
861                                      xoff, yoff, zoff,
862                                      lod, ptr, sizeBytes, compIdx);
863    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
864}
865*/
866
867// Copies from the Java object data into the Allocation pointed to by _alloc.
868static void
869nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
870                  jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
871                  jboolean usePadding)
872{
873    RsAllocation *alloc = (RsAllocation *)_alloc;
874    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
875    LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
876            "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
877    int count = w * h;
878    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation2DData, true,
879                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
880}
881
882static void
883nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
884                        jlong dstAlloc, jint dstXoff, jint dstYoff,
885                        jint dstMip, jint dstFace,
886                        jint width, jint height,
887                        jlong srcAlloc, jint srcXoff, jint srcYoff,
888                        jint srcMip, jint srcFace)
889{
890    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
891            " dstMip(%i), dstFace(%i), width(%i), height(%i),"
892            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
893            (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
894            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
895
896    dispatchTab.AllocationCopy2DRange((RsContext)con,
897                                      (RsAllocation)dstAlloc,
898                                      dstXoff, dstYoff,
899                                      dstMip, dstFace,
900                                      width, height,
901                                      (RsAllocation)srcAlloc,
902                                      srcXoff, srcYoff,
903                                      srcMip, srcFace);
904}
905
906// Copies from the Java object data into the Allocation pointed to by _alloc.
907static void
908nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
909                  jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
910                  jint mSize, jboolean usePadding)
911{
912    RsAllocation *alloc = (RsAllocation *)_alloc;
913    LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
914            " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
915            lod, w, h, d, sizeBytes);
916    int count = w * h * d;
917    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DData, true,
918                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
919}
920
921static void
922nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
923                        jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
924                        jint dstMip,
925                        jint width, jint height, jint depth,
926                        jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
927                        jint srcMip)
928{
929    LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
930            " dstMip(%i), width(%i), height(%i),"
931            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
932            (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
933            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
934
935    dispatchTab.AllocationCopy3DRange((RsContext)con,
936                                      (RsAllocation)dstAlloc,
937                                      dstXoff, dstYoff, dstZoff, dstMip,
938                                      width, height, depth,
939                                      (RsAllocation)srcAlloc,
940                                      srcXoff, srcYoff, srcZoff, srcMip);
941}
942
943// Copies from the Allocation pointed to by _alloc into the Java object data.
944static void
945nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
946                jint mSize, jboolean usePadding)
947{
948    RsAllocation *alloc = (RsAllocation *)_alloc;
949    LOG_API("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
950    int count = 0;
951    PER_ARRAY_TYPE(0, dispatchTab.AllocationRead, false,
952                   (RsContext)con, alloc, ptr, len * typeBytes);
953}
954
955// Copies from the Allocation pointed to by _alloc into the Java object data.
956static void
957nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
958                  jint count, jobject data, jint sizeBytes, jint dataType,
959                  jint mSize, jboolean usePadding)
960{
961    RsAllocation *alloc = (RsAllocation *)_alloc;
962    LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
963              "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
964    PER_ARRAY_TYPE(0, dispatchTab.Allocation1DRead, false,
965                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
966}
967
968// Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
969/*
970static void
971nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc,
972                       jint xoff, jint yoff, jint zoff,
973                       jint lod, jint compIdx, jobject data, jint sizeBytes, int dataType)
974{
975    RsAllocation *alloc = (RsAllocation *)_alloc;
976    LOG_API("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), "
977            "sizeBytes(%i)", (RsContext)con, alloc, xoff, yoff, zoff, compIdx, sizeBytes);
978    PER_ARRAY_TYPE(0, dispatchTab.AllocationElementRead, false, (RsContext)con, alloc,
979                   xoff, yoff, zoff, lod, ptr, sizeBytes, compIdx);
980}
981*/
982
983// Copies from the Allocation pointed to by _alloc into the Java object data.
984static void
985nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
986                  jint w, jint h, jobject data, jint sizeBytes, jint dataType,
987                  jint mSize, jboolean usePadding)
988{
989    RsAllocation *alloc = (RsAllocation *)_alloc;
990    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
991    LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
992              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
993    int count = w * h;
994    PER_ARRAY_TYPE(0, dispatchTab.Allocation2DRead, false,
995                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
996}
997
998// Copies from the Allocation pointed to by _alloc into the Java object data.
999/*
1000static void
1001nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1002                  jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
1003                  jint mSize, jboolean usePadding)
1004{
1005    RsAllocation *alloc = (RsAllocation *)_alloc;
1006    LOG_API("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1007            " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1008            lod, w, h, d, sizeBytes);
1009    int count = w * h * d;
1010    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DRead, false,
1011                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1012}
1013*/
1014
1015static jlong
1016nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
1017{
1018    LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1019    return (jlong)(uintptr_t) dispatchTab.AllocationGetType((RsContext)con, (RsAllocation)a);
1020}
1021
1022static void
1023nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
1024{
1025    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
1026            (RsAllocation)alloc, dimX);
1027    dispatchTab.AllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
1028}
1029
1030// -----------------------------------
1031
1032static void
1033nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot, jboolean mUseInc)
1034{
1035    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)",
1036            (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1037    if (mUseInc) {
1038        dispatchTabInc.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1039    } else {
1040        dispatchTab.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1041    }
1042}
1043
1044static void
1045nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val, jboolean mUseInc)
1046{
1047    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
1048            (void *)script, slot, val);
1049    if (mUseInc) {
1050        dispatchTabInc.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1051    } else {
1052        dispatchTab.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1053    }
1054}
1055
1056static void
1057nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
1058{
1059    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
1060            (void *)script, slot, val);
1061    if (mUseInc) {
1062        dispatchTabInc.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1063    } else {
1064        dispatchTab.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1065    }
1066}
1067
1068static void
1069nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
1070{
1071    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con,
1072            (void *)script, slot, val);
1073    if (mUseInc) {
1074        dispatchTabInc.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1075    } else {
1076        dispatchTab.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1077    }
1078}
1079
1080static void
1081nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val, jboolean mUseInc)
1082{
1083    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con,
1084            (void *)script, slot, val);
1085    if (mUseInc) {
1086        dispatchTabInc.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1087    } else {
1088        dispatchTab.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1089    }
1090}
1091
1092static void
1093nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val, jboolean mUseInc)
1094{
1095    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con,
1096            (void *)script, slot, val);
1097    if (mUseInc) {
1098        dispatchTabInc.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1099    } else {
1100        dispatchTab.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1101    }
1102}
1103
1104static void
1105nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
1106{
1107    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1108    jint len = _env->GetArrayLength(data);
1109    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1110    if (mUseInc) {
1111        dispatchTabInc.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1112    } else {
1113        dispatchTab.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1114    }
1115    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1116}
1117
1118static void
1119nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
1120                jlong elem, jintArray dims, jboolean mUseInc)
1121{
1122    LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1123    jint len = _env->GetArrayLength(data);
1124    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1125    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1126    jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
1127    if (mUseInc) {
1128        dispatchTabInc.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1129                                      (const uint32_t *)dimsPtr, dimsLen);
1130    } else {
1131        dispatchTab.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1132                                   (const uint32_t *)dimsPtr, dimsLen);
1133    }
1134    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1135    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1136}
1137
1138
1139static void
1140nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone, jboolean mUseInc)
1141{
1142    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", (RsContext)con,
1143            (void *)script, (const char *)timeZone);
1144
1145    jint length = _env->GetArrayLength(timeZone);
1146    jbyte* timeZone_ptr;
1147    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1148    if (mUseInc) {
1149        dispatchTabInc.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1150    } else {
1151        dispatchTab.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1152    }
1153
1154    if (timeZone_ptr) {
1155        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1156    }
1157}
1158
1159static void
1160nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot, jboolean mUseInc)
1161{
1162    LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1163    if (mUseInc) {
1164        dispatchTabInc.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
1165    } else {
1166        dispatchTab.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
1167    }
1168}
1169
1170static void
1171nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
1172{
1173    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1174    jint len = _env->GetArrayLength(data);
1175    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1176    if (mUseInc) {
1177        dispatchTabInc.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1178    } else {
1179        dispatchTab.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1180    }
1181    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1182}
1183
1184static void
1185nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1186               jlong script, jint slot, jlong ain, jlong aout, jboolean mUseInc)
1187{
1188    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1189    if (mUseInc) {
1190        dispatchTab.ContextFinish((RsContext)con);
1191        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1192                                     (RsAllocation)ain, (RsAllocation)aout,
1193                                     NULL, 0, NULL, 0);
1194    } else {
1195        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1196                                  (RsAllocation)ain, (RsAllocation)aout,
1197                                  NULL, 0, NULL, 0);
1198    }
1199}
1200static void
1201nScriptForEachV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1202                jlong script, jint slot, jlong ain, jlong aout, jbyteArray params, jboolean mUseInc)
1203{
1204    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1205    jint len = _env->GetArrayLength(params);
1206    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1207    if (mUseInc) {
1208        dispatchTab.ContextFinish((RsContext)con);
1209        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1210                                     (RsAllocation)ain, (RsAllocation)aout,
1211                                     ptr, len, NULL, 0);
1212    } else {
1213        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1214                                  (RsAllocation)ain, (RsAllocation)aout,
1215                                  ptr, len, NULL, 0);
1216    }
1217    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1218}
1219
1220static void
1221nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1222                      jlong script, jint slot, jlong ain, jlong aout,
1223                      jint xstart, jint xend,
1224                      jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
1225{
1226    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1227    RsScriptCall sc;
1228    sc.xStart = xstart;
1229    sc.xEnd = xend;
1230    sc.yStart = ystart;
1231    sc.yEnd = yend;
1232    sc.zStart = zstart;
1233    sc.zEnd = zend;
1234    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1235    sc.arrayStart = 0;
1236    sc.arrayEnd = 0;
1237    if (mUseInc) {
1238        dispatchTab.ContextFinish((RsContext)con);
1239        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1240                                     (RsAllocation)ain, (RsAllocation)aout,
1241                                     NULL, 0, &sc, sizeof(sc));
1242    } else {
1243        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1244                                  (RsAllocation)ain, (RsAllocation)aout,
1245                                  NULL, 0, &sc, sizeof(sc));
1246    }
1247}
1248
1249static void
1250nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1251                       jlong script, jint slot, jlong ain, jlong aout,
1252                       jbyteArray params, jint xstart, jint xend,
1253                       jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
1254{
1255    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1256    jint len = _env->GetArrayLength(params);
1257    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1258    RsScriptCall sc;
1259    sc.xStart = xstart;
1260    sc.xEnd = xend;
1261    sc.yStart = ystart;
1262    sc.yEnd = yend;
1263    sc.zStart = zstart;
1264    sc.zEnd = zend;
1265    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1266    sc.arrayStart = 0;
1267    sc.arrayEnd = 0;
1268    if (mUseInc) {
1269        dispatchTab.ContextFinish((RsContext)con);
1270        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1271                                     (RsAllocation)ain, (RsAllocation)aout,
1272                                     ptr, len, &sc, sizeof(sc));
1273    } else {
1274        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1275                                  (RsAllocation)ain, (RsAllocation)aout,
1276                                  ptr, len, &sc, sizeof(sc));
1277    }
1278    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1279}
1280
1281// -----------------------------------
1282
1283static jlong
1284nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
1285               jstring resName, jstring cacheDir,
1286               jbyteArray scriptRef, jint length)
1287{
1288    LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
1289
1290    AutoJavaStringToUTF8 resNameUTF(_env, resName);
1291    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1292    jlong ret = 0;
1293    jbyte* script_ptr = NULL;
1294    jint _exception = 0;
1295    jint remaining;
1296    if (!scriptRef) {
1297        _exception = 1;
1298        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1299        goto exit;
1300    }
1301    if (length < 0) {
1302        _exception = 1;
1303        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1304        goto exit;
1305    }
1306    remaining = _env->GetArrayLength(scriptRef);
1307    if (remaining < length) {
1308        _exception = 1;
1309        //jniThrowException(_env, "java/lang/IllegalArgumentException",
1310        //        "length > script.length - offset");
1311        goto exit;
1312    }
1313    script_ptr = (jbyte *)
1314        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1315
1316    //rsScriptCSetText(con, (const char *)script_ptr, length);
1317
1318    ret = (jlong)(uintptr_t)dispatchTab.ScriptCCreate((RsContext)con,
1319                                                      resNameUTF.c_str(), resNameUTF.length(),
1320                                                      cacheDirUTF.c_str(), cacheDirUTF.length(),
1321                                                      (const char *)script_ptr, length);
1322
1323exit:
1324    if (script_ptr) {
1325        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1326                _exception ? JNI_ABORT: 0);
1327    }
1328
1329    return (jlong)(uintptr_t)ret;
1330}
1331
1332static jlong
1333nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid, jboolean mUseInc)
1334{
1335    LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
1336    if (mUseInc) {
1337        return (jlong)(uintptr_t)dispatchTabInc.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1338    } else {
1339        return (jlong)(uintptr_t)dispatchTab.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1340    }
1341}
1342
1343static jlong
1344nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig, jboolean mUseInc)
1345{
1346    LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
1347            (void *)sid, slot, sig);
1348    if (mUseInc) {
1349        return (jlong)(uintptr_t)dispatchTabInc.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
1350                                                                     slot, sig);
1351    } else {
1352        return (jlong)(uintptr_t)dispatchTab.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
1353                                                                  slot, sig);
1354    }
1355}
1356
1357static jlong
1358nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1359{
1360    LOG_API("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con,
1361            (void *)sid, slot);
1362    return (jlong)dispatchTab.ScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
1363}
1364
1365static jlong
1366nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jboolean mUseInc)
1367{
1368    LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
1369    if (mUseInc) {
1370        return (jlong)(uintptr_t)dispatchTabInc.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1371    } else {
1372        return (jlong)(uintptr_t)dispatchTab.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1373    }
1374}
1375
1376static jlong
1377nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
1378    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
1379{
1380    LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
1381
1382    jint kernelsLen = _env->GetArrayLength(_kernels);
1383    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
1384    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
1385    for(int i = 0; i < kernelsLen; ++i) {
1386        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
1387    }
1388
1389    jint srcLen = _env->GetArrayLength(_src);
1390    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
1391    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
1392    for(int i = 0; i < srcLen; ++i) {
1393        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
1394    }
1395
1396    jint dstkLen = _env->GetArrayLength(_dstk);
1397    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
1398    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
1399    for(int i = 0; i < dstkLen; ++i) {
1400        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
1401    }
1402
1403    jint dstfLen = _env->GetArrayLength(_dstf);
1404    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
1405    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
1406    for(int i = 0; i < dstfLen; ++i) {
1407        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
1408    }
1409
1410    jint typesLen = _env->GetArrayLength(_types);
1411    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
1412    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
1413    for(int i = 0; i < typesLen; ++i) {
1414        typesPtr[i] = (RsType)jTypesPtr[i];
1415    }
1416
1417    jlong id = (jlong)(uintptr_t) dispatchTab.ScriptGroupCreate((RsContext)con,
1418                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
1419                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
1420                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
1421                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
1422                               (RsType *)typesPtr, typesLen * sizeof(RsType));
1423
1424    free(kernelsPtr);
1425    free(srcPtr);
1426    free(dstkPtr);
1427    free(dstfPtr);
1428    free(typesPtr);
1429    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
1430    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
1431    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
1432    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
1433    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
1434    return id;
1435}
1436
1437static void
1438nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1439{
1440    LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1441            (void *)gid, (void *)kid, (void *)alloc);
1442    dispatchTab.ScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
1443                                    (RsAllocation)alloc);
1444}
1445
1446static void
1447nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1448{
1449    LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1450            (void *)gid, (void *)kid, (void *)alloc);
1451    dispatchTab.ScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
1452                                     (RsAllocation)alloc);
1453}
1454
1455static void
1456nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
1457{
1458    LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
1459    dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
1460}
1461
1462// ---------------------------------------------------------------------------
1463
1464static jlong
1465nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
1466               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1467{
1468    LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
1469    return (jlong)(uintptr_t)dispatchTab.SamplerCreate((RsContext)con,
1470                                                       (RsSamplerValue)magFilter,
1471                                                       (RsSamplerValue)minFilter,
1472                                                       (RsSamplerValue)wrapS,
1473                                                       (RsSamplerValue)wrapT,
1474                                                       (RsSamplerValue)wrapR,
1475                                                       aniso);
1476}
1477
1478static jint
1479nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
1480    return (jint)sizeof(void*);
1481}
1482
1483// ---------------------------------------------------------------------------
1484// For Incremental Intrinsic Support
1485static bool nIncLoadSO() {
1486    void* handle = NULL;
1487    handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
1488    if (handle == NULL) {
1489        LOG_API("couldn't dlopen %s, %s", filename, dlerror());
1490        return false;
1491    }
1492
1493    if (loadSymbols(handle, dispatchTabInc) == false) {
1494        LOG_API("%s init failed!", filename);
1495        return false;
1496    }
1497    LOG_API("Successfully loaded %s", filename);
1498    return true;
1499}
1500
1501// -----------------------------------
1502// To create/destroy a dummy context
1503static void
1504nIncObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
1505{
1506    LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
1507    dispatchTabInc.ObjDestroy((RsContext)con, (void *)obj);
1508}
1509
1510
1511static jlong
1512nIncDeviceCreate(JNIEnv *_env, jobject _this)
1513{
1514    LOG_API("nDeviceCreate");
1515    return (jlong)(uintptr_t)dispatchTabInc.DeviceCreate();
1516}
1517
1518static void
1519nIncDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
1520{
1521    LOG_API("nDeviceDestroy");
1522    return dispatchTabInc.DeviceDestroy((RsDevice)dev);
1523}
1524
1525static jlong
1526nIncContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
1527{
1528    LOG_API("nContextCreate");
1529    //The compat context for incremental support will be synchronous.
1530    return (jlong)(uintptr_t)dispatchTabInc.ContextCreate((RsDevice)dev, ver, sdkVer,
1531                                                          (RsContextType)ct,
1532                                                          RS_CONTEXT_SYNCHRONOUS);
1533}
1534
1535static void
1536nIncContextFinish(JNIEnv *_env, jobject _this, jlong con)
1537{
1538    LOG_API("nContextFinish, con(%p)", (RsContext)con);
1539    dispatchTabInc.ContextFinish((RsContext)con);
1540}
1541
1542static void
1543nIncContextDestroy(JNIEnv *_env, jobject _this, jlong con)
1544{
1545    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
1546    dispatchTabInc.ContextDestroy((RsContext)con);
1547}
1548
1549// -----------------------------------
1550// Create dummy Element
1551static jlong
1552nIncElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
1553{
1554    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
1555            type, kind, norm, size);
1556    return (jlong)(uintptr_t)dispatchTabInc.ElementCreate((RsContext)con, (RsDataType)type,
1557                                                          (RsDataKind)kind, norm, size);
1558}
1559// -----------------------------------
1560// Create dummy Type
1561static jlong
1562nIncTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
1563            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
1564{
1565    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
1566            incCon, eid, dimx, dimy, dimz, mips, faces, yuv);
1567
1568    return (jlong)(uintptr_t)dispatchTabInc.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
1569                                                       dimz, mips, faces, yuv);
1570}
1571
1572// -----------------------------------
1573// Create Allocation from pointer
1574static jlong
1575nIncAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong alloc, jlong type)
1576{
1577    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
1578            incCon, (RsElement)type, mips, usage, (void *)pointer);
1579    size_t strideIn;
1580    void* pIn = NULL;
1581    RsAllocation ainI = NULL;
1582    if (alloc != 0) {
1583        pIn = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
1584                                               RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
1585                                               &strideIn, sizeof(size_t));
1586        ainI = dispatchTabInc.AllocationCreateTyped((RsContext)incCon, (RsType)type,
1587                                                    RS_ALLOCATION_MIPMAP_NONE,
1588                                                    RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED,
1589                                                    (uintptr_t)pIn);
1590    }
1591    return (jlong)(uintptr_t) ainI;
1592}
1593
1594// ---------------------------------------------------------------------------
1595
1596
1597static const char *classPathName = "android/support/v8/renderscript/RenderScript";
1598
1599static JNINativeMethod methods[] = {
1600{"nLoadSO",                        "(Z)Z",                                    (bool*)nLoadSO },
1601{"nLoadIOSO",                      "()Z",                                     (bool*)nLoadIOSO },
1602{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
1603{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
1604{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
1605{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
1606{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1607{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
1608{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
1609{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
1610
1611
1612// All methods below are thread protected in java.
1613{"rsnContextCreate",                 "(JIIILjava/lang/String;)J",             (void*)nContextCreate },
1614{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
1615{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
1616{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
1617{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
1618{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
1619//{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
1620//{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
1621//{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
1622{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
1623
1624{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
1625{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
1626{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
1627
1628{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
1629
1630{"rsnAllocationCreateTyped",         "(JJIIJ)J",                              (void*)nAllocationCreateTyped },
1631{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
1632{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
1633{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
1634
1635{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1636{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1637
1638{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
1639{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
1640{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
1641{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
1642{"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
1643//{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
1644{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
1645{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
1646{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
1647{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
1648{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
1649{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
1650//{"rsnAllocationElementRead",         "(JJIIIIILjava/lang/Object;II)V",        (void*)nAllocationElementRead },
1651{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
1652//{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",  (void*)nAllocationRead3D },
1653{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
1654{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
1655{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
1656
1657{"rsnScriptBindAllocation",          "(JJJIZ)V",                              (void*)nScriptBindAllocation },
1658{"rsnScriptSetTimeZone",             "(JJ[BZ)V",                              (void*)nScriptSetTimeZone },
1659{"rsnScriptInvoke",                  "(JJIZ)V",                               (void*)nScriptInvoke },
1660{"rsnScriptInvokeV",                 "(JJI[BZ)V",                             (void*)nScriptInvokeV },
1661{"rsnScriptForEach",                 "(JJJIJJZ)V",                            (void*)nScriptForEach },
1662{"rsnScriptForEach",                 "(JJJIJJ[BZ)V",                          (void*)nScriptForEachV },
1663{"rsnScriptForEachClipped",          "(JJJIJJIIIIIIZ)V",                      (void*)nScriptForEachClipped },
1664{"rsnScriptForEachClipped",          "(JJJIJJ[BIIIIIIZ)V",                    (void*)nScriptForEachClippedV },
1665{"rsnScriptSetVarI",                 "(JJIIZ)V",                              (void*)nScriptSetVarI },
1666{"rsnScriptSetVarJ",                 "(JJIJZ)V",                              (void*)nScriptSetVarJ },
1667{"rsnScriptSetVarF",                 "(JJIFZ)V",                              (void*)nScriptSetVarF },
1668{"rsnScriptSetVarD",                 "(JJIDZ)V",                              (void*)nScriptSetVarD },
1669{"rsnScriptSetVarV",                 "(JJI[BZ)V",                             (void*)nScriptSetVarV },
1670{"rsnScriptSetVarVE",                "(JJI[BJ[IZ)V",                          (void*)nScriptSetVarVE },
1671{"rsnScriptSetVarObj",               "(JJIJZ)V",                              (void*)nScriptSetVarObj },
1672
1673{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
1674{"rsnScriptIntrinsicCreate",         "(JIJZ)J",                               (void*)nScriptIntrinsicCreate },
1675{"rsnScriptKernelIDCreate",          "(JJIIZ)J",                              (void*)nScriptKernelIDCreate },
1676{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
1677{"rsnScriptFieldIDCreate",           "(JJIZ)J",                               (void*)nScriptFieldIDCreate },
1678{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
1679//{"rsnScriptGroup2Create",            "(J[J)J",                                (void*)nScriptGroup2Create },
1680{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
1681{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
1682{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
1683
1684{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
1685
1686{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
1687
1688// Entry points for Inc libRSSupport
1689{"nIncLoadSO",                       "()Z",                                   (bool*)nIncLoadSO },
1690{"nIncDeviceCreate",                 "()J",                                   (void*)nIncDeviceCreate },
1691{"nIncDeviceDestroy",                "(J)V",                                  (void*)nIncDeviceDestroy },
1692{"rsnIncContextCreate",              "(JIII)J",                               (void*)nIncContextCreate },
1693{"rsnIncContextFinish",              "(J)V",                                  (void*)nIncContextFinish },
1694{"rsnIncContextDestroy",             "(J)V",                                  (void*)nIncContextDestroy },
1695{"rsnIncObjDestroy",                 "(JJ)V",                                 (void*)nIncObjDestroy },
1696{"rsnIncElementCreate",              "(JJIZI)J",                              (void*)nIncElementCreate },
1697{"rsnIncTypeCreate",                 "(JJIIIZZI)J",                           (void*)nIncTypeCreate },
1698{"rsnIncAllocationCreateTyped",      "(JJJJ)J",                               (void*)nIncAllocationCreateTyped },
1699};
1700
1701// ---------------------------------------------------------------------------
1702
1703jint JNI_OnLoad(JavaVM* vm, void* reserved)
1704{
1705    JNIEnv* env = NULL;
1706    jclass clazz = NULL;
1707    jint result = -1;
1708
1709    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1710        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
1711        //            "ERROR: GetEnv failed\n");
1712        goto bail;
1713    }
1714    if (env == NULL) {
1715        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
1716        goto bail;
1717    }
1718
1719    clazz = env->FindClass(classPathName);
1720    if (clazz == NULL) {
1721        goto bail;
1722    }
1723
1724    if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) {
1725        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
1726        //            "ERROR: MediaPlayer native registration failed\n");
1727        goto bail;
1728    }
1729
1730    /* success -- return valid version number */
1731    result = JNI_VERSION_1_4;
1732
1733bail:
1734    return result;
1735}
1736