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 
36 template <typename... T>
UNUSED(T...t)37 void UNUSED(T... t) {}
38 #define PER_ARRAY_TYPE(flag, fnc, readonly, ...) {                                      \
39     jint len = 0;                                                                       \
40     void *ptr = nullptr;                                                                \
41     void *srcPtr = nullptr;                                                             \
42     size_t typeBytes = 0;                                                               \
43     jint relFlag = 0;                                                                   \
44     if (readonly) {                                                                     \
45         /* The on-release mode should only be JNI_ABORT for read-only accesses. */      \
46         /* readonly = true, also indicates we are copying to the allocation   . */      \
47         relFlag = JNI_ABORT;                                                            \
48     }                                                                                   \
49     switch(dataType) {                                                                  \
50     case RS_TYPE_FLOAT_32:                                                              \
51         len = _env->GetArrayLength((jfloatArray)data);                                  \
52         ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
53         typeBytes = 4;                                                                  \
54         if (usePadding) {                                                               \
55             srcPtr = ptr;                                                               \
56             len = len / 3 * 4;                                                          \
57             if (count == 0) {                                                           \
58                 count = len / 4;                                                        \
59             }                                                                           \
60             ptr = malloc (len * typeBytes);                                             \
61             if (readonly) {                                                             \
62                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
63                 fnc(__VA_ARGS__);                                                       \
64             } else {                                                                    \
65                 fnc(__VA_ARGS__);                                                       \
66                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
67             }                                                                           \
68             free(ptr);                                                                  \
69             ptr = srcPtr;                                                               \
70         } else {                                                                        \
71             fnc(__VA_ARGS__);                                                           \
72         }                                                                               \
73         _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag);     \
74         return;                                                                         \
75     case RS_TYPE_FLOAT_64:                                                              \
76         len = _env->GetArrayLength((jdoubleArray)data);                                 \
77         ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
78         typeBytes = 8;                                                                  \
79         if (usePadding) {                                                               \
80             srcPtr = ptr;                                                               \
81             len = len / 3 * 4;                                                          \
82             if (count == 0) {                                                           \
83                 count = len / 4;                                                        \
84             }                                                                           \
85             ptr = malloc (len * typeBytes);                                             \
86             if (readonly) {                                                             \
87                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
88                 fnc(__VA_ARGS__);                                                       \
89             } else {                                                                    \
90                 fnc(__VA_ARGS__);                                                       \
91                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
92             }                                                                           \
93             free(ptr);                                                                  \
94             ptr = srcPtr;                                                               \
95         } else {                                                                        \
96             fnc(__VA_ARGS__);                                                           \
97         }                                                                               \
98         _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag);  \
99         return;                                                                         \
100     case RS_TYPE_SIGNED_8:                                                              \
101     case RS_TYPE_UNSIGNED_8:                                                            \
102         len = _env->GetArrayLength((jbyteArray)data);                                   \
103         ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
104         typeBytes = 1;                                                                  \
105         if (usePadding) {                                                               \
106             srcPtr = ptr;                                                               \
107             len = len / 3 * 4;                                                          \
108             if (count == 0) {                                                           \
109                 count = len / 4;                                                        \
110             }                                                                           \
111             ptr = malloc (len * typeBytes);                                             \
112             if (readonly) {                                                             \
113                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
114                 fnc(__VA_ARGS__);                                                       \
115             } else {                                                                    \
116                 fnc(__VA_ARGS__);                                                       \
117                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
118             }                                                                           \
119             free(ptr);                                                                  \
120             ptr = srcPtr;                                                               \
121         } else {                                                                        \
122             fnc(__VA_ARGS__);                                                           \
123         }                                                                               \
124         _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag);         \
125         return;                                                                         \
126     case RS_TYPE_SIGNED_16:                                                             \
127     case RS_TYPE_UNSIGNED_16:                                                           \
128         len = _env->GetArrayLength((jshortArray)data);                                  \
129         ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
130         typeBytes = 2;                                                                  \
131         if (usePadding) {                                                               \
132             srcPtr = ptr;                                                               \
133             len = len / 3 * 4;                                                          \
134             if (count == 0) {                                                           \
135                 count = len / 4;                                                        \
136             }                                                                           \
137             ptr = malloc (len * typeBytes);                                             \
138             if (readonly) {                                                             \
139                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
140                 fnc(__VA_ARGS__);                                                       \
141             } else {                                                                    \
142                 fnc(__VA_ARGS__);                                                       \
143                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
144             }                                                                           \
145             free(ptr);                                                                  \
146             ptr = srcPtr;                                                               \
147         } else {                                                                        \
148             fnc(__VA_ARGS__);                                                           \
149         }                                                                               \
150         _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag);     \
151         return;                                                                         \
152     case RS_TYPE_SIGNED_32:                                                             \
153     case RS_TYPE_UNSIGNED_32:                                                           \
154         len = _env->GetArrayLength((jintArray)data);                                    \
155         ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
156         typeBytes = 4;                                                                  \
157         if (usePadding) {                                                               \
158             srcPtr = ptr;                                                               \
159             len = len / 3 * 4;                                                          \
160             if (count == 0) {                                                           \
161                 count = len / 4;                                                        \
162             }                                                                           \
163             ptr = malloc (len * typeBytes);                                             \
164             if (readonly) {                                                             \
165                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
166                 fnc(__VA_ARGS__);                                                       \
167             } else {                                                                    \
168                 fnc(__VA_ARGS__);                                                       \
169                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
170             }                                                                           \
171             free(ptr);                                                                  \
172             ptr = srcPtr;                                                               \
173         } else {                                                                        \
174             fnc(__VA_ARGS__);                                                           \
175         }                                                                               \
176         _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag);           \
177         return;                                                                         \
178     case RS_TYPE_SIGNED_64:                                                             \
179     case RS_TYPE_UNSIGNED_64:                                                           \
180         len = _env->GetArrayLength((jlongArray)data);                                   \
181         ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
182         typeBytes = 8;                                                                  \
183         if (usePadding) {                                                               \
184             srcPtr = ptr;                                                               \
185             len = len / 3 * 4;                                                          \
186             if (count == 0) {                                                           \
187                 count = len / 4;                                                        \
188             }                                                                           \
189             ptr = malloc (len * typeBytes);                                             \
190             if (readonly) {                                                             \
191                 copyWithPadding(ptr, srcPtr, mSize, count);                             \
192                 fnc(__VA_ARGS__);                                                       \
193             } else {                                                                    \
194                 fnc(__VA_ARGS__);                                                       \
195                 copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
196             }                                                                           \
197             free(ptr);                                                                  \
198             ptr = srcPtr;                                                               \
199         } else {                                                                        \
200             fnc(__VA_ARGS__);                                                           \
201         }                                                                               \
202         _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag);        \
203         return;                                                                         \
204     default:                                                                            \
205         break;                                                                          \
206     }                                                                                   \
207     UNUSED(len, ptr, srcPtr, typeBytes, relFlag);                                       \
208 }
209 
210 
211 class AutoJavaStringToUTF8 {
212 public:
AutoJavaStringToUTF8(JNIEnv * env,jstring str)213     AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
214         fCStr = env->GetStringUTFChars(str, NULL);
215         fLength = env->GetStringUTFLength(str);
216     }
~AutoJavaStringToUTF8()217     ~AutoJavaStringToUTF8() {
218         fEnv->ReleaseStringUTFChars(fJStr, fCStr);
219     }
c_str() const220     const char* c_str() const { return fCStr; }
length() const221     jsize length() const { return fLength; }
222 
223 private:
224     JNIEnv*     fEnv;
225     jstring     fJStr;
226     const char* fCStr;
227     jsize       fLength;
228 };
229 
230 class AutoJavaStringArrayToUTF8 {
231 public:
AutoJavaStringArrayToUTF8(JNIEnv * env,jobjectArray strings,jsize stringsLength)232     AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
233     : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
234         mCStrings = NULL;
235         mSizeArray = NULL;
236         if (stringsLength > 0) {
237             mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
238             mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
239             for (jsize ct = 0; ct < stringsLength; ct ++) {
240                 jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
241                 mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
242                 mSizeArray[ct] = mEnv->GetStringUTFLength(s);
243             }
244         }
245     }
~AutoJavaStringArrayToUTF8()246     ~AutoJavaStringArrayToUTF8() {
247         for (jsize ct=0; ct < mStringsLength; ct++) {
248             jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
249             mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
250         }
251         free(mCStrings);
252         free(mSizeArray);
253     }
c_str() const254     const char **c_str() const { return mCStrings; }
c_str_len() const255     size_t *c_str_len() const { return mSizeArray; }
length() const256     jsize length() const { return mStringsLength; }
257 
258 private:
259     JNIEnv      *mEnv;
260     jobjectArray mStrings;
261     const char **mCStrings;
262     size_t      *mSizeArray;
263     jsize        mStringsLength;
264 };
265 
266 
267 // ---------------------------------------------------------------------------
268 static dispatchTable dispatchTab;
269 // Incremental Support lib
270 static dispatchTable dispatchTabInc;
271 
nLoadSO(JNIEnv * _env,jobject _this,jboolean useNative,jint targetApi)272 static jboolean nLoadSO(JNIEnv *_env, jobject _this, jboolean useNative, jint targetApi) {
273     void* handle = NULL;
274     if (useNative) {
275         handle = dlopen("libRS.so", RTLD_LAZY | RTLD_LOCAL);
276     } else {
277         handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
278     }
279     if (handle == NULL) {
280         LOG_API("couldn't dlopen %s, %s", filename, dlerror());
281         return false;
282     }
283 
284     if (loadSymbols(handle, dispatchTab, targetApi) == false) {
285         LOG_API("%s init failed!", filename);
286         return false;
287     }
288     LOG_API("Successfully loaded %s", filename);
289     return true;
290 }
291 
292 static ioSuppDT ioDispatch;
nLoadIOSO(JNIEnv * _env,jobject _this)293 static jboolean nLoadIOSO(JNIEnv *_env, jobject _this) {
294     void* handleIO = NULL;
295     handleIO = dlopen("libRSSupportIO.so", RTLD_LAZY | RTLD_LOCAL);
296     if (handleIO == NULL) {
297         LOG_API("Couldn't load libRSSupportIO.so");
298         return false;
299     }
300     if (loadIOSuppSyms(handleIO, ioDispatch) == false) {
301         LOG_API("libRSSupportIO init failed!");
302         return false;
303     }
304     return true;
305 }
306 
307 // ---------------------------------------------------------------------------
308 
copyWithPadding(void * ptr,void * srcPtr,int mSize,int count)309 static void copyWithPadding(void* ptr, void* srcPtr, int mSize, int count) {
310     int sizeBytesPad = mSize * 4;
311     int sizeBytes = mSize * 3;
312     uint8_t *dst = static_cast<uint8_t *>(ptr);
313     uint8_t *src = static_cast<uint8_t *>(srcPtr);
314     for (int i = 0; i < count; i++) {
315         memcpy(dst, src, sizeBytes);
316         dst += sizeBytesPad;
317         src += sizeBytes;
318     }
319 }
320 
copyWithUnPadding(void * ptr,void * srcPtr,int mSize,int count)321 static void copyWithUnPadding(void* ptr, void* srcPtr, int mSize, int count) {
322     int sizeBytesPad = mSize * 4;
323     int sizeBytes = mSize * 3;
324     uint8_t *dst = static_cast<uint8_t *>(ptr);
325     uint8_t *src = static_cast<uint8_t *>(srcPtr);
326     for (int i = 0; i < count; i++) {
327         memcpy(dst, src, sizeBytes);
328         dst += sizeBytes;
329         src += sizeBytesPad;
330     }
331 }
332 
333 
334 // ---------------------------------------------------------------------------
335 
336 static void
nContextFinish(JNIEnv * _env,jobject _this,jlong con)337 nContextFinish(JNIEnv *_env, jobject _this, jlong con)
338 {
339     LOG_API("nContextFinish, con(%p)", (RsContext)con);
340     dispatchTab.ContextFinish((RsContext)con);
341 }
342 
343 static jlong
nClosureCreate(JNIEnv * _env,jobject _this,jlong con,jlong kernelID,jlong returnValue,jlongArray fieldIDArray,jlongArray valueArray,jintArray sizeArray,jlongArray depClosureArray,jlongArray depFieldIDArray)344 nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
345                jlong returnValue, jlongArray fieldIDArray,
346                jlongArray valueArray, jintArray sizeArray,
347                jlongArray depClosureArray, jlongArray depFieldIDArray) {
348   jlong ret = 0;
349 
350   jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
351   jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
352   jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
353   jsize values_length = _env->GetArrayLength(valueArray);
354   jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
355   jsize sizes_length = _env->GetArrayLength(sizeArray);
356   jlong* jDepClosures =
357       _env->GetLongArrayElements(depClosureArray, nullptr);
358   jsize depClosures_length = _env->GetArrayLength(depClosureArray);
359   jlong* jDepFieldIDs =
360       _env->GetLongArrayElements(depFieldIDArray, nullptr);
361   jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
362 
363   size_t numValues, numDependencies;
364   RsScriptFieldID* fieldIDs;
365   uintptr_t* values;
366   RsClosure* depClosures;
367   RsScriptFieldID* depFieldIDs;
368 
369   if (fieldIDs_length != values_length || values_length != sizes_length) {
370       LOG_API("Unmatched field IDs, values, and sizes in closure creation.");
371       goto exit;
372   }
373 
374   numValues = (size_t)fieldIDs_length;
375 
376   if (depClosures_length != depFieldIDs_length) {
377       LOG_API("Unmatched closures and field IDs for dependencies in closure creation.");
378       goto exit;
379   }
380 
381   numDependencies = (size_t)depClosures_length;
382 
383   if (numDependencies > numValues) {
384       LOG_API("Unexpected number of dependencies in closure creation");
385       goto exit;
386   }
387 
388   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
389       LOG_API("Too many arguments or globals in closure creation");
390       goto exit;
391   }
392 
393   fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
394   if (fieldIDs == nullptr) {
395       goto exit;
396   }
397 
398   for (size_t i = 0; i < numValues; i++) {
399     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
400   }
401 
402   values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues);
403   if (values == nullptr) {
404       goto exit;
405   }
406 
407   for (size_t i = 0; i < numValues; i++) {
408     values[i] = (uintptr_t)jValues[i];
409   }
410 
411   depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies);
412   if (depClosures == nullptr) {
413       goto exit;
414   }
415 
416   for (size_t i = 0; i < numDependencies; i++) {
417     depClosures[i] = (RsClosure)jDepClosures[i];
418   }
419 
420   depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies);
421   if (depFieldIDs == nullptr) {
422       goto exit;
423   }
424 
425   for (size_t i = 0; i < numDependencies; i++) {
426     depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
427   }
428 
429   ret = (jlong)(uintptr_t)dispatchTab.ClosureCreate(
430       (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
431       fieldIDs, numValues, values, numValues,
432       (int*)jSizes, numValues,
433       depClosures, numDependencies,
434       depFieldIDs, numDependencies);
435 
436 exit:
437 
438   _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT);
439   _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT);
440   _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
441   _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
442   _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
443 
444   return ret;
445 }
446 
447 static jlong
nInvokeClosureCreate(JNIEnv * _env,jobject _this,jlong con,jlong invokeID,jbyteArray paramArray,jlongArray fieldIDArray,jlongArray valueArray,jintArray sizeArray)448 nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
449                      jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
450                      jintArray sizeArray) {
451   jlong ret = 0;
452 
453   jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
454   jsize jParamLength = _env->GetArrayLength(paramArray);
455   jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
456   jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
457   jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
458   jsize values_length = _env->GetArrayLength(valueArray);
459   jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
460   jsize sizes_length = _env->GetArrayLength(sizeArray);
461 
462   size_t numValues;
463   RsScriptFieldID* fieldIDs;
464   uintptr_t* values;
465 
466   if (fieldIDs_length != values_length || values_length != sizes_length) {
467       LOG_API("Unmatched field IDs, values, and sizes in closure creation.");
468       goto exit;
469   }
470 
471   numValues = (size_t) fieldIDs_length;
472 
473   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
474       LOG_API("Too many arguments or globals in closure creation");
475       goto exit;
476   }
477 
478   fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
479   if (fieldIDs == nullptr) {
480       goto exit;
481   }
482 
483   for (size_t i = 0; i < numValues; i++) {
484     fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
485   }
486 
487   values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues);
488   if (values == nullptr) {
489       goto exit;
490   }
491 
492   for (size_t i = 0; i < numValues; i++) {
493     values[i] = (uintptr_t)jValues[i];
494   }
495 
496   ret = (jlong)(uintptr_t)dispatchTab.InvokeClosureCreate(
497       (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
498       fieldIDs, numValues, values, numValues,
499       (int*)jSizes, numValues);
500 
501 exit:
502 
503   _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
504   _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
505   _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
506   _env->ReleaseByteArrayElements(paramArray,      jParams,      JNI_ABORT);
507 
508   return ret;
509 }
510 
511 static void
nClosureSetArg(JNIEnv * _env,jobject _this,jlong con,jlong closureID,jint index,jlong value,jint size)512 nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
513                jint index, jlong value, jint size) {
514   dispatchTab.ClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
515                   (uintptr_t)value, (size_t)size);
516 }
517 
518 static void
nClosureSetGlobal(JNIEnv * _env,jobject _this,jlong con,jlong closureID,jlong fieldID,jlong value,jint size)519 nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
520                   jlong fieldID, jlong value, jint size) {
521   dispatchTab.ClosureSetGlobal((RsContext)con, (RsClosure)closureID,
522                      (RsScriptFieldID)fieldID, (uintptr_t)value, (size_t)size);
523 }
524 
525 static long
nScriptGroup2Create(JNIEnv * _env,jobject _this,jlong con,jstring name,jstring cacheDir,jlongArray closureArray)526 nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name,
527                     jstring cacheDir, jlongArray closureArray) {
528   jlong ret = 0;
529 
530   AutoJavaStringToUTF8 nameUTF(_env, name);
531   AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
532 
533   jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
534   jsize numClosures = _env->GetArrayLength(closureArray);
535 
536   RsClosure* closures;
537 
538   if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
539     LOG_API("Too many closures in script group");
540     goto exit;
541   }
542 
543   closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
544   if (closures == nullptr) {
545       goto exit;
546   }
547 
548   for (int i = 0; i < numClosures; i++) {
549     closures[i] = (RsClosure)jClosures[i];
550   }
551 
552   ret = (jlong)(uintptr_t)dispatchTab.ScriptGroup2Create(
553       (RsContext)con, nameUTF.c_str(), nameUTF.length(),
554       cacheDirUTF.c_str(), cacheDirUTF.length(),
555       closures, numClosures);
556 
557 exit:
558 
559   _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT);
560 
561   return ret;
562 }
563 
564 static void
nScriptGroup2Execute(JNIEnv * _env,jobject _this,jlong con,jlong groupID)565 nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) {
566   dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID);
567 }
568 
569 static void
nObjDestroy(JNIEnv * _env,jobject _this,jlong con,jlong obj)570 nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
571 {
572     LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
573     dispatchTab.ObjDestroy((RsContext)con, (void *)obj);
574 }
575 
576 
577 static void
nScriptIntrinsicBLAS_Single(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong id,jint func,jint TransA,jint TransB,jint Side,jint Uplo,jint Diag,jint M,jint N,jint K,jfloat alpha,jlong A,jlong B,jfloat beta,jlong C,jint incX,jint incY,jint KL,jint KU,jboolean mUseInc)578 nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
579                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
580                             jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY,
581                             jint KL, jint KU, jboolean mUseInc) {
582     RsBlasCall call;
583     memset(&call, 0, sizeof(call));
584     call.func = (RsBlasFunction)func;
585     call.transA = (RsBlasTranspose)TransA;
586     call.transB = (RsBlasTranspose)TransB;
587     call.side = (RsBlasSide)Side;
588     call.uplo = (RsBlasUplo)Uplo;
589     call.diag = (RsBlasDiag)Diag;
590     call.M = M;
591     call.N = N;
592     call.K = K;
593     call.alpha.f = alpha;
594     call.beta.f = beta;
595     call.incX = incX;
596     call.incY = incY;
597     call.KL = KL;
598     call.KU = KU;
599 
600     RsAllocation in_allocs[3];
601     in_allocs[0] = (RsAllocation)A;
602     in_allocs[1] = (RsAllocation)B;
603     in_allocs[2] = (RsAllocation)C;
604 
605     if (mUseInc) {
606         dispatchTab.ContextFinish((RsContext)con);
607         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
608                                           in_allocs, sizeof(in_allocs), nullptr,
609                                           &call, sizeof(call), nullptr, 0);
610     } else {
611         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
612                                        in_allocs, sizeof(in_allocs), nullptr,
613                                        &call, sizeof(call), nullptr, 0);
614     }
615 }
616 
617 static void
nScriptIntrinsicBLAS_Double(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong id,jint func,jint TransA,jint TransB,jint Side,jint Uplo,jint Diag,jint M,jint N,jint K,jdouble alpha,jlong A,jlong B,jdouble beta,jlong C,jint incX,jint incY,jint KL,jint KU,jboolean mUseInc)618 nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
619                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
620                             jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY,
621                             jint KL, jint KU, jboolean mUseInc) {
622     RsBlasCall call;
623     memset(&call, 0, sizeof(call));
624     call.func = (RsBlasFunction)func;
625     call.transA = (RsBlasTranspose)TransA;
626     call.transB = (RsBlasTranspose)TransB;
627     call.side = (RsBlasSide)Side;
628     call.uplo = (RsBlasUplo)Uplo;
629     call.diag = (RsBlasDiag)Diag;
630     call.M = M;
631     call.N = N;
632     call.K = K;
633     call.alpha.d = alpha;
634     call.beta.d = beta;
635     call.incX = incX;
636     call.incY = incY;
637     call.KL = KL;
638     call.KU = KU;
639 
640     RsAllocation in_allocs[3];
641     in_allocs[0] = (RsAllocation)A;
642     in_allocs[1] = (RsAllocation)B;
643     in_allocs[2] = (RsAllocation)C;
644 
645     if (mUseInc) {
646         dispatchTab.ContextFinish((RsContext)con);
647         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
648                                           in_allocs, sizeof(in_allocs), nullptr,
649                                           &call, sizeof(call), nullptr, 0);
650     } else {
651         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
652                                         in_allocs, sizeof(in_allocs), nullptr,
653                                         &call, sizeof(call), nullptr, 0);
654     }
655 }
656 
657 static void
nScriptIntrinsicBLAS_Complex(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong id,jint func,jint TransA,jint TransB,jint Side,jint Uplo,jint Diag,jint M,jint N,jint K,jfloat alphaX,jfloat alphaY,jlong A,jlong B,jfloat betaX,jfloat betaY,jlong C,jint incX,jint incY,jint KL,jint KU,jboolean mUseInc)658 nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
659                              jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
660                              jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX,
661                              jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) {
662     RsBlasCall call;
663     memset(&call, 0, sizeof(call));
664     call.func = (RsBlasFunction)func;
665     call.transA = (RsBlasTranspose)TransA;
666     call.transB = (RsBlasTranspose)TransB;
667     call.side = (RsBlasSide)Side;
668     call.uplo = (RsBlasUplo)Uplo;
669     call.diag = (RsBlasDiag)Diag;
670     call.M = M;
671     call.N = N;
672     call.K = K;
673     call.alpha.c.r = alphaX;
674     call.alpha.c.i = alphaY;
675     call.beta.c.r = betaX;
676     call.beta.c.i = betaY;
677     call.incX = incX;
678     call.incY = incY;
679     call.KL = KL;
680     call.KU = KU;
681 
682     RsAllocation in_allocs[3];
683     in_allocs[0] = (RsAllocation)A;
684     in_allocs[1] = (RsAllocation)B;
685     in_allocs[2] = (RsAllocation)C;
686 
687 
688     if (mUseInc) {
689         dispatchTab.ContextFinish((RsContext)con);
690         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
691                                           in_allocs, sizeof(in_allocs), nullptr,
692                                           &call, sizeof(call), nullptr, 0);
693     } else {
694         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
695                                        in_allocs, sizeof(in_allocs), nullptr,
696                                        &call, sizeof(call), nullptr, 0);
697     }
698 }
699 
700 static void
nScriptIntrinsicBLAS_Z(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong id,jint func,jint TransA,jint TransB,jint Side,jint Uplo,jint Diag,jint M,jint N,jint K,jdouble alphaX,jdouble alphaY,jlong A,jlong B,jdouble betaX,jdouble betaY,jlong C,jint incX,jint incY,jint KL,jint KU,jboolean mUseInc)701 nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA,
702                        jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
703                        jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX,
704                        jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) {
705     RsBlasCall call;
706     memset(&call, 0, sizeof(call));
707     call.func = (RsBlasFunction)func;
708     call.transA = (RsBlasTranspose)TransA;
709     call.transB = (RsBlasTranspose)TransB;
710     call.side = (RsBlasSide)Side;
711     call.uplo = (RsBlasUplo)Uplo;
712     call.diag = (RsBlasDiag)Diag;
713     call.M = M;
714     call.N = N;
715     call.K = K;
716     call.alpha.z.r = alphaX;
717     call.alpha.z.i = alphaY;
718     call.beta.z.r = betaX;
719     call.beta.z.i = betaY;
720     call.incX = incX;
721     call.incY = incY;
722     call.KL = KL;
723     call.KU = KU;
724 
725     RsAllocation in_allocs[3];
726     in_allocs[0] = (RsAllocation)A;
727     in_allocs[1] = (RsAllocation)B;
728     in_allocs[2] = (RsAllocation)C;
729 
730 
731     if (mUseInc) {
732         dispatchTab.ContextFinish((RsContext)con);
733         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
734                                           in_allocs, sizeof(in_allocs), nullptr,
735                                           &call, sizeof(call), nullptr, 0);
736     } else {
737         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
738                                         in_allocs, sizeof(in_allocs), nullptr,
739                                         &call, sizeof(call), nullptr, 0);
740     }
741 }
742 
743 
744 static void
nScriptIntrinsicBLAS_BNNM(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong id,jint M,jint N,jint K,jlong A,jint a_offset,jlong B,jint b_offset,jlong C,jint c_offset,jint c_mult_int,jboolean mUseInc)745 nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint M, jint N, jint K,
746                           jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset,
747                           jint c_mult_int, jboolean mUseInc) {
748     RsBlasCall call;
749     memset(&call, 0, sizeof(call));
750     call.func = RsBlas_bnnm;
751     call.M = M;
752     call.N = N;
753     call.K = K;
754     call.a_offset = a_offset & 0xFF;
755     call.b_offset = b_offset & 0xFF;
756     call.c_offset = c_offset;
757     call.c_mult_int = c_mult_int;
758 
759     RsAllocation in_allocs[3];
760     in_allocs[0] = (RsAllocation)A;
761     in_allocs[1] = (RsAllocation)B;
762     in_allocs[2] = (RsAllocation)C;
763 
764     if (mUseInc) {
765         dispatchTab.ContextFinish((RsContext)con);
766         dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0,
767                                           in_allocs, sizeof(in_allocs), nullptr,
768                                           &call, sizeof(call), nullptr, 0);
769     } else {
770         dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0,
771                                         in_allocs, sizeof(in_allocs), nullptr,
772                                         &call, sizeof(call), nullptr, 0);
773     }
774 }
775 // ---------------------------------------------------------------------------
776 static jlong
nDeviceCreate(JNIEnv * _env,jobject _this)777 nDeviceCreate(JNIEnv *_env, jobject _this)
778 {
779     LOG_API("nDeviceCreate");
780     return (jlong)(uintptr_t)dispatchTab.DeviceCreate();
781 }
782 
783 static void
nDeviceDestroy(JNIEnv * _env,jobject _this,jlong dev)784 nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
785 {
786     LOG_API("nDeviceDestroy");
787     return dispatchTab.DeviceDestroy((RsDevice)dev);
788 }
789 
790 static void
nDeviceSetConfig(JNIEnv * _env,jobject _this,jlong dev,jint p,jint value)791 nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
792 {
793     LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
794     return dispatchTab.DeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
795 }
796 
797 static jlong
nContextCreate(JNIEnv * _env,jobject _this,jlong dev,jint ver,jint sdkVer,jint ct,jstring nativeLibDirJava)798 nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
799                jint ct, jstring nativeLibDirJava)
800 {
801     LOG_API("nContextCreate");
802     // Access the NativeLibDir in the Java Context.
803     const char * nativeLibDir = _env->GetStringUTFChars(nativeLibDirJava, JNI_FALSE);
804     size_t length = (size_t)_env->GetStringUTFLength(nativeLibDirJava);
805 
806     jlong id = (jlong)(uintptr_t)dispatchTab.ContextCreate((RsDevice)dev, ver,
807                                                            sdkVer,
808                                                            (RsContextType)ct, 0);
809     if (dispatchTab.SetNativeLibDir) {
810         dispatchTab.SetNativeLibDir((RsContext)id, nativeLibDir, length);
811     }
812 
813     _env->ReleaseStringUTFChars(nativeLibDirJava, nativeLibDir);
814     return id;
815 }
816 
817 
818 static void
nContextSetPriority(JNIEnv * _env,jobject _this,jlong con,jint p)819 nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
820 {
821     LOG_API("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
822     dispatchTab.ContextSetPriority((RsContext)con, p);
823 }
824 
825 
826 
827 static void
nContextDestroy(JNIEnv * _env,jobject _this,jlong con)828 nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
829 {
830     LOG_API("nContextDestroy, con(%p)", (RsContext)con);
831     dispatchTab.ContextDestroy((RsContext)con);
832 }
833 
834 static void
nContextDump(JNIEnv * _env,jobject _this,jlong con,jint bits)835 nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
836 {
837     LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
838     dispatchTab.ContextDump((RsContext)con, bits);
839 }
840 
841 
842 static jstring
nContextGetErrorMessage(JNIEnv * _env,jobject _this,jlong con)843 nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
844 {
845     LOG_API("nContextGetErrorMessage, con(%p)", (RsContext)con);
846     char buf[1024];
847 
848     size_t receiveLen;
849     uint32_t subID;
850     int id = dispatchTab.ContextGetMessage((RsContext)con,
851                                            buf, sizeof(buf),
852                                            &receiveLen, sizeof(receiveLen),
853                                            &subID, sizeof(subID));
854     if (!id && receiveLen) {
855         //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
856         //            "message receive buffer too small.  %zu", receiveLen);
857     }
858     return _env->NewStringUTF(buf);
859 }
860 
861 static jint
nContextGetUserMessage(JNIEnv * _env,jobject _this,jlong con,jintArray data)862 nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
863 {
864     jint len = _env->GetArrayLength(data);
865     LOG_API("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
866     jint *ptr = _env->GetIntArrayElements(data, NULL);
867     size_t receiveLen;
868     uint32_t subID;
869     int id = dispatchTab.ContextGetMessage((RsContext)con,
870                                            ptr, len * 4,
871                                            &receiveLen, sizeof(receiveLen),
872                                            &subID, sizeof(subID));
873     if (!id && receiveLen) {
874         //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
875         //            "message receive buffer too small.  %zu", receiveLen);
876     }
877     _env->ReleaseIntArrayElements(data, ptr, 0);
878     return (jint)id;
879 }
880 
881 static jint
nContextPeekMessage(JNIEnv * _env,jobject _this,jlong con,jintArray auxData)882 nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
883 {
884     LOG_API("nContextPeekMessage, con(%p)", (RsContext)con);
885     jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
886     size_t receiveLen;
887     uint32_t subID;
888     int id = dispatchTab.ContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
889                                   &subID, sizeof(subID));
890     auxDataPtr[0] = (jint)subID;
891     auxDataPtr[1] = (jint)receiveLen;
892     _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
893     return (jint)id;
894 }
895 
nContextInitToClient(JNIEnv * _env,jobject _this,jlong con)896 static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
897 {
898     LOG_API("nContextInitToClient, con(%p)", (RsContext)con);
899     dispatchTab.ContextInitToClient((RsContext)con);
900 }
901 
nContextDeinitToClient(JNIEnv * _env,jobject _this,jlong con)902 static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
903 {
904     LOG_API("nContextDeinitToClient, con(%p)", (RsContext)con);
905     dispatchTab.ContextDeinitToClient((RsContext)con);
906 }
907 
908 static void
nContextSendMessage(JNIEnv * _env,jobject _this,jlong con,jint id,jintArray data)909 nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
910 {
911     jint *ptr = NULL;
912     jint len = 0;
913     if (data) {
914         len = _env->GetArrayLength(data);
915         jint *ptr = _env->GetIntArrayElements(data, NULL);
916     }
917     LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
918     dispatchTab.ContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
919     if (data) {
920         _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
921     }
922 }
923 
924 
925 
926 static jlong
nElementCreate(JNIEnv * _env,jobject _this,jlong con,jlong type,jint kind,jboolean norm,jint size)927 nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind,
928                jboolean norm, jint size)
929 {
930     LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
931             type, kind, norm, size);
932     return (jlong)(uintptr_t)dispatchTab.ElementCreate((RsContext)con,
933                                                        (RsDataType)type,
934                                                        (RsDataKind)kind,
935                                                        norm, size);
936 }
937 
938 static jlong
nElementCreate2(JNIEnv * _env,jobject _this,jlong con,jlongArray _ids,jobjectArray _names,jintArray _arraySizes)939 nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
940                 jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
941 {
942     int fieldCount = _env->GetArrayLength(_ids);
943     LOG_API("nElementCreate2, con(%p)", (RsContext)con);
944 
945     jlong *jIds = _env->GetLongArrayElements(_ids, NULL);
946     jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
947 
948     RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
949     uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
950 
951     for(int i = 0; i < fieldCount; i ++) {
952         ids[i] = (RsElement)jIds[i];
953         arraySizes[i] = (uint32_t)jArraySizes[i];
954     }
955 
956     AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
957 
958     const char **nameArray = names.c_str();
959     size_t *sizeArray = names.c_str_len();
960 
961     jlong id = (jlong)(uintptr_t)dispatchTab.ElementCreate2((RsContext)con, (RsElement *)ids,
962                                                             fieldCount, nameArray,
963                                                             fieldCount * sizeof(size_t),  sizeArray,
964                                                             (const uint32_t *)arraySizes, fieldCount);
965 
966     free(ids);
967     free(arraySizes);
968     _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
969     _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
970     return id;
971 }
972 
973 
974 
975 
976 static void
nElementGetSubElements(JNIEnv * _env,jobject _this,jlong con,jlong id,jlongArray _IDs,jobjectArray _names,jintArray _arraySizes)977 nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
978                        jlongArray _IDs,
979                        jobjectArray _names,
980                        jintArray _arraySizes)
981 {
982     uint32_t dataSize = _env->GetArrayLength(_IDs);
983     LOG_API("nElementGetSubElements, con(%p)", (RsContext)con);
984 
985     uintptr_t *ids = (uintptr_t *)malloc(dataSize * sizeof(uintptr_t));
986     const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
987     uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
988 
989     dispatchTab.ElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
990                                       (uint32_t)dataSize);
991 
992     for(uint32_t i = 0; i < dataSize; i++) {
993         const jlong id = (jlong)(uintptr_t)ids[i];
994         const jint arraySize = (jint)arraySizes[i];
995         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
996         _env->SetLongArrayRegion(_IDs, i, 1, &id);
997         _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
998     }
999 
1000     free(ids);
1001     free(names);
1002     free(arraySizes);
1003 }
1004 
1005 // -----------------------------------
1006 
1007 static jlong
nTypeCreate(JNIEnv * _env,jobject _this,jlong con,jlong eid,jint dimx,jint dimy,jint dimz,jboolean mips,jboolean faces,jint yuv)1008 nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
1009             jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
1010 {
1011     LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
1012             (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
1013 
1014     return (jlong)(uintptr_t)dispatchTab.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
1015                                                     dimz, mips, faces, yuv);
1016 }
1017 
1018 // -----------------------------------
1019 
1020 static jlong
nAllocationCreateTyped(JNIEnv * _env,jobject _this,jlong con,jlong type,jint mips,jint usage,jlong pointer)1021 nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
1022                        jlong pointer)
1023 {
1024     LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
1025             (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
1026     return (jlong)(uintptr_t) dispatchTab.AllocationCreateTyped((RsContext)con, (RsType)type,
1027                                                                 (RsAllocationMipmapControl)mips,
1028                                                                 (uint32_t)usage, (uintptr_t)pointer);
1029 }
1030 
1031 static void
nAllocationSyncAll(JNIEnv * _env,jobject _this,jlong con,jlong a,jint bits)1032 nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
1033 {
1034     LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a, bits);
1035     dispatchTab.AllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
1036 }
1037 
1038 static void
nAllocationSetSurface(JNIEnv * _env,jobject _this,jlong con,jlong alloc,jobject sur)1039 nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
1040 {
1041     ioDispatch.sAllocationSetSurface(_env, _this, (RsContext)con, (RsAllocation)alloc, sur, dispatchTab);
1042 }
1043 
1044 static void
nAllocationIoSend(JNIEnv * _env,jobject _this,jlong con,jlong alloc)1045 nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1046 {
1047     dispatchTab.AllocationIoSend((RsContext)con, (RsAllocation)alloc);
1048 }
1049 
1050 static void
nAllocationGenerateMipmaps(JNIEnv * _env,jobject _this,jlong con,jlong alloc)1051 nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1052 {
1053     LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
1054     dispatchTab.AllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
1055 }
1056 
GetBitmapSize(JNIEnv * env,jobject jbitmap)1057 static size_t GetBitmapSize(JNIEnv *env, jobject jbitmap) {
1058     AndroidBitmapInfo info;
1059     memset(&info, 0, sizeof(info));
1060     AndroidBitmap_getInfo(env, jbitmap, &info);
1061     size_t s = info.width * info.height;
1062     switch (info.format) {
1063         case ANDROID_BITMAP_FORMAT_RGBA_8888: s *= 4; break;
1064         case ANDROID_BITMAP_FORMAT_RGB_565: s *= 2; break;
1065         case ANDROID_BITMAP_FORMAT_RGBA_4444: s *= 2; break;
1066     }
1067     return s;
1068 }
1069 
1070 static jlong
nAllocationCreateFromBitmap(JNIEnv * _env,jobject _this,jlong con,jlong type,jint mip,jobject jbitmap,jint usage)1071 nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
1072                             jobject jbitmap, jint usage)
1073 {
1074     jlong id = 0;
1075     void *pixels = NULL;
1076     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
1077 
1078     if (pixels != NULL) {
1079         id = (jlong)(uintptr_t)dispatchTab.AllocationCreateFromBitmap((RsContext)con,
1080                                                                       (RsType)type,
1081                                                                       (RsAllocationMipmapControl)mip,
1082                                                                       pixels,
1083                                                                       GetBitmapSize(_env, jbitmap),
1084                                                                       usage);
1085         AndroidBitmap_unlockPixels(_env, jbitmap);
1086     }
1087     return id;
1088 }
1089 
1090 static jlong
nAllocationCreateBitmapBackedAllocation(JNIEnv * _env,jobject _this,jlong con,jlong type,jint mip,jobject jbitmap,jint usage)1091 nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
1092                                         jint mip, jobject jbitmap, jint usage)
1093 {
1094     jlong id = 0;
1095     void *pixels = NULL;
1096     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
1097 
1098     if (pixels != NULL) {
1099         id = (jlong)(uintptr_t)dispatchTab.AllocationCreateTyped((RsContext)con,
1100                                                                  (RsType)type,
1101                                                                  (RsAllocationMipmapControl)mip,
1102                                                                  (uint32_t)usage,
1103                                                                  (uintptr_t)pixels);
1104         AndroidBitmap_unlockPixels(_env, jbitmap);
1105     }
1106     return id;
1107 }
1108 
1109 static jlong
nAllocationCubeCreateFromBitmap(JNIEnv * _env,jobject _this,jlong con,jlong type,jint mip,jobject jbitmap,jint usage)1110 nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type,
1111                                 jint mip, jobject jbitmap, jint usage)
1112 {
1113     void *pixels = NULL;
1114     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
1115 
1116     jlong id = 0;
1117     if (pixels != NULL) {
1118         id = (jlong)(uintptr_t)dispatchTab.AllocationCubeCreateFromBitmap((RsContext)con,
1119                                                                           (RsType)type,
1120                                                                           (RsAllocationMipmapControl)mip,
1121                                                                           pixels,
1122                                                                           GetBitmapSize(_env, jbitmap),
1123                                                                           usage);
1124         AndroidBitmap_unlockPixels(_env, jbitmap);
1125     }
1126     return id;
1127 }
1128 
1129 static void
nAllocationCopyFromBitmap(JNIEnv * _env,jobject _this,jlong con,jlong alloc,jobject jbitmap)1130 nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1131 {
1132     AndroidBitmapInfo info;
1133     memset(&info, 0, sizeof(info));
1134     AndroidBitmap_getInfo(_env, jbitmap, &info);
1135 
1136     void *pixels = NULL;
1137     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
1138 
1139     if (pixels != NULL) {
1140         dispatchTab.Allocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0, 0,
1141                                      RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, info.width,
1142                                      info.height, pixels, GetBitmapSize(_env, jbitmap), 0);
1143         AndroidBitmap_unlockPixels(_env, jbitmap);
1144     }
1145 }
1146 
1147 static void
nAllocationCopyToBitmap(JNIEnv * _env,jobject _this,jlong con,jlong alloc,jobject jbitmap)1148 nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1149 {
1150     AndroidBitmapInfo info;
1151     memset(&info, 0, sizeof(info));
1152     AndroidBitmap_getInfo(_env, jbitmap, &info);
1153 
1154     void *pixels = NULL;
1155     AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
1156 
1157     if (pixels != NULL) {
1158         dispatchTab.AllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, pixels,
1159                                            GetBitmapSize(_env, jbitmap));
1160         AndroidBitmap_unlockPixels(_env, jbitmap);
1161     }
1162     //bitmap.notifyPixelsChanged();
1163 }
1164 
1165 // Copies from the Java object data into the Allocation pointed to by _alloc.
1166 static void
nAllocationData1D(JNIEnv * _env,jobject _this,jlong con,jlong _alloc,jint offset,jint lod,jint count,jobject data,jint sizeBytes,jint dataType,jint mSize,jboolean usePadding)1167 nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1168                   jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
1169                   jboolean usePadding)
1170 {
1171     RsAllocation *alloc = (RsAllocation *)_alloc;
1172     LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1173             "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
1174             dataType);
1175     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation1DData, true,
1176                    (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1177 }
1178 
1179 
1180 static void
nAllocationElementData1D(JNIEnv * _env,jobject _this,jlong con,jlong alloc,jint xoff,jint lod,jint compIdx,jbyteArray data,jint sizeBytes)1181 nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint xoff,
1182                          jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1183 {
1184     jint len = _env->GetArrayLength(data);
1185     LOG_API("nAllocationElementData1D, con(%p), alloc(%p), xoff(%i), comp(%i), len(%i), "
1186             "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, compIdx, len,
1187             sizeBytes);
1188     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1189     dispatchTab.Allocation1DElementData((RsContext)con, (RsAllocation)alloc, xoff,
1190                                         lod, ptr, sizeBytes, compIdx);
1191     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1192 }
1193 
1194 /*
1195 static void
1196 nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1197                        jint xoff, jint yoff, jint zoff,
1198                        jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1199 {
1200     jint len = _env->GetArrayLength(data);
1201     LOG_API("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1202             "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1203             sizeBytes);
1204     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1205     dispatchTab.AllocationElementData((RsContext)con, (RsAllocation)alloc,
1206                                       xoff, yoff, zoff,
1207                                       lod, ptr, sizeBytes, compIdx);
1208     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1209 }
1210 */
1211 
1212 // Copies from the Java object data into the Allocation pointed to by _alloc.
1213 static void
nAllocationData2D(JNIEnv * _env,jobject _this,jlong con,jlong _alloc,jint xoff,jint yoff,jint lod,jint _face,jint w,jint h,jobject data,jint sizeBytes,jint dataType,jint mSize,jboolean usePadding)1214 nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1215                   jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
1216                   jboolean usePadding)
1217 {
1218     RsAllocation *alloc = (RsAllocation *)_alloc;
1219     RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1220     LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1221             "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1222     int count = w * h;
1223     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation2DData, true,
1224                    (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1225 }
1226 
1227 static void
nAllocationData2D_alloc(JNIEnv * _env,jobject _this,jlong con,jlong dstAlloc,jint dstXoff,jint dstYoff,jint dstMip,jint dstFace,jint width,jint height,jlong srcAlloc,jint srcXoff,jint srcYoff,jint srcMip,jint srcFace)1228 nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
1229                         jlong dstAlloc, jint dstXoff, jint dstYoff,
1230                         jint dstMip, jint dstFace,
1231                         jint width, jint height,
1232                         jlong srcAlloc, jint srcXoff, jint srcYoff,
1233                         jint srcMip, jint srcFace)
1234 {
1235     LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1236             " dstMip(%i), dstFace(%i), width(%i), height(%i),"
1237             " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
1238             (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
1239             width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
1240 
1241     dispatchTab.AllocationCopy2DRange((RsContext)con,
1242                                       (RsAllocation)dstAlloc,
1243                                       dstXoff, dstYoff,
1244                                       dstMip, dstFace,
1245                                       width, height,
1246                                       (RsAllocation)srcAlloc,
1247                                       srcXoff, srcYoff,
1248                                       srcMip, srcFace);
1249 }
1250 
1251 // Copies from the Java object data into the Allocation pointed to by _alloc.
1252 static void
nAllocationData3D(JNIEnv * _env,jobject _this,jlong con,jlong _alloc,jint xoff,jint yoff,jint zoff,jint lod,jint w,jint h,jint d,jobject data,jint sizeBytes,jint dataType,jint mSize,jboolean usePadding)1253 nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1254                   jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
1255                   jint mSize, jboolean usePadding)
1256 {
1257     RsAllocation *alloc = (RsAllocation *)_alloc;
1258     LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1259             " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1260             lod, w, h, d, sizeBytes);
1261     int count = w * h * d;
1262     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DData, true,
1263                    (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1264 }
1265 
1266 static void
nAllocationData3D_alloc(JNIEnv * _env,jobject _this,jlong con,jlong dstAlloc,jint dstXoff,jint dstYoff,jint dstZoff,jint dstMip,jint width,jint height,jint depth,jlong srcAlloc,jint srcXoff,jint srcYoff,jint srcZoff,jint srcMip)1267 nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
1268                         jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
1269                         jint dstMip,
1270                         jint width, jint height, jint depth,
1271                         jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
1272                         jint srcMip)
1273 {
1274     LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1275             " dstMip(%i), width(%i), height(%i),"
1276             " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
1277             (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
1278             width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
1279 
1280     dispatchTab.AllocationCopy3DRange((RsContext)con,
1281                                       (RsAllocation)dstAlloc,
1282                                       dstXoff, dstYoff, dstZoff, dstMip,
1283                                       width, height, depth,
1284                                       (RsAllocation)srcAlloc,
1285                                       srcXoff, srcYoff, srcZoff, srcMip);
1286 }
1287 
1288 // Copies from the Allocation pointed to by _alloc into the Java object data.
1289 static void
nAllocationRead(JNIEnv * _env,jobject _this,jlong con,jlong _alloc,jobject data,jint dataType,jint mSize,jboolean usePadding)1290 nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
1291                 jint mSize, jboolean usePadding)
1292 {
1293     RsAllocation *alloc = (RsAllocation *)_alloc;
1294     LOG_API("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1295     int count = 0;
1296     PER_ARRAY_TYPE(0, dispatchTab.AllocationRead, false,
1297                    (RsContext)con, alloc, ptr, len * typeBytes);
1298 }
1299 
1300 // Copies from the Allocation pointed to by _alloc into the Java object data.
1301 static void
nAllocationRead1D(JNIEnv * _env,jobject _this,jlong con,jlong _alloc,jint offset,jint lod,jint count,jobject data,jint sizeBytes,jint dataType,jint mSize,jboolean usePadding)1302 nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1303                   jint count, jobject data, jint sizeBytes, jint dataType,
1304                   jint mSize, jboolean usePadding)
1305 {
1306     RsAllocation *alloc = (RsAllocation *)_alloc;
1307     LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1308               "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
1309     PER_ARRAY_TYPE(0, dispatchTab.Allocation1DRead, false,
1310                    (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1311 }
1312 
1313 // Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
1314 /*
1315 static void
1316 nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc,
1317                        jint xoff, jint yoff, jint zoff,
1318                        jint lod, jint compIdx, jobject data, jint sizeBytes)
1319 {
1320     jint len = _env->GetArrayLength(data);
1321     LOG_API("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1322             "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1323             sizeBytes);
1324     jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1325     dispatchTab.AllocationElementRead((RsContext)con, (RsAllocation)alloc,
1326                                       xoff, yoff, zoff,
1327                                       lod, ptr, sizeBytes, compIdx);
1328     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1329 }
1330 */
1331 
1332 // Copies from the Allocation pointed to by _alloc into the Java object data.
1333 static void
nAllocationRead2D(JNIEnv * _env,jobject _this,jlong con,jlong _alloc,jint xoff,jint yoff,jint lod,jint _face,jint w,jint h,jobject data,jint sizeBytes,jint dataType,jint mSize,jboolean usePadding)1334 nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1335                   jint w, jint h, jobject data, jint sizeBytes, jint dataType,
1336                   jint mSize, jboolean usePadding)
1337 {
1338     RsAllocation *alloc = (RsAllocation *)_alloc;
1339     RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1340     LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1341               "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1342     int count = w * h;
1343     PER_ARRAY_TYPE(0, dispatchTab.Allocation2DRead, false,
1344                    (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1345 }
1346 
1347 // Copies from the Allocation pointed to by _alloc into the Java object data.
1348 /*
1349 static void
1350 nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1351                   jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
1352                   jint mSize, jboolean usePadding)
1353 {
1354     RsAllocation *alloc = (RsAllocation *)_alloc;
1355     LOG_API("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1356             " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1357             lod, w, h, d, sizeBytes);
1358     int count = w * h * d;
1359     PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DRead, false,
1360                    (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1361 }
1362 */
1363 
1364 static jlong
nAllocationGetType(JNIEnv * _env,jobject _this,jlong con,jlong a)1365 nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
1366 {
1367     LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1368     return (jlong)(uintptr_t) dispatchTab.AllocationGetType((RsContext)con, (RsAllocation)a);
1369 }
1370 
1371 static void
nAllocationResize1D(JNIEnv * _env,jobject _this,jlong con,jlong alloc,jint dimX)1372 nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
1373 {
1374     LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
1375             (RsAllocation)alloc, dimX);
1376     dispatchTab.AllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
1377 }
1378 
1379 // -----------------------------------
1380 
1381 static void
nScriptBindAllocation(JNIEnv * _env,jobject _this,jlong con,jlong script,jlong alloc,jint slot,jboolean mUseInc)1382 nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot, jboolean mUseInc)
1383 {
1384     LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)",
1385             (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1386     if (mUseInc) {
1387         dispatchTabInc.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1388     } else {
1389         dispatchTab.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1390     }
1391 }
1392 
1393 static void
nScriptSetVarI(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,jint val,jboolean mUseInc)1394 nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val, jboolean mUseInc)
1395 {
1396     LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
1397             (void *)script, slot, val);
1398     if (mUseInc) {
1399         dispatchTabInc.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1400     } else {
1401         dispatchTab.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1402     }
1403 }
1404 
1405 static void
nScriptSetVarObj(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,jlong val,jboolean mUseInc)1406 nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
1407 {
1408     LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con,
1409             (void *)script, slot, val);
1410     if (mUseInc) {
1411         dispatchTabInc.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1412     } else {
1413         dispatchTab.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1414     }
1415 }
1416 
1417 static void
nScriptSetVarJ(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,jlong val,jboolean mUseInc)1418 nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc)
1419 {
1420     LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con,
1421             (void *)script, slot, val);
1422     if (mUseInc) {
1423         dispatchTabInc.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1424     } else {
1425         dispatchTab.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1426     }
1427 }
1428 
1429 static void
nScriptSetVarF(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,float val,jboolean mUseInc)1430 nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val, jboolean mUseInc)
1431 {
1432     LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con,
1433             (void *)script, slot, val);
1434     if (mUseInc) {
1435         dispatchTabInc.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1436     } else {
1437         dispatchTab.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1438     }
1439 }
1440 
1441 static void
nScriptSetVarD(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,double val,jboolean mUseInc)1442 nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val, jboolean mUseInc)
1443 {
1444     LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con,
1445             (void *)script, slot, val);
1446     if (mUseInc) {
1447         dispatchTabInc.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1448     } else {
1449         dispatchTab.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1450     }
1451 }
1452 
1453 static void
nScriptSetVarV(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,jbyteArray data,jboolean mUseInc)1454 nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
1455 {
1456     LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1457     jint len = _env->GetArrayLength(data);
1458     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1459     if (mUseInc) {
1460         dispatchTabInc.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1461     } else {
1462         dispatchTab.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1463     }
1464     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1465 }
1466 
1467 static void
nScriptSetVarVE(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,jbyteArray data,jlong elem,jintArray dims,jboolean mUseInc)1468 nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
1469                 jlong elem, jintArray dims, jboolean mUseInc)
1470 {
1471     LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1472     jint len = _env->GetArrayLength(data);
1473     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1474     jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1475     jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
1476     if (mUseInc) {
1477         dispatchTabInc.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1478                                       (const uint32_t *)dimsPtr, dimsLen);
1479     } else {
1480         dispatchTab.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1481                                    (const uint32_t *)dimsPtr, dimsLen);
1482     }
1483     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1484     _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1485 }
1486 
1487 
1488 static void
nScriptSetTimeZone(JNIEnv * _env,jobject _this,jlong con,jlong script,jbyteArray timeZone,jboolean mUseInc)1489 nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone, jboolean mUseInc)
1490 {
1491     LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", (RsContext)con,
1492             (void *)script, (const char *)timeZone);
1493 
1494     jint length = _env->GetArrayLength(timeZone);
1495     jbyte* timeZone_ptr;
1496     timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1497     if (mUseInc) {
1498         dispatchTabInc.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1499     } else {
1500         dispatchTab.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1501     }
1502 
1503     if (timeZone_ptr) {
1504         _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1505     }
1506 }
1507 
1508 static void
nScriptInvoke(JNIEnv * _env,jobject _this,jlong con,jlong obj,jint slot,jboolean mUseInc)1509 nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot, jboolean mUseInc)
1510 {
1511     LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1512     if (mUseInc) {
1513         dispatchTabInc.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
1514     } else {
1515         dispatchTab.ScriptInvoke((RsContext)con, (RsScript)obj, slot);
1516     }
1517 }
1518 
1519 static void
nScriptInvokeV(JNIEnv * _env,jobject _this,jlong con,jlong script,jint slot,jbyteArray data,jboolean mUseInc)1520 nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc)
1521 {
1522     LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1523     jint len = _env->GetArrayLength(data);
1524     jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1525     if (mUseInc) {
1526         dispatchTabInc.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1527     } else {
1528         dispatchTab.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1529     }
1530     _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1531 }
1532 
1533 static void
nScriptForEach(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong script,jint slot,jlong ain,jlong aout,jboolean mUseInc)1534 nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1535                jlong script, jint slot, jlong ain, jlong aout, jboolean mUseInc)
1536 {
1537     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1538     if (mUseInc) {
1539         dispatchTab.ContextFinish((RsContext)con);
1540         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1541                                      (RsAllocation)ain, (RsAllocation)aout,
1542                                      NULL, 0, NULL, 0);
1543     } else {
1544         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1545                                   (RsAllocation)ain, (RsAllocation)aout,
1546                                   NULL, 0, NULL, 0);
1547     }
1548 }
1549 static void
nScriptForEachV(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong script,jint slot,jlong ain,jlong aout,jbyteArray params,jboolean mUseInc)1550 nScriptForEachV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1551                 jlong script, jint slot, jlong ain, jlong aout, jbyteArray params, jboolean mUseInc)
1552 {
1553     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1554     jint len = _env->GetArrayLength(params);
1555     jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1556     if (mUseInc) {
1557         dispatchTab.ContextFinish((RsContext)con);
1558         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1559                                      (RsAllocation)ain, (RsAllocation)aout,
1560                                      ptr, len, NULL, 0);
1561     } else {
1562         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1563                                   (RsAllocation)ain, (RsAllocation)aout,
1564                                   ptr, len, NULL, 0);
1565     }
1566     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1567 }
1568 
1569 static void
nScriptForEachClipped(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong script,jint slot,jlong ain,jlong aout,jint xstart,jint xend,jint ystart,jint yend,jint zstart,jint zend,jboolean mUseInc)1570 nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1571                       jlong script, jint slot, jlong ain, jlong aout,
1572                       jint xstart, jint xend,
1573                       jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
1574 {
1575     LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1576     RsScriptCall sc;
1577     sc.xStart = xstart;
1578     sc.xEnd = xend;
1579     sc.yStart = ystart;
1580     sc.yEnd = yend;
1581     sc.zStart = zstart;
1582     sc.zEnd = zend;
1583     sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1584     sc.arrayStart = 0;
1585     sc.arrayEnd = 0;
1586     if (mUseInc) {
1587         dispatchTab.ContextFinish((RsContext)con);
1588         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1589                                      (RsAllocation)ain, (RsAllocation)aout,
1590                                      NULL, 0, &sc, sizeof(sc));
1591     } else {
1592         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1593                                   (RsAllocation)ain, (RsAllocation)aout,
1594                                   NULL, 0, &sc, sizeof(sc));
1595     }
1596 }
1597 
1598 static void
nScriptForEachClippedV(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong script,jint slot,jlong ain,jlong aout,jbyteArray params,jint xstart,jint xend,jint ystart,jint yend,jint zstart,jint zend,jboolean mUseInc)1599 nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con, jlong incCon,
1600                        jlong script, jint slot, jlong ain, jlong aout,
1601                        jbyteArray params, jint xstart, jint xend,
1602                        jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc)
1603 {
1604     LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1605     jint len = _env->GetArrayLength(params);
1606     jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1607     RsScriptCall sc;
1608     sc.xStart = xstart;
1609     sc.xEnd = xend;
1610     sc.yStart = ystart;
1611     sc.yEnd = yend;
1612     sc.zStart = zstart;
1613     sc.zEnd = zend;
1614     sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1615     sc.arrayStart = 0;
1616     sc.arrayEnd = 0;
1617     if (mUseInc) {
1618         dispatchTab.ContextFinish((RsContext)con);
1619         dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot,
1620                                      (RsAllocation)ain, (RsAllocation)aout,
1621                                      ptr, len, &sc, sizeof(sc));
1622     } else {
1623         dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot,
1624                                   (RsAllocation)ain, (RsAllocation)aout,
1625                                   ptr, len, &sc, sizeof(sc));
1626     }
1627     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1628 }
1629 
1630 // -----------------------------------
1631 
1632 static jlong
nScriptCCreate(JNIEnv * _env,jobject _this,jlong con,jstring resName,jstring cacheDir,jbyteArray scriptRef,jint length)1633 nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
1634                jstring resName, jstring cacheDir,
1635                jbyteArray scriptRef, jint length)
1636 {
1637     LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
1638 
1639     AutoJavaStringToUTF8 resNameUTF(_env, resName);
1640     AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1641     jlong ret = 0;
1642     jbyte* script_ptr = NULL;
1643     jint _exception = 0;
1644     jint remaining;
1645     if (!scriptRef) {
1646         _exception = 1;
1647         //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1648         goto exit;
1649     }
1650     if (length < 0) {
1651         _exception = 1;
1652         //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1653         goto exit;
1654     }
1655     remaining = _env->GetArrayLength(scriptRef);
1656     if (remaining < length) {
1657         _exception = 1;
1658         //jniThrowException(_env, "java/lang/IllegalArgumentException",
1659         //        "length > script.length - offset");
1660         goto exit;
1661     }
1662     script_ptr = (jbyte *)
1663         _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1664 
1665     //rsScriptCSetText(con, (const char *)script_ptr, length);
1666 
1667     ret = (jlong)(uintptr_t)dispatchTab.ScriptCCreate((RsContext)con,
1668                                                       resNameUTF.c_str(), resNameUTF.length(),
1669                                                       cacheDirUTF.c_str(), cacheDirUTF.length(),
1670                                                       (const char *)script_ptr, length);
1671 
1672 exit:
1673     if (script_ptr) {
1674         _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1675                 _exception ? JNI_ABORT: 0);
1676     }
1677 
1678     return (jlong)(uintptr_t)ret;
1679 }
1680 
1681 static jlong
nScriptIntrinsicCreate(JNIEnv * _env,jobject _this,jlong con,jint id,jlong eid,jboolean mUseInc)1682 nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid, jboolean mUseInc)
1683 {
1684     LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
1685     if (mUseInc) {
1686         return (jlong)(uintptr_t)dispatchTabInc.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1687     } else {
1688         return (jlong)(uintptr_t)dispatchTab.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1689     }
1690 }
1691 
1692 static jlong
nScriptKernelIDCreate(JNIEnv * _env,jobject _this,jlong con,jlong sid,jint slot,jint sig,jboolean mUseInc)1693 nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig, jboolean mUseInc)
1694 {
1695     LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
1696             (void *)sid, slot, sig);
1697     if (mUseInc) {
1698         return (jlong)(uintptr_t)dispatchTabInc.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
1699                                                                      slot, sig);
1700     } else {
1701         return (jlong)(uintptr_t)dispatchTab.ScriptKernelIDCreate((RsContext)con, (RsScript)sid,
1702                                                                   slot, sig);
1703     }
1704 }
1705 
1706 static jlong
nScriptInvokeIDCreate(JNIEnv * _env,jobject _this,jlong con,jlong sid,jint slot)1707 nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1708 {
1709     LOG_API("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con,
1710             (void *)sid, slot);
1711     return (jlong)dispatchTab.ScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
1712 }
1713 
1714 static jlong
nScriptFieldIDCreate(JNIEnv * _env,jobject _this,jlong con,jlong sid,jint slot,jboolean mUseInc)1715 nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jboolean mUseInc)
1716 {
1717     LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
1718     if (mUseInc) {
1719         return (jlong)(uintptr_t)dispatchTabInc.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1720     } else {
1721         return (jlong)(uintptr_t)dispatchTab.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1722     }
1723 }
1724 
1725 static jlong
nScriptGroupCreate(JNIEnv * _env,jobject _this,jlong con,jlongArray _kernels,jlongArray _src,jlongArray _dstk,jlongArray _dstf,jlongArray _types)1726 nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
1727     jlongArray _dstk, jlongArray _dstf, jlongArray _types)
1728 {
1729     LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
1730 
1731     jint kernelsLen = _env->GetArrayLength(_kernels);
1732     jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
1733     RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
1734     for(int i = 0; i < kernelsLen; ++i) {
1735         kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
1736     }
1737 
1738     jint srcLen = _env->GetArrayLength(_src);
1739     jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
1740     RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
1741     for(int i = 0; i < srcLen; ++i) {
1742         srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
1743     }
1744 
1745     jint dstkLen = _env->GetArrayLength(_dstk);
1746     jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
1747     RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
1748     for(int i = 0; i < dstkLen; ++i) {
1749         dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
1750     }
1751 
1752     jint dstfLen = _env->GetArrayLength(_dstf);
1753     jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
1754     RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
1755     for(int i = 0; i < dstfLen; ++i) {
1756         dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
1757     }
1758 
1759     jint typesLen = _env->GetArrayLength(_types);
1760     jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
1761     RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
1762     for(int i = 0; i < typesLen; ++i) {
1763         typesPtr[i] = (RsType)jTypesPtr[i];
1764     }
1765 
1766     jlong id = (jlong)(uintptr_t) dispatchTab.ScriptGroupCreate((RsContext)con,
1767                                (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
1768                                (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
1769                                (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
1770                                (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
1771                                (RsType *)typesPtr, typesLen * sizeof(RsType));
1772 
1773     free(kernelsPtr);
1774     free(srcPtr);
1775     free(dstkPtr);
1776     free(dstfPtr);
1777     free(typesPtr);
1778     _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
1779     _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
1780     _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
1781     _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
1782     _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
1783     return id;
1784 }
1785 
1786 static void
nScriptGroupSetInput(JNIEnv * _env,jobject _this,jlong con,jlong gid,jlong kid,jlong alloc)1787 nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1788 {
1789     LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1790             (void *)gid, (void *)kid, (void *)alloc);
1791     dispatchTab.ScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
1792                                     (RsAllocation)alloc);
1793 }
1794 
1795 static void
nScriptGroupSetOutput(JNIEnv * _env,jobject _this,jlong con,jlong gid,jlong kid,jlong alloc)1796 nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1797 {
1798     LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1799             (void *)gid, (void *)kid, (void *)alloc);
1800     dispatchTab.ScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid,
1801                                      (RsAllocation)alloc);
1802 }
1803 
1804 static void
nScriptGroupExecute(JNIEnv * _env,jobject _this,jlong con,jlong gid)1805 nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
1806 {
1807     LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
1808     dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
1809 }
1810 
1811 // ---------------------------------------------------------------------------
1812 
1813 static jlong
nSamplerCreate(JNIEnv * _env,jobject _this,jlong con,jint magFilter,jint minFilter,jint wrapS,jint wrapT,jint wrapR,jfloat aniso)1814 nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
1815                jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1816 {
1817     LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
1818     return (jlong)(uintptr_t)dispatchTab.SamplerCreate((RsContext)con,
1819                                                        (RsSamplerValue)magFilter,
1820                                                        (RsSamplerValue)minFilter,
1821                                                        (RsSamplerValue)wrapS,
1822                                                        (RsSamplerValue)wrapT,
1823                                                        (RsSamplerValue)wrapR,
1824                                                        aniso);
1825 }
1826 
1827 static jint
nSystemGetPointerSize(JNIEnv * _env,jobject _this)1828 nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
1829     return (jint)sizeof(void*);
1830 }
1831 
1832 // ---------------------------------------------------------------------------
1833 // For Incremental Intrinsic Support
nIncLoadSO(JNIEnv * _env,jobject _this,jint deviceApi)1834 static jboolean nIncLoadSO(JNIEnv *_env, jobject _this, jint deviceApi) {
1835     void* handle = NULL;
1836     handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
1837     if (handle == NULL) {
1838         LOG_API("couldn't dlopen %s, %s", filename, dlerror());
1839         return false;
1840     }
1841 
1842     if (loadSymbols(handle, dispatchTabInc, deviceApi) == false) {
1843         LOG_API("%s init failed!", filename);
1844         return false;
1845     }
1846     LOG_API("Successfully loaded %s", filename);
1847     return true;
1848 }
1849 
1850 // -----------------------------------
1851 // To create/destroy a dummy context
1852 static void
nIncObjDestroy(JNIEnv * _env,jobject _this,jlong con,jlong obj)1853 nIncObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
1854 {
1855     LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
1856     dispatchTabInc.ObjDestroy((RsContext)con, (void *)obj);
1857 }
1858 
1859 
1860 static jlong
nIncDeviceCreate(JNIEnv * _env,jobject _this)1861 nIncDeviceCreate(JNIEnv *_env, jobject _this)
1862 {
1863     LOG_API("nDeviceCreate");
1864     return (jlong)(uintptr_t)dispatchTabInc.DeviceCreate();
1865 }
1866 
1867 static void
nIncDeviceDestroy(JNIEnv * _env,jobject _this,jlong dev)1868 nIncDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
1869 {
1870     LOG_API("nDeviceDestroy");
1871     return dispatchTabInc.DeviceDestroy((RsDevice)dev);
1872 }
1873 
1874 static jlong
nIncContextCreate(JNIEnv * _env,jobject _this,jlong dev,jint ver,jint sdkVer,jint ct)1875 nIncContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
1876 {
1877     LOG_API("nContextCreate");
1878     //The compat context for incremental support will be synchronous.
1879     return (jlong)(uintptr_t)dispatchTabInc.ContextCreate((RsDevice)dev, ver, sdkVer,
1880                                                           (RsContextType)ct,
1881                                                           RS_CONTEXT_SYNCHRONOUS);
1882 }
1883 
1884 static void
nIncContextFinish(JNIEnv * _env,jobject _this,jlong con)1885 nIncContextFinish(JNIEnv *_env, jobject _this, jlong con)
1886 {
1887     LOG_API("nContextFinish, con(%p)", (RsContext)con);
1888     dispatchTabInc.ContextFinish((RsContext)con);
1889 }
1890 
1891 static void
nIncContextDestroy(JNIEnv * _env,jobject _this,jlong con)1892 nIncContextDestroy(JNIEnv *_env, jobject _this, jlong con)
1893 {
1894     LOG_API("nContextDestroy, con(%p)", (RsContext)con);
1895     dispatchTabInc.ContextDestroy((RsContext)con);
1896 }
1897 
1898 // -----------------------------------
1899 // Create dummy Element
1900 static jlong
nIncElementCreate(JNIEnv * _env,jobject _this,jlong con,jlong type,jint kind,jboolean norm,jint size)1901 nIncElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
1902 {
1903     LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con,
1904             type, kind, norm, size);
1905     return (jlong)(uintptr_t)dispatchTabInc.ElementCreate((RsContext)con, (RsDataType)type,
1906                                                           (RsDataKind)kind, norm, size);
1907 }
1908 // -----------------------------------
1909 // Create dummy Type
1910 static jlong
nIncTypeCreate(JNIEnv * _env,jobject _this,jlong con,jlong eid,jint dimx,jint dimy,jint dimz,jboolean mips,jboolean faces,jint yuv)1911 nIncTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
1912             jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
1913 {
1914     LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
1915             incCon, eid, dimx, dimy, dimz, mips, faces, yuv);
1916 
1917     return (jlong)(uintptr_t)dispatchTabInc.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy,
1918                                                        dimz, mips, faces, yuv);
1919 }
1920 
1921 // -----------------------------------
1922 // Create Allocation from pointer
1923 static jlong
nIncAllocationCreateTyped(JNIEnv * _env,jobject _this,jlong con,jlong incCon,jlong alloc,jlong type)1924 nIncAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong alloc, jlong type)
1925 {
1926     LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
1927             incCon, (RsElement)type, mips, usage, (void *)pointer);
1928     size_t strideIn;
1929     void* pIn = NULL;
1930     RsAllocation ainI = NULL;
1931     if (alloc != 0) {
1932         pIn = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
1933                                                RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
1934                                                &strideIn, sizeof(size_t));
1935         ainI = dispatchTabInc.AllocationCreateTyped((RsContext)incCon, (RsType)type,
1936                                                     RS_ALLOCATION_MIPMAP_NONE,
1937                                                     RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED,
1938                                                     (uintptr_t)pIn);
1939     }
1940     return (jlong)(uintptr_t) ainI;
1941 }
1942 
1943 // ---------------------------------------------------------------------------
1944 
1945 
1946 static const char *classPathName = "android/support/v8/renderscript/RenderScript";
1947 
1948 static JNINativeMethod methods[] = {
1949 {"nLoadSO",                        "(ZI)Z",                                   (bool*)nLoadSO },
1950 {"nLoadIOSO",                      "()Z",                                     (bool*)nLoadIOSO },
1951 {"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
1952 {"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
1953 {"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
1954 {"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
1955 {"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1956 {"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
1957 {"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
1958 {"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
1959 
1960 
1961 // All methods below are thread protected in java.
1962 {"rsnContextCreate",                 "(JIIILjava/lang/String;)J",             (void*)nContextCreate },
1963 {"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
1964 {"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
1965 {"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
1966 {"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
1967 {"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
1968 {"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
1969 {"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
1970 {"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
1971 {"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
1972 {"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
1973 
1974 {"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
1975 {"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
1976 {"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
1977 
1978 {"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
1979 
1980 {"rsnAllocationCreateTyped",         "(JJIIJ)J",                              (void*)nAllocationCreateTyped },
1981 {"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
1982 {"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
1983 {"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
1984 
1985 {"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1986 {"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1987 
1988 {"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
1989 {"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
1990 {"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
1991 {"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
1992 {"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
1993 //{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
1994 {"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
1995 {"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
1996 {"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
1997 {"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
1998 {"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
1999 {"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
2000 //{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
2001 {"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
2002 //{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",  (void*)nAllocationRead3D },
2003 {"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
2004 {"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
2005 {"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
2006 
2007 {"rsnScriptBindAllocation",          "(JJJIZ)V",                              (void*)nScriptBindAllocation },
2008 {"rsnScriptSetTimeZone",             "(JJ[BZ)V",                              (void*)nScriptSetTimeZone },
2009 {"rsnScriptInvoke",                  "(JJIZ)V",                               (void*)nScriptInvoke },
2010 {"rsnScriptInvokeV",                 "(JJI[BZ)V",                             (void*)nScriptInvokeV },
2011 {"rsnScriptForEach",                 "(JJJIJJZ)V",                            (void*)nScriptForEach },
2012 {"rsnScriptForEach",                 "(JJJIJJ[BZ)V",                          (void*)nScriptForEachV },
2013 {"rsnScriptForEachClipped",          "(JJJIJJIIIIIIZ)V",                      (void*)nScriptForEachClipped },
2014 {"rsnScriptForEachClipped",          "(JJJIJJ[BIIIIIIZ)V",                    (void*)nScriptForEachClippedV },
2015 {"rsnScriptSetVarI",                 "(JJIIZ)V",                              (void*)nScriptSetVarI },
2016 {"rsnScriptSetVarJ",                 "(JJIJZ)V",                              (void*)nScriptSetVarJ },
2017 {"rsnScriptSetVarF",                 "(JJIFZ)V",                              (void*)nScriptSetVarF },
2018 {"rsnScriptSetVarD",                 "(JJIDZ)V",                              (void*)nScriptSetVarD },
2019 {"rsnScriptSetVarV",                 "(JJI[BZ)V",                             (void*)nScriptSetVarV },
2020 {"rsnScriptSetVarVE",                "(JJI[BJ[IZ)V",                          (void*)nScriptSetVarVE },
2021 {"rsnScriptSetVarObj",               "(JJIJZ)V",                              (void*)nScriptSetVarObj },
2022 
2023 {"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
2024 {"rsnScriptIntrinsicCreate",         "(JIJZ)J",                               (void*)nScriptIntrinsicCreate },
2025 {"rsnScriptKernelIDCreate",          "(JJIIZ)J",                              (void*)nScriptKernelIDCreate },
2026 {"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
2027 {"rsnScriptFieldIDCreate",           "(JJIZ)J",                               (void*)nScriptFieldIDCreate },
2028 {"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
2029 {"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
2030 {"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
2031 {"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
2032 {"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
2033 {"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
2034 
2035 {"rsnScriptIntrinsicBLAS_Single",    "(JJJIIIIIIIIIFJJFJIIIIZ)V",             (void*)nScriptIntrinsicBLAS_Single },
2036 {"rsnScriptIntrinsicBLAS_Double",    "(JJJIIIIIIIIIDJJDJIIIIZ)V",             (void*)nScriptIntrinsicBLAS_Double },
2037 {"rsnScriptIntrinsicBLAS_Complex",   "(JJJIIIIIIIIIFFJJFFJIIIIZ)V",           (void*)nScriptIntrinsicBLAS_Complex },
2038 {"rsnScriptIntrinsicBLAS_Z",         "(JJJIIIIIIIIIDDJJDDJIIIIZ)V",           (void*)nScriptIntrinsicBLAS_Z },
2039 
2040 {"rsnScriptIntrinsicBLAS_BNNM",      "(JJJIIIJIJIJIIZ)V",                     (void*)nScriptIntrinsicBLAS_BNNM },
2041 
2042 {"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
2043 
2044 {"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
2045 
2046 // Entry points for Inc libRSSupport
2047 {"nIncLoadSO",                       "(I)Z",                                  (bool*)nIncLoadSO },
2048 {"nIncDeviceCreate",                 "()J",                                   (void*)nIncDeviceCreate },
2049 {"nIncDeviceDestroy",                "(J)V",                                  (void*)nIncDeviceDestroy },
2050 {"rsnIncContextCreate",              "(JIII)J",                               (void*)nIncContextCreate },
2051 {"rsnIncContextFinish",              "(J)V",                                  (void*)nIncContextFinish },
2052 {"rsnIncContextDestroy",             "(J)V",                                  (void*)nIncContextDestroy },
2053 {"rsnIncObjDestroy",                 "(JJ)V",                                 (void*)nIncObjDestroy },
2054 {"rsnIncElementCreate",              "(JJIZI)J",                              (void*)nIncElementCreate },
2055 {"rsnIncTypeCreate",                 "(JJIIIZZI)J",                           (void*)nIncTypeCreate },
2056 {"rsnIncAllocationCreateTyped",      "(JJJJ)J",                               (void*)nIncAllocationCreateTyped },
2057 };
2058 
2059 // ---------------------------------------------------------------------------
2060 
JNI_OnLoad(JavaVM * vm,void * reserved)2061 jint JNI_OnLoad(JavaVM* vm, void* reserved)
2062 {
2063     JNIEnv* env = NULL;
2064     jclass clazz = NULL;
2065     jint result = -1;
2066 
2067     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
2068         //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
2069         //            "ERROR: GetEnv failed\n");
2070         goto bail;
2071     }
2072     if (env == NULL) {
2073         //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
2074         goto bail;
2075     }
2076 
2077     clazz = env->FindClass(classPathName);
2078     if (clazz == NULL) {
2079         goto bail;
2080     }
2081 
2082     if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) {
2083         //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
2084         //            "ERROR: MediaPlayer native registration failed\n");
2085         goto bail;
2086     }
2087 
2088     /* success -- return valid version number */
2089     result = JNI_VERSION_1_4;
2090 
2091 bail:
2092     return result;
2093 }
2094