android_renderscript_RenderScript.cpp revision bcccd31800d79f28767fe3d5db4e5cb4fb148360
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#include "jni.h"
27#include <rsEnv.h>
28
29#include "rsDispatch.h"
30#include <dlfcn.h>
31
32//#define LOG_API ALOG
33#define LOG_API(...)
34
35#define NELEM(m) (sizeof(m) / sizeof((m)[0]))
36
37class AutoJavaStringToUTF8 {
38public:
39    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
40        fCStr = env->GetStringUTFChars(str, NULL);
41        fLength = env->GetStringUTFLength(str);
42    }
43    ~AutoJavaStringToUTF8() {
44        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
45    }
46    const char* c_str() const { return fCStr; }
47    jsize length() const { return fLength; }
48
49private:
50    JNIEnv*     fEnv;
51    jstring     fJStr;
52    const char* fCStr;
53    jsize       fLength;
54};
55
56class AutoJavaStringArrayToUTF8 {
57public:
58    AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
59    : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
60        mCStrings = NULL;
61        mSizeArray = NULL;
62        if (stringsLength > 0) {
63            mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
64            mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
65            for (jsize ct = 0; ct < stringsLength; ct ++) {
66                jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
67                mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
68                mSizeArray[ct] = mEnv->GetStringUTFLength(s);
69            }
70        }
71    }
72    ~AutoJavaStringArrayToUTF8() {
73        for (jsize ct=0; ct < mStringsLength; ct++) {
74            jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
75            mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
76        }
77        free(mCStrings);
78        free(mSizeArray);
79    }
80    const char **c_str() const { return mCStrings; }
81    size_t *c_str_len() const { return mSizeArray; }
82    jsize length() const { return mStringsLength; }
83
84private:
85    JNIEnv      *mEnv;
86    jobjectArray mStrings;
87    const char **mCStrings;
88    size_t      *mSizeArray;
89    jsize        mStringsLength;
90};
91
92
93// ---------------------------------------------------------------------------
94static dispatchTable dispatchTab;
95
96static jboolean nLoadSO(JNIEnv *_env, jobject _this, jboolean useNative) {
97    void* handle = NULL;
98    if (useNative) {
99        handle = dlopen("libRS.so", RTLD_LAZY | RTLD_LOCAL);
100    } else {
101        handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
102    }
103    if (handle == NULL) {
104        LOG_API("couldn't dlopen %s, %s", filename, dlerror());
105        return false;
106    }
107
108    if (loadSymbols(handle, dispatchTab) == false) {
109        LOG_API("%s init failed!", filename);
110        return false;
111    }
112    LOG_API("Successfully loaded %s", filename);
113    return true;
114}
115
116// ---------------------------------------------------------------------------
117
118static void
119nContextFinish(JNIEnv *_env, jobject _this, RsContext con)
120{
121    LOG_API("nContextFinish, con(%p)", con);
122    dispatchTab.ContextFinish(con);
123}
124
125static jlong
126nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
127               jlong returnValue, jlongArray fieldIDArray,
128               jlongArray valueArray, jintArray sizeArray,
129               jlongArray depClosureArray, jlongArray depFieldIDArray) {
130  LOG_API("nClosureCreate: con(%p)", con);
131  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
132  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
133  RsScriptFieldID* fieldIDs =
134      (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length);
135  for (int i = 0; i< fieldIDs_length; i++) {
136    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
137  }
138
139  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
140  jsize values_length = _env->GetArrayLength(valueArray);
141  uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length);
142  for (int i = 0; i < values_length; i++) {
143    values[i] = (uintptr_t)jValues[i];
144  }
145
146  jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr);
147  jsize sizes_length = _env->GetArrayLength(sizeArray);
148
149  jlong* jDepClosures =
150      _env->GetLongArrayElements(depClosureArray, nullptr);
151  jsize depClosures_length = _env->GetArrayLength(depClosureArray);
152  RsClosure* depClosures =
153      (RsClosure*)alloca(sizeof(RsClosure) * depClosures_length);
154  for (int i = 0; i < depClosures_length; i++) {
155    depClosures[i] = (RsClosure)jDepClosures[i];
156  }
157
158  jlong* jDepFieldIDs =
159      _env->GetLongArrayElements(depFieldIDArray, nullptr);
160  jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
161  RsScriptFieldID* depFieldIDs =
162      (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * depFieldIDs_length);
163  for (int i = 0; i < depClosures_length; i++) {
164    depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
165  }
166
167  return (jlong)(uintptr_t)dispatchTab.ClosureCreate(
168      (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
169      fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length,
170      (size_t*)sizes, (size_t)sizes_length,
171      depClosures, (size_t)depClosures_length,
172      depFieldIDs, (size_t)depFieldIDs_length);
173}
174
175static void
176nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
177               jint index, jlong value, jint size) {
178  dispatchTab.ClosureSetArg((RsContext)con, (RsClosure)closureID,
179                            (uint32_t)index, (uintptr_t)value, (size_t)size);
180}
181
182static void
183nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
184                  jlong fieldID, jlong value, jint size) {
185  dispatchTab.ClosureSetGlobal((RsContext)con, (RsClosure)closureID,
186                               (RsScriptFieldID)fieldID, (uintptr_t)value,
187                               (size_t)size);
188}
189
190static long
191nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con,
192                    jlongArray closureArray) {
193  jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
194  jsize numClosures = _env->GetArrayLength(closureArray);
195  RsClosure* closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
196  for (int i = 0; i < numClosures; i++) {
197    closures[i] = (RsClosure)jClosures[i];
198  }
199
200  return (jlong)(uintptr_t)dispatchTab.ScriptGroup2Create((RsContext)con,
201                                                          closures,
202                                                          numClosures);
203}
204
205static void
206nObjDestroy(JNIEnv *_env, jobject _this, RsContext con, jint obj)
207{
208    LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
209    dispatchTab.ObjDestroy(con, (void *)obj);
210}
211
212// ---------------------------------------------------------------------------
213
214static jint
215nDeviceCreate(JNIEnv *_env, jobject _this)
216{
217    LOG_API("nDeviceCreate");
218    return (jint)dispatchTab.DeviceCreate();
219}
220
221static void
222nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev)
223{
224    LOG_API("nDeviceDestroy");
225    return dispatchTab.DeviceDestroy((RsDevice)dev);
226}
227
228static void
229nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value)
230{
231    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
232    return dispatchTab.DeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
233}
234
235static jint
236nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer, jint ct)
237{
238    LOG_API("nContextCreate");
239    return (jint)dispatchTab.ContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
240}
241
242
243static void
244nContextSetPriority(JNIEnv *_env, jobject _this, RsContext con, jint p)
245{
246    LOG_API("ContextSetPriority, con(%p), priority(%i)", con, p);
247    dispatchTab.ContextSetPriority(con, p);
248}
249
250
251
252static void
253nContextDestroy(JNIEnv *_env, jobject _this, RsContext con)
254{
255    LOG_API("nContextDestroy, con(%p)", con);
256    dispatchTab.ContextDestroy(con);
257}
258
259static void
260nContextDump(JNIEnv *_env, jobject _this, RsContext con, jint bits)
261{
262    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
263    dispatchTab.ContextDump((RsContext)con, bits);
264}
265
266
267static jstring
268nContextGetErrorMessage(JNIEnv *_env, jobject _this, RsContext con)
269{
270    LOG_API("nContextGetErrorMessage, con(%p)", con);
271    char buf[1024];
272
273    size_t receiveLen;
274    uint32_t subID;
275    int id = dispatchTab.ContextGetMessage(con,
276                                 buf, sizeof(buf),
277                                 &receiveLen, sizeof(receiveLen),
278                                 &subID, sizeof(subID));
279    if (!id && receiveLen) {
280        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
281        //            "message receive buffer too small.  %zu", receiveLen);
282    }
283    return _env->NewStringUTF(buf);
284}
285
286static jint
287nContextGetUserMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data)
288{
289    jint len = _env->GetArrayLength(data);
290    LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
291    jint *ptr = _env->GetIntArrayElements(data, NULL);
292    size_t receiveLen;
293    uint32_t subID;
294    int id = dispatchTab.ContextGetMessage(con,
295                                 ptr, len * 4,
296                                 &receiveLen, sizeof(receiveLen),
297                                 &subID, sizeof(subID));
298    if (!id && receiveLen) {
299        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
300        //            "message receive buffer too small.  %zu", receiveLen);
301    }
302    _env->ReleaseIntArrayElements(data, ptr, 0);
303    return id;
304}
305
306static jint
307nContextPeekMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray auxData)
308{
309    LOG_API("nContextPeekMessage, con(%p)", con);
310    jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
311    size_t receiveLen;
312    uint32_t subID;
313    int id = dispatchTab.ContextPeekMessage(con, &receiveLen, sizeof(receiveLen),
314                                  &subID, sizeof(subID));
315    auxDataPtr[0] = (jint)subID;
316    auxDataPtr[1] = (jint)receiveLen;
317    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
318    return id;
319}
320
321static void nContextInitToClient(JNIEnv *_env, jobject _this, RsContext con)
322{
323    LOG_API("nContextInitToClient, con(%p)", con);
324    dispatchTab.ContextInitToClient(con);
325}
326
327static void nContextDeinitToClient(JNIEnv *_env, jobject _this, RsContext con)
328{
329    LOG_API("nContextDeinitToClient, con(%p)", con);
330    dispatchTab.ContextDeinitToClient(con);
331}
332
333static void
334nContextSendMessage(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray data)
335{
336    jint *ptr = NULL;
337    jint len = 0;
338    if (data) {
339        len = _env->GetArrayLength(data);
340        jint *ptr = _env->GetIntArrayElements(data, NULL);
341    }
342    LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", con, id, len);
343    dispatchTab.ContextSendMessage(con, id, (const uint8_t *)ptr, len * sizeof(int));
344    if (data) {
345        _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
346    }
347}
348
349
350
351static jint
352nElementCreate(JNIEnv *_env, jobject _this, RsContext con, jint type, jint kind, jboolean norm, jint size)
353{
354    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size);
355    return (jint)dispatchTab.ElementCreate(con, (RsDataType)type, (RsDataKind)kind, norm, size);
356}
357
358static jint
359nElementCreate2(JNIEnv *_env, jobject _this, RsContext con,
360                jintArray _ids, jobjectArray _names, jintArray _arraySizes)
361{
362    int fieldCount = _env->GetArrayLength(_ids);
363    LOG_API("nElementCreate2, con(%p)", con);
364
365    jint *ids = _env->GetIntArrayElements(_ids, NULL);
366    jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
367
368    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
369
370    const char **nameArray = names.c_str();
371    size_t *sizeArray = names.c_str_len();
372
373    jint id = (jint)dispatchTab.ElementCreate2(con,
374                                     (RsElement *)ids, fieldCount,
375                                     nameArray, fieldCount * sizeof(size_t),  sizeArray,
376                                     (const uint32_t *)arraySizes, fieldCount);
377
378    _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT);
379    _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT);
380    return (jint)id;
381}
382
383
384
385static void
386nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id,
387                       jintArray _IDs,
388                       jobjectArray _names,
389                       jintArray _arraySizes)
390{
391    int dataSize = _env->GetArrayLength(_IDs);
392    LOG_API("nElementGetSubElements, con(%p)", con);
393
394    uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
395    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
396    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
397
398    dispatchTab.ElementGetSubElements(con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
399
400    for(jint i = 0; i < dataSize; i++) {
401        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
402        _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
403        _env->SetIntArrayRegion(_arraySizes, i, 1, (const jint*)&arraySizes[i]);
404    }
405
406    free(ids);
407    free(names);
408    free(arraySizes);
409}
410
411// -----------------------------------
412
413static int
414nTypeCreate(JNIEnv *_env, jobject _this, RsContext con, RsElement eid,
415            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
416{
417    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
418            con, eid, dimx, dimy, dimz, mips, faces, yuv);
419
420    jint id = (jint)dispatchTab.TypeCreate(con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
421    return (jint)id;
422}
423
424// -----------------------------------
425
426static jint
427nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage, jint pointer)
428{
429    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", con, (RsElement)type, mips, usage, (void *)pointer);
430    return (jint) dispatchTab.AllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uint32_t)pointer);
431}
432
433static void
434nAllocationSyncAll(JNIEnv *_env, jobject _this, RsContext con, jint a, jint bits)
435{
436    LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", con, (RsAllocation)a, bits);
437    dispatchTab.AllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
438}
439
440static void
441nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
442{
443    LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", con, (RsAllocation)alloc);
444    dispatchTab.AllocationGenerateMipmaps(con, (RsAllocation)alloc);
445}
446
447static size_t GetBitmapSize(JNIEnv *env, jobject jbitmap) {
448    AndroidBitmapInfo info;
449    memset(&info, 0, sizeof(info));
450    AndroidBitmap_getInfo(env, jbitmap, &info);
451    size_t s = info.width * info.height;
452    switch (info.format) {
453        case ANDROID_BITMAP_FORMAT_RGBA_8888: s *= 4; break;
454        case ANDROID_BITMAP_FORMAT_RGB_565: s *= 2; break;
455        case ANDROID_BITMAP_FORMAT_RGBA_4444: s *= 2; break;
456    }
457    return s;
458}
459
460static int
461nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
462{
463    jint id = 0;
464    void *pixels = NULL;
465    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
466
467    if (pixels != NULL) {
468        id = (jint)dispatchTab.AllocationCreateFromBitmap(con,
469                                                (RsType)type, (RsAllocationMipmapControl)mip,
470                                                pixels, GetBitmapSize(_env, jbitmap), usage);
471        AndroidBitmap_unlockPixels(_env, jbitmap);
472    }
473    return id;
474}
475
476static int
477nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
478{
479    jint id = 0;
480    void *pixels = NULL;
481    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
482
483    if (pixels != NULL) {
484        id = (jint)dispatchTab.AllocationCreateTyped(con,
485                                          (RsType)type, (RsAllocationMipmapControl)mip,
486                                          (uint32_t)usage, (uintptr_t)pixels);
487        AndroidBitmap_unlockPixels(_env, jbitmap);
488    }
489    return id;
490}
491
492static int
493nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
494{
495    void *pixels = NULL;
496    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
497
498    jint id = 0;
499    if (pixels != NULL) {
500        id = (jint)dispatchTab.AllocationCubeCreateFromBitmap(con,
501                                                    (RsType)type, (RsAllocationMipmapControl)mip,
502                                                    pixels, GetBitmapSize(_env, jbitmap), usage);
503        AndroidBitmap_unlockPixels(_env, jbitmap);
504    }
505    return id;
506}
507
508static void
509nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
510{
511    AndroidBitmapInfo info;
512    memset(&info, 0, sizeof(info));
513    AndroidBitmap_getInfo(_env, jbitmap, &info);
514
515    void *pixels = NULL;
516    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
517
518    if (pixels != NULL) {
519        dispatchTab.Allocation2DData(con, (RsAllocation)alloc, 0, 0,
520                           0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
521                           info.width, info.height, pixels, GetBitmapSize(_env, jbitmap), 0);
522        AndroidBitmap_unlockPixels(_env, jbitmap);
523    }
524}
525
526static void
527nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
528{
529    AndroidBitmapInfo info;
530    memset(&info, 0, sizeof(info));
531    AndroidBitmap_getInfo(_env, jbitmap, &info);
532
533    void *pixels = NULL;
534    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
535
536    if (pixels != NULL) {
537        dispatchTab.AllocationCopyToBitmap(con, (RsAllocation)alloc, pixels, GetBitmapSize(_env, jbitmap));
538        AndroidBitmap_unlockPixels(_env, jbitmap);
539    }
540    //bitmap.notifyPixelsChanged();
541}
542
543
544static void
545nAllocationData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jintArray data, int sizeBytes)
546{
547    jint len = _env->GetArrayLength(data);
548    LOG_API("nAllocation1DData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
549    jint *ptr = _env->GetIntArrayElements(data, NULL);
550    dispatchTab.Allocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
551    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
552}
553
554static void
555nAllocationData1D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jshortArray data, int sizeBytes)
556{
557    jint len = _env->GetArrayLength(data);
558    LOG_API("nAllocation1DData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
559    jshort *ptr = _env->GetShortArrayElements(data, NULL);
560    dispatchTab.Allocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
561    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
562}
563
564static void
565nAllocationData1D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jbyteArray data, int sizeBytes)
566{
567    jint len = _env->GetArrayLength(data);
568    LOG_API("nAllocation1DData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
569    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
570    dispatchTab.Allocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
571    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
572}
573
574static void
575nAllocationData1D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jfloatArray data, int sizeBytes)
576{
577    jint len = _env->GetArrayLength(data);
578    LOG_API("nAllocation1DData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
579    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
580    dispatchTab.Allocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
581    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
582}
583
584static void
585//    native void rsnAllocationElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
586nAllocationElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes)
587{
588    jint len = _env->GetArrayLength(data);
589    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
590    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
591    dispatchTab.Allocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
592    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
593}
594
595static void
596nAllocationData2D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
597                    jint w, jint h, jshortArray data, int sizeBytes)
598{
599    jint len = _env->GetArrayLength(data);
600    LOG_API("nAllocation2DData_s, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
601    jshort *ptr = _env->GetShortArrayElements(data, NULL);
602    dispatchTab.Allocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
603    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
604}
605
606static void
607nAllocationData2D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
608                    jint w, jint h, jbyteArray data, int sizeBytes)
609{
610    jint len = _env->GetArrayLength(data);
611    LOG_API("nAllocation2DData_b, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
612    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
613    dispatchTab.Allocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
614    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
615}
616
617static void
618nAllocationData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
619                    jint w, jint h, jintArray data, int sizeBytes)
620{
621    jint len = _env->GetArrayLength(data);
622    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
623    jint *ptr = _env->GetIntArrayElements(data, NULL);
624    dispatchTab.Allocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
625    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
626}
627
628static void
629nAllocationData2D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
630                    jint w, jint h, jfloatArray data, int sizeBytes)
631{
632    jint len = _env->GetArrayLength(data);
633    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
634    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
635    dispatchTab.Allocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes, 0);
636    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
637}
638
639static void
640nAllocationData2D_alloc(JNIEnv *_env, jobject _this, RsContext con,
641                        jint dstAlloc, jint dstXoff, jint dstYoff,
642                        jint dstMip, jint dstFace,
643                        jint width, jint height,
644                        jint srcAlloc, jint srcXoff, jint srcYoff,
645                        jint srcMip, jint srcFace)
646{
647    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
648            " dstMip(%i), dstFace(%i), width(%i), height(%i),"
649            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
650            con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
651            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
652
653    dispatchTab.AllocationCopy2DRange(con,
654                            (RsAllocation)dstAlloc,
655                            dstXoff, dstYoff,
656                            dstMip, dstFace,
657                            width, height,
658                            (RsAllocation)srcAlloc,
659                            srcXoff, srcYoff,
660                            srcMip, srcFace);
661}
662
663static void
664nAllocationData3D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
665                    jint w, jint h, jint d, jshortArray data, int sizeBytes)
666{
667    jint len = _env->GetArrayLength(data);
668    LOG_API("nAllocation3DData_s, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
669    jshort *ptr = _env->GetShortArrayElements(data, NULL);
670    dispatchTab.Allocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
671    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
672}
673
674static void
675nAllocationData3D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
676                    jint w, jint h, jint d, jbyteArray data, int sizeBytes)
677{
678    jint len = _env->GetArrayLength(data);
679    LOG_API("nAllocation3DData_b, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
680    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
681    dispatchTab.Allocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
682    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
683}
684
685static void
686nAllocationData3D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
687                    jint w, jint h, jint d, jintArray data, int sizeBytes)
688{
689    jint len = _env->GetArrayLength(data);
690    LOG_API("nAllocation3DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
691    jint *ptr = _env->GetIntArrayElements(data, NULL);
692    dispatchTab.Allocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
693    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
694}
695
696static void
697nAllocationData3D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
698                    jint w, jint h, jint d, jfloatArray data, int sizeBytes)
699{
700    jint len = _env->GetArrayLength(data);
701    LOG_API("nAllocation3DData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
702    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
703    dispatchTab.Allocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
704    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
705}
706
707static void
708nAllocationData3D_alloc(JNIEnv *_env, jobject _this, RsContext con,
709                        jint dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
710                        jint dstMip,
711                        jint width, jint height, jint depth,
712                        jint srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
713                        jint srcMip)
714{
715    LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
716            " dstMip(%i), width(%i), height(%i),"
717            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
718            con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
719            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
720
721    dispatchTab.AllocationCopy3DRange(con,
722                            (RsAllocation)dstAlloc,
723                            dstXoff, dstYoff, dstZoff, dstMip,
724                            width, height, depth,
725                            (RsAllocation)srcAlloc,
726                            srcXoff, srcYoff, srcZoff, srcMip);
727}
728
729static void
730nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
731{
732    jint len = _env->GetArrayLength(data);
733    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
734    jint *ptr = _env->GetIntArrayElements(data, NULL);
735    jsize length = _env->GetArrayLength(data);
736    dispatchTab.AllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(int));
737    _env->ReleaseIntArrayElements(data, ptr, 0);
738}
739
740static void
741nAllocationRead_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jshortArray data)
742{
743    jint len = _env->GetArrayLength(data);
744    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
745    jshort *ptr = _env->GetShortArrayElements(data, NULL);
746    jsize length = _env->GetArrayLength(data);
747    dispatchTab.AllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(short));
748    _env->ReleaseShortArrayElements(data, ptr, 0);
749}
750
751static void
752nAllocationRead_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jbyteArray data)
753{
754    jint len = _env->GetArrayLength(data);
755    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
756    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
757    jsize length = _env->GetArrayLength(data);
758    dispatchTab.AllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(char));
759    _env->ReleaseByteArrayElements(data, ptr, 0);
760}
761
762static void
763nAllocationRead_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jfloatArray data)
764{
765    jint len = _env->GetArrayLength(data);
766    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
767    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
768    jsize length = _env->GetArrayLength(data);
769    dispatchTab.AllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(float));
770    _env->ReleaseFloatArrayElements(data, ptr, 0);
771}
772
773static jint
774nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
775{
776    LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a);
777    return (jint) dispatchTab.AllocationGetType(con, (RsAllocation)a);
778}
779
780static void
781nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
782{
783    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
784    dispatchTab.AllocationResize1D(con, (RsAllocation)alloc, dimX);
785}
786
787// -----------------------------------
788
789static void
790nScriptBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint script, jint alloc, jint slot)
791{
792    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
793    dispatchTab.ScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
794}
795
796static void
797nScriptSetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
798{
799    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
800    dispatchTab.ScriptSetVarI(con, (RsScript)script, slot, val);
801}
802
803static void
804nScriptSetVarObj(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
805{
806    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
807    dispatchTab.ScriptSetVarObj(con, (RsScript)script, slot, (RsObjectBase)val);
808}
809
810static void
811nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
812{
813    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
814    dispatchTab.ScriptSetVarJ(con, (RsScript)script, slot, val);
815}
816
817static void
818nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
819{
820    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
821    dispatchTab.ScriptSetVarF(con, (RsScript)script, slot, val);
822}
823
824static void
825nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
826{
827    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
828    dispatchTab.ScriptSetVarD(con, (RsScript)script, slot, val);
829}
830
831static void
832nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
833{
834    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
835    jint len = _env->GetArrayLength(data);
836    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
837    dispatchTab.ScriptSetVarV(con, (RsScript)script, slot, ptr, len);
838    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
839}
840
841static void
842nScriptSetVarVE(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data, jint elem, jintArray dims)
843{
844    LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
845    jint len = _env->GetArrayLength(data);
846    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
847    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
848    jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
849    dispatchTab.ScriptSetVarVE(con, (RsScript)script, slot, ptr, len, (RsElement)elem,
850                     (const uint32_t *)dimsPtr, dimsLen);
851    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
852    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
853}
854
855
856static void
857nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
858{
859    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
860
861    jint length = _env->GetArrayLength(timeZone);
862    jbyte* timeZone_ptr;
863    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
864
865    dispatchTab.ScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
866
867    if (timeZone_ptr) {
868        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
869    }
870}
871
872static void
873nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
874{
875    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
876    dispatchTab.ScriptInvoke(con, (RsScript)obj, slot);
877}
878
879static void
880nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
881{
882    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
883    jint len = _env->GetArrayLength(data);
884    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
885    dispatchTab.ScriptInvokeV(con, (RsScript)script, slot, ptr, len);
886    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
887}
888
889static void
890nScriptForEach(JNIEnv *_env, jobject _this, RsContext con,
891               jint script, jint slot, jint ain, jint aout)
892{
893    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
894    dispatchTab.ScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, NULL, 0);
895}
896static void
897nScriptForEachV(JNIEnv *_env, jobject _this, RsContext con,
898                jint script, jint slot, jint ain, jint aout, jbyteArray params)
899{
900    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
901    jint len = _env->GetArrayLength(params);
902    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
903    dispatchTab.ScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, NULL, 0);
904    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
905}
906
907static void
908nScriptForEachClipped(JNIEnv *_env, jobject _this, RsContext con,
909                      jint script, jint slot, jint ain, jint aout,
910                      jint xstart, jint xend,
911                      jint ystart, jint yend, jint zstart, jint zend)
912{
913    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
914    RsScriptCall sc;
915    sc.xStart = xstart;
916    sc.xEnd = xend;
917    sc.yStart = ystart;
918    sc.yEnd = yend;
919    sc.zStart = zstart;
920    sc.zEnd = zend;
921    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
922    sc.arrayStart = 0;
923    sc.arrayEnd = 0;
924    dispatchTab.ScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc));
925}
926
927static void
928nScriptForEachClippedV(JNIEnv *_env, jobject _this, RsContext con,
929                       jint script, jint slot, jint ain, jint aout,
930                       jbyteArray params, jint xstart, jint xend,
931                       jint ystart, jint yend, jint zstart, jint zend)
932{
933    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
934    jint len = _env->GetArrayLength(params);
935    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
936    RsScriptCall sc;
937    sc.xStart = xstart;
938    sc.xEnd = xend;
939    sc.yStart = ystart;
940    sc.yEnd = yend;
941    sc.zStart = zstart;
942    sc.zEnd = zend;
943    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
944    sc.arrayStart = 0;
945    sc.arrayEnd = 0;
946    dispatchTab.ScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, &sc, sizeof(sc));
947    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
948}
949
950// -----------------------------------
951
952static jint
953nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con,
954               jstring resName, jstring cacheDir,
955               jbyteArray scriptRef, jint length)
956{
957    LOG_API("nScriptCCreate, con(%p)", con);
958
959    AutoJavaStringToUTF8 resNameUTF(_env, resName);
960    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
961    jint ret = 0;
962    jbyte* script_ptr = NULL;
963    jint _exception = 0;
964    jint remaining;
965    if (!scriptRef) {
966        _exception = 1;
967        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
968        goto exit;
969    }
970    if (length < 0) {
971        _exception = 1;
972        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
973        goto exit;
974    }
975    remaining = _env->GetArrayLength(scriptRef);
976    if (remaining < length) {
977        _exception = 1;
978        //jniThrowException(_env, "java/lang/IllegalArgumentException",
979        //        "length > script.length - offset");
980        goto exit;
981    }
982    script_ptr = (jbyte *)
983        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
984
985    //rsScriptCSetText(con, (const char *)script_ptr, length);
986
987    ret = (jint)dispatchTab.ScriptCCreate(con,
988                                resNameUTF.c_str(), resNameUTF.length(),
989                                cacheDirUTF.c_str(), cacheDirUTF.length(),
990                                (const char *)script_ptr, length);
991
992exit:
993    if (script_ptr) {
994        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
995                _exception ? JNI_ABORT: 0);
996    }
997
998    return ret;
999}
1000
1001static jint
1002nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, RsContext con, jint id, jint eid)
1003{
1004    LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", con, id, (void *)eid);
1005    return (jint)dispatchTab.ScriptIntrinsicCreate(con, id, (RsElement)eid);
1006}
1007
1008static jint
1009nScriptKernelIDCreate(JNIEnv *_env, jobject _this, RsContext con, jint sid, jint slot, jint sig)
1010{
1011    LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con, (void *)sid, slot, sig);
1012    return (jint)dispatchTab.ScriptKernelIDCreate(con, (RsScript)sid, slot, sig);
1013}
1014
1015static jint
1016nScriptFieldIDCreate(JNIEnv *_env, jobject _this, RsContext con, jint sid, jint slot)
1017{
1018    LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", con, (void *)sid, slot);
1019    return (jint)dispatchTab.ScriptFieldIDCreate(con, (RsScript)sid, slot);
1020}
1021
1022static jint
1023nScriptGroupCreate(JNIEnv *_env, jobject _this, RsContext con, jintArray _kernels, jintArray _src,
1024    jintArray _dstk, jintArray _dstf, jintArray _types)
1025{
1026    LOG_API("nScriptGroupCreate, con(%p)", con);
1027
1028    jint kernelsLen = _env->GetArrayLength(_kernels) * sizeof(int);
1029    jint *kernelsPtr = _env->GetIntArrayElements(_kernels, NULL);
1030    jint srcLen = _env->GetArrayLength(_src) * sizeof(int);
1031    jint *srcPtr = _env->GetIntArrayElements(_src, NULL);
1032    jint dstkLen = _env->GetArrayLength(_dstk) * sizeof(int);
1033    jint *dstkPtr = _env->GetIntArrayElements(_dstk, NULL);
1034    jint dstfLen = _env->GetArrayLength(_dstf) * sizeof(int);
1035    jint *dstfPtr = _env->GetIntArrayElements(_dstf, NULL);
1036    jint typesLen = _env->GetArrayLength(_types) * sizeof(int);
1037    jint *typesPtr = _env->GetIntArrayElements(_types, NULL);
1038
1039    int id = (int)dispatchTab.ScriptGroupCreate(con,
1040                               (RsScriptKernelID *)kernelsPtr, kernelsLen,
1041                               (RsScriptKernelID *)srcPtr, srcLen,
1042                               (RsScriptKernelID *)dstkPtr, dstkLen,
1043                               (RsScriptFieldID *)dstfPtr, dstfLen,
1044                               (RsType *)typesPtr, typesLen);
1045
1046    _env->ReleaseIntArrayElements(_kernels, kernelsPtr, 0);
1047    _env->ReleaseIntArrayElements(_src, srcPtr, 0);
1048    _env->ReleaseIntArrayElements(_dstk, dstkPtr, 0);
1049    _env->ReleaseIntArrayElements(_dstf, dstfPtr, 0);
1050    _env->ReleaseIntArrayElements(_types, typesPtr, 0);
1051    return id;
1052}
1053
1054static void
1055nScriptGroupSetInput(JNIEnv *_env, jobject _this, RsContext con, jint gid, jint kid, jint alloc)
1056{
1057    LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", con,
1058        (void *)gid, (void *)kid, (void *)alloc);
1059    dispatchTab.ScriptGroupSetInput(con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1060}
1061
1062static void
1063nScriptGroupSetOutput(JNIEnv *_env, jobject _this, RsContext con, jint gid, jint kid, jint alloc)
1064{
1065    LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", con,
1066        (void *)gid, (void *)kid, (void *)alloc);
1067    dispatchTab.ScriptGroupSetOutput(con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1068}
1069
1070static void
1071nScriptGroupExecute(JNIEnv *_env, jobject _this, RsContext con, jint gid)
1072{
1073    LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", con, (void *)gid);
1074    dispatchTab.ScriptGroupExecute(con, (RsScriptGroup)gid);
1075}
1076
1077// ---------------------------------------------------------------------------
1078
1079static jint
1080nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con, jint magFilter, jint minFilter,
1081               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1082{
1083    LOG_API("nSamplerCreate, con(%p)", con);
1084    return (jint)dispatchTab.SamplerCreate(con,
1085                                 (RsSamplerValue)magFilter,
1086                                 (RsSamplerValue)minFilter,
1087                                 (RsSamplerValue)wrapS,
1088                                 (RsSamplerValue)wrapT,
1089                                 (RsSamplerValue)wrapR,
1090                                 aniso);
1091}
1092
1093// ---------------------------------------------------------------------------
1094
1095
1096static const char *classPathName = "android/support/v8/renderscript/RenderScript";
1097
1098static JNINativeMethod methods[] = {
1099{"nLoadSO",                        "(Z)Z",                                    (bool*)nLoadSO },
1100{"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
1101{"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
1102{"nDeviceSetConfig",               "(III)V",                                  (void*)nDeviceSetConfig },
1103{"nContextGetUserMessage",         "(I[I)I",                                  (void*)nContextGetUserMessage },
1104{"nContextGetErrorMessage",        "(I)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1105{"nContextPeekMessage",            "(I[I)I",                                  (void*)nContextPeekMessage },
1106
1107{"nContextInitToClient",           "(I)V",                                    (void*)nContextInitToClient },
1108{"nContextDeinitToClient",         "(I)V",                                    (void*)nContextDeinitToClient },
1109
1110
1111// All methods below are thread protected in java.
1112{"rsnContextCreate",                 "(IIII)I",                               (void*)nContextCreate },
1113{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
1114{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
1115{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
1116{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
1117{"rsnContextSendMessage",            "(II[I)V",                               (void*)nContextSendMessage },
1118{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
1119{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
1120{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
1121{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
1122
1123{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
1124{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
1125{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
1126
1127{"rsnTypeCreate",                    "(IIIIIZZI)I",                           (void*)nTypeCreate },
1128
1129{"rsnAllocationCreateTyped",         "(IIIII)I",                               (void*)nAllocationCreateTyped },
1130{"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
1131{"rsnAllocationCreateBitmapBackedAllocation",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateBitmapBackedAllocation },
1132{"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
1133
1134{"rsnAllocationCopyFromBitmap",      "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1135{"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1136
1137{"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
1138{"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
1139{"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
1140{"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
1141{"rsnAllocationData1D",              "(IIIII[FI)V",                           (void*)nAllocationData1D_f },
1142{"rsnAllocationElementData1D",       "(IIIII[BI)V",                           (void*)nAllocationElementData1D },
1143{"rsnAllocationData2D",              "(IIIIIIII[II)V",                        (void*)nAllocationData2D_i },
1144{"rsnAllocationData2D",              "(IIIIIIII[SI)V",                        (void*)nAllocationData2D_s },
1145{"rsnAllocationData2D",              "(IIIIIIII[BI)V",                        (void*)nAllocationData2D_b },
1146{"rsnAllocationData2D",              "(IIIIIIII[FI)V",                        (void*)nAllocationData2D_f },
1147{"rsnAllocationData2D",              "(IIIIIIIIIIIII)V",                      (void*)nAllocationData2D_alloc },
1148{"rsnAllocationData3D",              "(IIIIIIIII[II)V",                       (void*)nAllocationData3D_i },
1149{"rsnAllocationData3D",              "(IIIIIIIII[SI)V",                       (void*)nAllocationData3D_s },
1150{"rsnAllocationData3D",              "(IIIIIIIII[BI)V",                       (void*)nAllocationData3D_b },
1151{"rsnAllocationData3D",              "(IIIIIIIII[FI)V",                       (void*)nAllocationData3D_f },
1152{"rsnAllocationData3D",              "(IIIIIIIIIIIIII)V",                     (void*)nAllocationData3D_alloc },
1153{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
1154{"rsnAllocationRead",                "(II[S)V",                               (void*)nAllocationRead_s },
1155{"rsnAllocationRead",                "(II[B)V",                               (void*)nAllocationRead_b },
1156{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
1157{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
1158{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
1159{"rsnAllocationGenerateMipmaps",     "(II)V",                                 (void*)nAllocationGenerateMipmaps },
1160
1161{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
1162{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
1163{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
1164{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
1165{"rsnScriptForEach",                 "(IIIII)V",                              (void*)nScriptForEach },
1166{"rsnScriptForEach",                 "(IIIII[B)V",                            (void*)nScriptForEachV },
1167{"rsnScriptForEachClipped",          "(IIIIIIIIIII)V",                        (void*)nScriptForEachClipped },
1168{"rsnScriptForEachClipped",          "(IIIII[BIIIIII)V",                      (void*)nScriptForEachClippedV },
1169{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
1170{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
1171{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
1172{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
1173{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
1174{"rsnScriptSetVarVE",                "(III[BI[I)V",                           (void*)nScriptSetVarVE },
1175{"rsnScriptSetVarObj",               "(IIII)V",                               (void*)nScriptSetVarObj },
1176
1177{"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;[BI)I",  (void*)nScriptCCreate },
1178{"rsnScriptIntrinsicCreate",         "(III)I",                                (void*)nScriptIntrinsicCreate },
1179{"rsnScriptKernelIDCreate",          "(IIII)I",                               (void*)nScriptKernelIDCreate },
1180{"rsnScriptFieldIDCreate",           "(III)I",                                (void*)nScriptFieldIDCreate },
1181{"rsnScriptGroupCreate",             "(I[I[I[I[I[I)I",                        (void*)nScriptGroupCreate },
1182{"rsnScriptGroup2Create",            "(J[J)J",                                (void*)nScriptGroup2Create },
1183{"rsnScriptGroupSetInput",           "(IIII)V",                               (void*)nScriptGroupSetInput },
1184{"rsnScriptGroupSetOutput",          "(IIII)V",                               (void*)nScriptGroupSetOutput },
1185{"rsnScriptGroupExecute",            "(II)V",                                 (void*)nScriptGroupExecute },
1186{"rsnSamplerCreate",                 "(IIIIIIF)I",                            (void*)nSamplerCreate },
1187
1188};
1189
1190// ---------------------------------------------------------------------------
1191
1192jint JNI_OnLoad(JavaVM* vm, void* reserved)
1193{
1194    JNIEnv* env = NULL;
1195    jclass clazz = NULL;
1196    jint result = -1;
1197
1198    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1199        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
1200        //            "ERROR: GetEnv failed\n");
1201        goto bail;
1202    }
1203    if (env == NULL) {
1204        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
1205        goto bail;
1206    }
1207
1208    clazz = env->FindClass(classPathName);
1209    if (clazz == NULL) {
1210        goto bail;
1211    }
1212
1213    if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) {
1214        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
1215        //            "ERROR: MediaPlayer native registration failed\n");
1216        goto bail;
1217    }
1218
1219    /* success -- return valid version number */
1220    result = JNI_VERSION_1_4;
1221
1222bail:
1223    return result;
1224}
1225