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