android_renderscript_RenderScript.cpp revision b600f3bcdbd9a8fecd18d273d94f9b05a438fdd2
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)
974{
975    jint len = _env->GetArrayLength(data);
976    LOG_API("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
977            "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
978            sizeBytes);
979    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
980    dispatchTab.AllocationElementRead((RsContext)con, (RsAllocation)alloc,
981                                      xoff, yoff, zoff,
982                                      lod, ptr, sizeBytes, compIdx);
983    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
984}
985*/
986
987// Copies from the Allocation pointed to by _alloc into the Java object data.
988static void
989nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
990                  jint w, jint h, jobject data, jint sizeBytes, jint dataType,
991                  jint mSize, jboolean usePadding)
992{
993    RsAllocation *alloc = (RsAllocation *)_alloc;
994    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
995    LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
996              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
997    int count = w * h;
998    PER_ARRAY_TYPE(0, dispatchTab.Allocation2DRead, false,
999                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1000}
1001
1002// Copies from the Allocation pointed to by _alloc into the Java object data.
1003/*
1004static void
1005nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1006                  jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
1007                  jint mSize, jboolean usePadding)
1008{
1009    RsAllocation *alloc = (RsAllocation *)_alloc;
1010    LOG_API("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1011            " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1012            lod, w, h, d, sizeBytes);
1013    int count = w * h * d;
1014    PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DRead, false,
1015                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1016}
1017*/
1018
1019static jlong
1020nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
1021{
1022    LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1023    return (jlong)(uintptr_t) dispatchTab.AllocationGetType((RsContext)con, (RsAllocation)a);
1024}
1025
1026static void
1027nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
1028{
1029    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
1030            (RsAllocation)alloc, dimX);
1031    dispatchTab.AllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
1032}
1033
1034// -----------------------------------
1035
1036static void
1037nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot, jboolean mUseInc)
1038{
1039    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)",
1040            (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1041    if (mUseInc) {
1042        dispatchTabInc.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1043    } else {
1044        dispatchTab.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1045    }
1046}
1047
1048static void
1049nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val, jboolean mUseInc)
1050{
1051    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
1052            (void *)script, slot, val);
1053    if (mUseInc) {
1054        dispatchTabInc.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1055    } else {
1056        dispatchTab.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1057    }
1058}
1059
1060static void
1061nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
1062{
1063    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
1064            (void *)script, slot, val);
1065    if (mUseInc) {
1066        dispatchTabInc.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1067    } else {
1068        dispatchTab.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1069    }
1070}
1071
1072static void
1073nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
1074{
1075    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con,
1076            (void *)script, slot, val);
1077    if (mUseInc) {
1078        dispatchTabInc.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1079    } else {
1080        dispatchTab.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1081    }
1082}
1083
1084static void
1085nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val, jboolean mUseInc)
1086{
1087    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con,
1088            (void *)script, slot, val);
1089    if (mUseInc) {
1090        dispatchTabInc.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1091    } else {
1092        dispatchTab.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1093    }
1094}
1095
1096static void
1097nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val, jboolean mUseInc)
1098{
1099    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con,
1100            (void *)script, slot, val);
1101    if (mUseInc) {
1102        dispatchTabInc.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1103    } else {
1104        dispatchTab.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1105    }
1106}
1107
1108static void
1109nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
1110{
1111    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1112    jint len = _env->GetArrayLength(data);
1113    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1114    if (mUseInc) {
1115        dispatchTabInc.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1116    } else {
1117        dispatchTab.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1118    }
1119    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1120}
1121
1122static void
1123nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
1124                jlong elem, jintArray dims, jboolean mUseInc)
1125{
1126    LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1127    jint len = _env->GetArrayLength(data);
1128    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1129    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1130    jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
1131    if (mUseInc) {
1132        dispatchTabInc.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1133                                      (const uint32_t *)dimsPtr, dimsLen);
1134    } else {
1135        dispatchTab.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1136                                   (const uint32_t *)dimsPtr, dimsLen);
1137    }
1138    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1139    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1140}
1141
1142
1143static void
1144nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone, jboolean mUseInc)
1145{
1146    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", (RsContext)con,
1147            (void *)script, (const char *)timeZone);
1148
1149    jint length = _env->GetArrayLength(timeZone);
1150    jbyte* timeZone_ptr;
1151    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1152    if (mUseInc) {
1153        dispatchTabInc.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1154    } else {
1155        dispatchTab.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1156    }
1157
1158    if (timeZone_ptr) {
1159        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1160    }
1161}
1162
1163static void
1164nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot, jboolean mUseInc)
1165{
1166    LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1167    if (mUseInc) {
1168        dispatchTabInc.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
1169    } else {
1170        dispatchTab.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
1171    }
1172}
1173
1174static void
1175nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
1176{
1177    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1178    jint len = _env->GetArrayLength(data);
1179    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1180    if (mUseInc) {
1181        dispatchTabInc.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1182    } else {
1183        dispatchTab.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1184    }
1185    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1186}
1187
1188static void
1189nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1190               jlong script, jint slot, jlong ain, jlong aout, jboolean mUseInc)
1191{
1192    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1193    if (mUseInc) {
1194        dispatchTab.ContextFinish((RsContext)con);
1195        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1196                                     (RsAllocation)ain, (RsAllocation)aout,
1197                                     NULL, 0, NULL, 0);
1198    } else {
1199        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1200                                  (RsAllocation)ain, (RsAllocation)aout,
1201                                  NULL, 0, NULL, 0);
1202    }
1203}
1204static void
1205nScriptForEachV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1206                jlong script, jint slot, jlong ain, jlong aout, jbyteArray params, jboolean mUseInc)
1207{
1208    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1209    jint len = _env->GetArrayLength(params);
1210    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1211    if (mUseInc) {
1212        dispatchTab.ContextFinish((RsContext)con);
1213        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1214                                     (RsAllocation)ain, (RsAllocation)aout,
1215                                     ptr, len, NULL, 0);
1216    } else {
1217        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1218                                  (RsAllocation)ain, (RsAllocation)aout,
1219                                  ptr, len, NULL, 0);
1220    }
1221    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1222}
1223
1224static void
1225nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1226                      jlong script, jint slot, jlong ain, jlong aout,
1227                      jint xstart, jint xend,
1228                      jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
1229{
1230    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1231    RsScriptCall sc;
1232    sc.xStart = xstart;
1233    sc.xEnd = xend;
1234    sc.yStart = ystart;
1235    sc.yEnd = yend;
1236    sc.zStart = zstart;
1237    sc.zEnd = zend;
1238    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1239    sc.arrayStart = 0;
1240    sc.arrayEnd = 0;
1241    if (mUseInc) {
1242        dispatchTab.ContextFinish((RsContext)con);
1243        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1244                                     (RsAllocation)ain, (RsAllocation)aout,
1245                                     NULL, 0, &sc, sizeof(sc));
1246    } else {
1247        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1248                                  (RsAllocation)ain, (RsAllocation)aout,
1249                                  NULL, 0, &sc, sizeof(sc));
1250    }
1251}
1252
1253static void
1254nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1255                       jlong script, jint slot, jlong ain, jlong aout,
1256                       jbyteArray params, jint xstart, jint xend,
1257                       jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
1258{
1259    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1260    jint len = _env->GetArrayLength(params);
1261    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1262    RsScriptCall sc;
1263    sc.xStart = xstart;
1264    sc.xEnd = xend;
1265    sc.yStart = ystart;
1266    sc.yEnd = yend;
1267    sc.zStart = zstart;
1268    sc.zEnd = zend;
1269    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1270    sc.arrayStart = 0;
1271    sc.arrayEnd = 0;
1272    if (mUseInc) {
1273        dispatchTab.ContextFinish((RsContext)con);
1274        dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1275                                     (RsAllocation)ain, (RsAllocation)aout,
1276                                     ptr, len, &sc, sizeof(sc));
1277    } else {
1278        dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1279                                  (RsAllocation)ain, (RsAllocation)aout,
1280                                  ptr, len, &sc, sizeof(sc));
1281    }
1282    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1283}
1284
1285// -----------------------------------
1286
1287static jlong
1288nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
1289               jstring resName, jstring cacheDir,
1290               jbyteArray scriptRef, jint length)
1291{
1292    LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
1293
1294    AutoJavaStringToUTF8 resNameUTF(_env, resName);
1295    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1296    jlong ret = 0;
1297    jbyte* script_ptr = NULL;
1298    jint _exception = 0;
1299    jint remaining;
1300    if (!scriptRef) {
1301        _exception = 1;
1302        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1303        goto exit;
1304    }
1305    if (length < 0) {
1306        _exception = 1;
1307        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1308        goto exit;
1309    }
1310    remaining = _env->GetArrayLength(scriptRef);
1311    if (remaining < length) {
1312        _exception = 1;
1313        //jniThrowException(_env, "java/lang/IllegalArgumentException",
1314        //        "length > script.length - offset");
1315        goto exit;
1316    }
1317    script_ptr = (jbyte *)
1318        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1319
1320    //rsScriptCSetText(con, (const char *)script_ptr, length);
1321
1322    ret = (jlong)(uintptr_t)dispatchTab.ScriptCCreate((RsContext)con,
1323                                                      resNameUTF.c_str(), resNameUTF.length(),
1324                                                      cacheDirUTF.c_str(), cacheDirUTF.length(),
1325                                                      (const char *)script_ptr, length);
1326
1327exit:
1328    if (script_ptr) {
1329        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1330                _exception ? JNI_ABORT: 0);
1331    }
1332
1333    return (jlong)(uintptr_t)ret;
1334}
1335
1336static jlong
1337nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid, jboolean mUseInc)
1338{
1339    LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
1340    if (mUseInc) {
1341        return (jlong)(uintptr_t)dispatchTabInc.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1342    } else {
1343        return (jlong)(uintptr_t)dispatchTab.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1344    }
1345}
1346
1347static jlong
1348nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig, jboolean mUseInc)
1349{
1350    LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
1351            (void *)sid, slot, sig);
1352    if (mUseInc) {
1353        return (jlong)(uintptr_t)dispatchTabInc.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
1354                                                                     slot, sig);
1355    } else {
1356        return (jlong)(uintptr_t)dispatchTab.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
1357                                                                  slot, sig);
1358    }
1359}
1360
1361static jlong
1362nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1363{
1364    LOG_API("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con,
1365            (void *)sid, slot);
1366    return (jlong)dispatchTab.ScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
1367}
1368
1369static jlong
1370nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jboolean mUseInc)
1371{
1372    LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
1373    if (mUseInc) {
1374        return (jlong)(uintptr_t)dispatchTabInc.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1375    } else {
1376        return (jlong)(uintptr_t)dispatchTab.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1377    }
1378}
1379
1380static jlong
1381nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
1382    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
1383{
1384    LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
1385
1386    jint kernelsLen = _env->GetArrayLength(_kernels);
1387    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
1388    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
1389    for(int i = 0; i < kernelsLen; ++i) {
1390        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
1391    }
1392
1393    jint srcLen = _env->GetArrayLength(_src);
1394    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
1395    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
1396    for(int i = 0; i < srcLen; ++i) {
1397        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
1398    }
1399
1400    jint dstkLen = _env->GetArrayLength(_dstk);
1401    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
1402    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
1403    for(int i = 0; i < dstkLen; ++i) {
1404        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
1405    }
1406
1407    jint dstfLen = _env->GetArrayLength(_dstf);
1408    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
1409    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
1410    for(int i = 0; i < dstfLen; ++i) {
1411        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
1412    }
1413
1414    jint typesLen = _env->GetArrayLength(_types);
1415    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
1416    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
1417    for(int i = 0; i < typesLen; ++i) {
1418        typesPtr[i] = (RsType)jTypesPtr[i];
1419    }
1420
1421    jlong id = (jlong)(uintptr_t) dispatchTab.ScriptGroupCreate((RsContext)con,
1422                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
1423                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
1424                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
1425                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
1426                               (RsType *)typesPtr, typesLen * sizeof(RsType));
1427
1428    free(kernelsPtr);
1429    free(srcPtr);
1430    free(dstkPtr);
1431    free(dstfPtr);
1432    free(typesPtr);
1433    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
1434    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
1435    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
1436    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
1437    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
1438    return id;
1439}
1440
1441static void
1442nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1443{
1444    LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1445            (void *)gid, (void *)kid, (void *)alloc);
1446    dispatchTab.ScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
1447                                    (RsAllocation)alloc);
1448}
1449
1450static void
1451nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1452{
1453    LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1454            (void *)gid, (void *)kid, (void *)alloc);
1455    dispatchTab.ScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
1456                                     (RsAllocation)alloc);
1457}
1458
1459static void
1460nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
1461{
1462    LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
1463    dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
1464}
1465
1466// ---------------------------------------------------------------------------
1467
1468static jlong
1469nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
1470               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1471{
1472    LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
1473    return (jlong)(uintptr_t)dispatchTab.SamplerCreate((RsContext)con,
1474                                                       (RsSamplerValue)magFilter,
1475                                                       (RsSamplerValue)minFilter,
1476                                                       (RsSamplerValue)wrapS,
1477                                                       (RsSamplerValue)wrapT,
1478                                                       (RsSamplerValue)wrapR,
1479                                                       aniso);
1480}
1481
1482static jint
1483nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
1484    return (jint)sizeof(void*);
1485}
1486
1487// ---------------------------------------------------------------------------
1488// For Incremental Intrinsic Support
1489static bool nIncLoadSO() {
1490    void* handle = NULL;
1491    handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
1492    if (handle == NULL) {
1493        LOG_API("couldn't dlopen %s, %s", filename, dlerror());
1494        return false;
1495    }
1496
1497    if (loadSymbols(handle, dispatchTabInc) == false) {
1498        LOG_API("%s init failed!", filename);
1499        return false;
1500    }
1501    LOG_API("Successfully loaded %s", filename);
1502    return true;
1503}
1504
1505// -----------------------------------
1506// To create/destroy a dummy context
1507static void
1508nIncObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
1509{
1510    LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
1511    dispatchTabInc.ObjDestroy((RsContext)con, (void *)obj);
1512}
1513
1514
1515static jlong
1516nIncDeviceCreate(JNIEnv *_env, jobject _this)
1517{
1518    LOG_API("nDeviceCreate");
1519    return (jlong)(uintptr_t)dispatchTabInc.DeviceCreate();
1520}
1521
1522static void
1523nIncDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
1524{
1525    LOG_API("nDeviceDestroy");
1526    return dispatchTabInc.DeviceDestroy((RsDevice)dev);
1527}
1528
1529static jlong
1530nIncContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
1531{
1532    LOG_API("nContextCreate");
1533    //The compat context for incremental support will be synchronous.
1534    return (jlong)(uintptr_t)dispatchTabInc.ContextCreate((RsDevice)dev, ver, sdkVer,
1535                                                          (RsContextType)ct,
1536                                                          RS_CONTEXT_SYNCHRONOUS);
1537}
1538
1539static void
1540nIncContextFinish(JNIEnv *_env, jobject _this, jlong con)
1541{
1542    LOG_API("nContextFinish, con(%p)", (RsContext)con);
1543    dispatchTabInc.ContextFinish((RsContext)con);
1544}
1545
1546static void
1547nIncContextDestroy(JNIEnv *_env, jobject _this, jlong con)
1548{
1549    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
1550    dispatchTabInc.ContextDestroy((RsContext)con);
1551}
1552
1553// -----------------------------------
1554// Create dummy Element
1555static jlong
1556nIncElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
1557{
1558    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
1559            type, kind, norm, size);
1560    return (jlong)(uintptr_t)dispatchTabInc.ElementCreate((RsContext)con, (RsDataType)type,
1561                                                          (RsDataKind)kind, norm, size);
1562}
1563// -----------------------------------
1564// Create dummy Type
1565static jlong
1566nIncTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
1567            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
1568{
1569    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
1570            incCon, eid, dimx, dimy, dimz, mips, faces, yuv);
1571
1572    return (jlong)(uintptr_t)dispatchTabInc.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
1573                                                       dimz, mips, faces, yuv);
1574}
1575
1576// -----------------------------------
1577// Create Allocation from pointer
1578static jlong
1579nIncAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong alloc, jlong type)
1580{
1581    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
1582            incCon, (RsElement)type, mips, usage, (void *)pointer);
1583    size_t strideIn;
1584    void* pIn = NULL;
1585    RsAllocation ainI = NULL;
1586    if (alloc != 0) {
1587        pIn = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
1588                                               RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
1589                                               &strideIn, sizeof(size_t));
1590        ainI = dispatchTabInc.AllocationCreateTyped((RsContext)incCon, (RsType)type,
1591                                                    RS_ALLOCATION_MIPMAP_NONE,
1592                                                    RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED,
1593                                                    (uintptr_t)pIn);
1594    }
1595    return (jlong)(uintptr_t) ainI;
1596}
1597
1598// ---------------------------------------------------------------------------
1599
1600
1601static const char *classPathName = "android/support/v8/renderscript/RenderScript";
1602
1603static JNINativeMethod methods[] = {
1604{"nLoadSO",                        "(Z)Z",                                    (bool*)nLoadSO },
1605{"nLoadIOSO",                      "()Z",                                     (bool*)nLoadIOSO },
1606{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
1607{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
1608{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
1609{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
1610{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1611{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
1612{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
1613{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
1614
1615
1616// All methods below are thread protected in java.
1617{"rsnContextCreate",                 "(JIIILjava/lang/String;)J",             (void*)nContextCreate },
1618{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
1619{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
1620{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
1621{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
1622{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
1623//{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
1624//{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
1625//{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
1626{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
1627
1628{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
1629{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
1630{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
1631
1632{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
1633
1634{"rsnAllocationCreateTyped",         "(JJIIJ)J",                              (void*)nAllocationCreateTyped },
1635{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
1636{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
1637{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
1638
1639{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1640{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1641
1642{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
1643{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
1644{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
1645{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
1646{"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
1647//{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
1648{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
1649{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
1650{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
1651{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
1652{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
1653{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
1654//{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
1655{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
1656//{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",  (void*)nAllocationRead3D },
1657{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
1658{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
1659{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
1660
1661{"rsnScriptBindAllocation",          "(JJJIZ)V",                              (void*)nScriptBindAllocation },
1662{"rsnScriptSetTimeZone",             "(JJ[BZ)V",                              (void*)nScriptSetTimeZone },
1663{"rsnScriptInvoke",                  "(JJIZ)V",                               (void*)nScriptInvoke },
1664{"rsnScriptInvokeV",                 "(JJI[BZ)V",                             (void*)nScriptInvokeV },
1665{"rsnScriptForEach",                 "(JJJIJJZ)V",                            (void*)nScriptForEach },
1666{"rsnScriptForEach",                 "(JJJIJJ[BZ)V",                          (void*)nScriptForEachV },
1667{"rsnScriptForEachClipped",          "(JJJIJJIIIIIIZ)V",                      (void*)nScriptForEachClipped },
1668{"rsnScriptForEachClipped",          "(JJJIJJ[BIIIIIIZ)V",                    (void*)nScriptForEachClippedV },
1669{"rsnScriptSetVarI",                 "(JJIIZ)V",                              (void*)nScriptSetVarI },
1670{"rsnScriptSetVarJ",                 "(JJIJZ)V",                              (void*)nScriptSetVarJ },
1671{"rsnScriptSetVarF",                 "(JJIFZ)V",                              (void*)nScriptSetVarF },
1672{"rsnScriptSetVarD",                 "(JJIDZ)V",                              (void*)nScriptSetVarD },
1673{"rsnScriptSetVarV",                 "(JJI[BZ)V",                             (void*)nScriptSetVarV },
1674{"rsnScriptSetVarVE",                "(JJI[BJ[IZ)V",                          (void*)nScriptSetVarVE },
1675{"rsnScriptSetVarObj",               "(JJIJZ)V",                              (void*)nScriptSetVarObj },
1676
1677{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
1678{"rsnScriptIntrinsicCreate",         "(JIJZ)J",                               (void*)nScriptIntrinsicCreate },
1679{"rsnScriptKernelIDCreate",          "(JJIIZ)J",                              (void*)nScriptKernelIDCreate },
1680{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
1681{"rsnScriptFieldIDCreate",           "(JJIZ)J",                               (void*)nScriptFieldIDCreate },
1682{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
1683//{"rsnScriptGroup2Create",            "(J[J)J",                                (void*)nScriptGroup2Create },
1684{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
1685{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
1686{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
1687
1688{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
1689
1690{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
1691
1692// Entry points for Inc libRSSupport
1693{"nIncLoadSO",                       "()Z",                                   (bool*)nIncLoadSO },
1694{"nIncDeviceCreate",                 "()J",                                   (void*)nIncDeviceCreate },
1695{"nIncDeviceDestroy",                "(J)V",                                  (void*)nIncDeviceDestroy },
1696{"rsnIncContextCreate",              "(JIII)J",                               (void*)nIncContextCreate },
1697{"rsnIncContextFinish",              "(J)V",                                  (void*)nIncContextFinish },
1698{"rsnIncContextDestroy",             "(J)V",                                  (void*)nIncContextDestroy },
1699{"rsnIncObjDestroy",                 "(JJ)V",                                 (void*)nIncObjDestroy },
1700{"rsnIncElementCreate",              "(JJIZI)J",                              (void*)nIncElementCreate },
1701{"rsnIncTypeCreate",                 "(JJIIIZZI)J",                           (void*)nIncTypeCreate },
1702{"rsnIncAllocationCreateTyped",      "(JJJJ)J",                               (void*)nIncAllocationCreateTyped },
1703};
1704
1705// ---------------------------------------------------------------------------
1706
1707jint JNI_OnLoad(JavaVM* vm, void* reserved)
1708{
1709    JNIEnv* env = NULL;
1710    jclass clazz = NULL;
1711    jint result = -1;
1712
1713    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1714        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
1715        //            "ERROR: GetEnv failed\n");
1716        goto bail;
1717    }
1718    if (env == NULL) {
1719        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
1720        goto bail;
1721    }
1722
1723    clazz = env->FindClass(classPathName);
1724    if (clazz == NULL) {
1725        goto bail;
1726    }
1727
1728    if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) {
1729        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
1730        //            "ERROR: MediaPlayer native registration failed\n");
1731        goto bail;
1732    }
1733
1734    /* success -- return valid version number */
1735    result = JNI_VERSION_1_4;
1736
1737bail:
1738    return result;
1739}
1740