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