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