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