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