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 "RenderScript_jni"
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <fcntl.h>
22#include <unistd.h>
23#include <math.h>
24#include <utils/misc.h>
25#include <inttypes.h>
26
27#include <androidfw/Asset.h>
28#include <androidfw/AssetManager.h>
29#include <androidfw/ResourceTypes.h>
30
31#include "jni.h"
32#include "JNIHelp.h"
33#include "android_runtime/AndroidRuntime.h"
34#include "android_runtime/android_view_Surface.h"
35#include "android_runtime/android_util_AssetManager.h"
36#include "android/graphics/GraphicsJNI.h"
37#include "android/native_window.h"
38#include "android/native_window_jni.h"
39
40#include <rsEnv.h>
41#include <rsApiStubs.h>
42#include <gui/Surface.h>
43#include <gui/GLConsumer.h>
44#include <android_runtime/android_graphics_SurfaceTexture.h>
45
46//#define LOG_API ALOGE
47static constexpr bool kLogApi = false;
48
49using namespace android;
50
51#define PER_ARRAY_TYPE(flag, fnc, readonly, ...) {                                      \
52    jint len = 0;                                                                       \
53    void *ptr = nullptr;                                                                \
54    void *srcPtr = nullptr;                                                             \
55    size_t typeBytes = 0;                                                               \
56    jint relFlag = 0;                                                                   \
57    if (readonly) {                                                                     \
58        /* The on-release mode should only be JNI_ABORT for read-only accesses. */      \
59        /* readonly = true, also indicates we are copying to the allocation   . */      \
60        relFlag = JNI_ABORT;                                                            \
61    }                                                                                   \
62    switch(dataType) {                                                                  \
63    case RS_TYPE_FLOAT_32:                                                              \
64        len = _env->GetArrayLength((jfloatArray)data);                                  \
65        ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
66        if (ptr == nullptr) {                                                           \
67            ALOGE("Failed to get Java array elements.");                                \
68            return;                                                                     \
69        }                                                                               \
70        typeBytes = 4;                                                                  \
71        if (usePadding) {                                                               \
72            srcPtr = ptr;                                                               \
73            len = len / 3 * 4;                                                          \
74            if (count == 0) {                                                           \
75                count = len / 4;                                                        \
76            }                                                                           \
77            ptr = malloc (len * typeBytes);                                             \
78            if (readonly) {                                                             \
79                copyWithPadding(ptr, srcPtr, mSize, count);                             \
80                fnc(__VA_ARGS__);                                                       \
81            } else {                                                                    \
82                fnc(__VA_ARGS__);                                                       \
83                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
84            }                                                                           \
85            free(ptr);                                                                  \
86            ptr = srcPtr;                                                               \
87        } else {                                                                        \
88            fnc(__VA_ARGS__);                                                           \
89        }                                                                               \
90        _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag);     \
91        return;                                                                         \
92    case RS_TYPE_FLOAT_64:                                                              \
93        len = _env->GetArrayLength((jdoubleArray)data);                                 \
94        ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
95        if (ptr == nullptr) {                                                           \
96            ALOGE("Failed to get Java array elements.");                                \
97            return;                                                                     \
98        }                                                                               \
99        typeBytes = 8;                                                                  \
100        if (usePadding) {                                                               \
101            srcPtr = ptr;                                                               \
102            len = len / 3 * 4;                                                          \
103            if (count == 0) {                                                           \
104                count = len / 4;                                                        \
105            }                                                                           \
106            ptr = malloc (len * typeBytes);                                             \
107            if (readonly) {                                                             \
108                copyWithPadding(ptr, srcPtr, mSize, count);                             \
109                fnc(__VA_ARGS__);                                                       \
110            } else {                                                                    \
111                fnc(__VA_ARGS__);                                                       \
112                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
113            }                                                                           \
114            free(ptr);                                                                  \
115            ptr = srcPtr;                                                               \
116        } else {                                                                        \
117            fnc(__VA_ARGS__);                                                           \
118        }                                                                               \
119        _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag);  \
120        return;                                                                         \
121    case RS_TYPE_SIGNED_8:                                                              \
122    case RS_TYPE_UNSIGNED_8:                                                            \
123        len = _env->GetArrayLength((jbyteArray)data);                                   \
124        ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
125        if (ptr == nullptr) {                                                           \
126            ALOGE("Failed to get Java array elements.");                                \
127            return;                                                                     \
128        }                                                                               \
129        typeBytes = 1;                                                                  \
130        if (usePadding) {                                                               \
131            srcPtr = ptr;                                                               \
132            len = len / 3 * 4;                                                          \
133            if (count == 0) {                                                           \
134                count = len / 4;                                                        \
135            }                                                                           \
136            ptr = malloc (len * typeBytes);                                             \
137            if (readonly) {                                                             \
138                copyWithPadding(ptr, srcPtr, mSize, count);                             \
139                fnc(__VA_ARGS__);                                                       \
140            } else {                                                                    \
141                fnc(__VA_ARGS__);                                                       \
142                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
143            }                                                                           \
144            free(ptr);                                                                  \
145            ptr = srcPtr;                                                               \
146        } else {                                                                        \
147            fnc(__VA_ARGS__);                                                           \
148        }                                                                               \
149        _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag);         \
150        return;                                                                         \
151    case RS_TYPE_SIGNED_16:                                                             \
152    case RS_TYPE_UNSIGNED_16:                                                           \
153    case RS_TYPE_FLOAT_16:                                                              \
154        len = _env->GetArrayLength((jshortArray)data);                                  \
155        ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
156        if (ptr == nullptr) {                                                           \
157            ALOGE("Failed to get Java array elements.");                                \
158            return;                                                                     \
159        }                                                                               \
160        typeBytes = 2;                                                                  \
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->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag);     \
181        return;                                                                         \
182    case RS_TYPE_SIGNED_32:                                                             \
183    case RS_TYPE_UNSIGNED_32:                                                           \
184        len = _env->GetArrayLength((jintArray)data);                                    \
185        ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
186        if (ptr == nullptr) {                                                           \
187            ALOGE("Failed to get Java array elements.");                                \
188            return;                                                                     \
189        }                                                                               \
190        typeBytes = 4;                                                                  \
191        if (usePadding) {                                                               \
192            srcPtr = ptr;                                                               \
193            len = len / 3 * 4;                                                          \
194            if (count == 0) {                                                           \
195                count = len / 4;                                                        \
196            }                                                                           \
197            ptr = malloc (len * typeBytes);                                             \
198            if (readonly) {                                                             \
199                copyWithPadding(ptr, srcPtr, mSize, count);                             \
200                fnc(__VA_ARGS__);                                                       \
201            } else {                                                                    \
202                fnc(__VA_ARGS__);                                                       \
203                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
204            }                                                                           \
205            free(ptr);                                                                  \
206            ptr = srcPtr;                                                               \
207        } else {                                                                        \
208            fnc(__VA_ARGS__);                                                           \
209        }                                                                               \
210        _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag);           \
211        return;                                                                         \
212    case RS_TYPE_SIGNED_64:                                                             \
213    case RS_TYPE_UNSIGNED_64:                                                           \
214        len = _env->GetArrayLength((jlongArray)data);                                   \
215        ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
216        if (ptr == nullptr) {                                                           \
217            ALOGE("Failed to get Java array elements.");                                \
218            return;                                                                     \
219        }                                                                               \
220        typeBytes = 8;                                                                  \
221        if (usePadding) {                                                               \
222            srcPtr = ptr;                                                               \
223            len = len / 3 * 4;                                                          \
224            if (count == 0) {                                                           \
225                count = len / 4;                                                        \
226            }                                                                           \
227            ptr = malloc (len * typeBytes);                                             \
228            if (readonly) {                                                             \
229                copyWithPadding(ptr, srcPtr, mSize, count);                             \
230                fnc(__VA_ARGS__);                                                       \
231            } else {                                                                    \
232                fnc(__VA_ARGS__);                                                       \
233                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
234            }                                                                           \
235            free(ptr);                                                                  \
236            ptr = srcPtr;                                                               \
237        } else {                                                                        \
238            fnc(__VA_ARGS__);                                                           \
239        }                                                                               \
240        _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag);        \
241        return;                                                                         \
242    default:                                                                            \
243        break;                                                                          \
244    }                                                                                   \
245    UNUSED(len, ptr, srcPtr, typeBytes, relFlag);                                       \
246}
247
248
249class AutoJavaStringToUTF8 {
250public:
251    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
252        fCStr = env->GetStringUTFChars(str, nullptr);
253        fLength = env->GetStringUTFLength(str);
254    }
255    ~AutoJavaStringToUTF8() {
256        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
257    }
258    const char* c_str() const { return fCStr; }
259    jsize length() const { return fLength; }
260
261private:
262    JNIEnv*     fEnv;
263    jstring     fJStr;
264    const char* fCStr;
265    jsize       fLength;
266};
267
268class AutoJavaStringArrayToUTF8 {
269public:
270    AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
271    : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
272        mCStrings = nullptr;
273        mSizeArray = nullptr;
274        if (stringsLength > 0) {
275            mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
276            mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
277            for (jsize ct = 0; ct < stringsLength; ct ++) {
278                jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
279                mCStrings[ct] = mEnv->GetStringUTFChars(s, nullptr);
280                mSizeArray[ct] = mEnv->GetStringUTFLength(s);
281            }
282        }
283    }
284    ~AutoJavaStringArrayToUTF8() {
285        for (jsize ct=0; ct < mStringsLength; ct++) {
286            jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
287            mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
288        }
289        free(mCStrings);
290        free(mSizeArray);
291    }
292    const char **c_str() const { return mCStrings; }
293    size_t *c_str_len() const { return mSizeArray; }
294    jsize length() const { return mStringsLength; }
295
296private:
297    JNIEnv      *mEnv;
298    jobjectArray mStrings;
299    const char **mCStrings;
300    size_t      *mSizeArray;
301    jsize        mStringsLength;
302};
303
304// ---------------------------------------------------------------------------
305
306static jfieldID gContextId = 0;
307
308static void _nInit(JNIEnv *_env, jclass _this)
309{
310    gContextId             = _env->GetFieldID(_this, "mContext", "J");
311}
312
313// ---------------------------------------------------------------------------
314
315static void copyWithPadding(void* ptr, void* srcPtr, int mSize, int count) {
316    int sizeBytesPad = mSize * 4;
317    int sizeBytes = mSize * 3;
318    uint8_t *dst = static_cast<uint8_t *>(ptr);
319    uint8_t *src = static_cast<uint8_t *>(srcPtr);
320    for (int i = 0; i < count; i++) {
321        memcpy(dst, src, sizeBytes);
322        dst += sizeBytesPad;
323        src += sizeBytes;
324    }
325}
326
327static void copyWithUnPadding(void* ptr, void* srcPtr, int mSize, int count) {
328    int sizeBytesPad = mSize * 4;
329    int sizeBytes = mSize * 3;
330    uint8_t *dst = static_cast<uint8_t *>(ptr);
331    uint8_t *src = static_cast<uint8_t *>(srcPtr);
332    for (int i = 0; i < count; i++) {
333        memcpy(dst, src, sizeBytes);
334        dst += sizeBytes;
335        src += sizeBytesPad;
336    }
337}
338
339
340// ---------------------------------------------------------------------------
341static void
342nContextFinish(JNIEnv *_env, jobject _this, jlong con)
343{
344    if (kLogApi) {
345        ALOGD("nContextFinish, con(%p)", (RsContext)con);
346    }
347    rsContextFinish((RsContext)con);
348}
349
350static jlong
351nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
352               jlong returnValue, jlongArray fieldIDArray,
353               jlongArray valueArray, jintArray sizeArray,
354               jlongArray depClosureArray, jlongArray depFieldIDArray) {
355  jlong ret = 0;
356
357  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
358  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
359  if (jFieldIDs == nullptr) {
360      ALOGE("Failed to get Java array elements: fieldIDs.");
361      return ret;
362  }
363
364  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
365  jsize values_length = _env->GetArrayLength(valueArray);
366  if (jValues == nullptr) {
367      ALOGE("Failed to get Java array elements: values.");
368      return ret;
369  }
370
371  jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
372  jsize sizes_length = _env->GetArrayLength(sizeArray);
373  if (jSizes == nullptr) {
374      ALOGE("Failed to get Java array elements: sizes.");
375      return ret;
376  }
377
378  jlong* jDepClosures =
379      _env->GetLongArrayElements(depClosureArray, nullptr);
380  jsize depClosures_length = _env->GetArrayLength(depClosureArray);
381  if (jDepClosures == nullptr) {
382      ALOGE("Failed to get Java array elements: depClosures.");
383      return ret;
384  }
385
386  jlong* jDepFieldIDs =
387      _env->GetLongArrayElements(depFieldIDArray, nullptr);
388  jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
389  if (jDepFieldIDs == nullptr) {
390      ALOGE("Failed to get Java array elements: depFieldIDs.");
391      return ret;
392  }
393
394  size_t numValues, numDependencies;
395  RsScriptFieldID* fieldIDs;
396  RsClosure* depClosures;
397  RsScriptFieldID* depFieldIDs;
398
399  if (fieldIDs_length != values_length || values_length != sizes_length) {
400      ALOGE("Unmatched field IDs, values, and sizes in closure creation.");
401      goto exit;
402  }
403
404  numValues = (size_t)fieldIDs_length;
405
406  if (depClosures_length != depFieldIDs_length) {
407      ALOGE("Unmatched closures and field IDs for dependencies in closure creation.");
408      goto exit;
409  }
410
411  numDependencies = (size_t)depClosures_length;
412
413  if (numDependencies > numValues) {
414      ALOGE("Unexpected number of dependencies in closure creation");
415      goto exit;
416  }
417
418  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
419      ALOGE("Too many arguments or globals in closure creation");
420      goto exit;
421  }
422
423  if (numValues > 0) {
424      fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
425      if (fieldIDs == nullptr) {
426          goto exit;
427      }
428  } else {
429      // numValues == 0
430      // alloca(0) implementation is platform-dependent.
431      fieldIDs = nullptr;
432  }
433
434  for (size_t i = 0; i < numValues; i++) {
435    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
436  }
437
438  if (numDependencies > 0) {
439      depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies);
440      if (depClosures == nullptr) {
441          goto exit;
442      }
443
444      for (size_t i = 0; i < numDependencies; i++) {
445          depClosures[i] = (RsClosure)jDepClosures[i];
446      }
447
448      depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies);
449      if (depFieldIDs == nullptr) {
450          goto exit;
451      }
452
453      for (size_t i = 0; i < numDependencies; i++) {
454          depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
455      }
456  } else {
457      // alloca(0) implementation is platform-dependent.
458      depClosures = nullptr;
459      depFieldIDs = nullptr;
460  }
461
462  ret = (jlong)(uintptr_t)rsClosureCreate(
463      (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
464      fieldIDs, numValues, jValues, numValues,
465      (int*)jSizes, numValues,
466      depClosures, numDependencies,
467      depFieldIDs, numDependencies);
468
469exit:
470
471  _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT);
472  _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT);
473  _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
474  _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
475  _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
476
477  return ret;
478}
479
480static jlong
481nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
482                     jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
483                     jintArray sizeArray) {
484  jlong ret = 0;
485
486  jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
487  jsize jParamLength = _env->GetArrayLength(paramArray);
488  if (jParams == nullptr) {
489      ALOGE("Failed to get Java array elements: params.");
490      return ret;
491  }
492
493  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
494  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
495  if (jFieldIDs == nullptr) {
496      ALOGE("Failed to get Java array elements: fieldIDs.");
497      return ret;
498  }
499
500  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
501  jsize values_length = _env->GetArrayLength(valueArray);
502  if (jValues == nullptr) {
503      ALOGE("Failed to get Java array elements: values.");
504      return ret;
505  }
506
507  jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
508  jsize sizes_length = _env->GetArrayLength(sizeArray);
509  if (jSizes == nullptr) {
510      ALOGE("Failed to get Java array elements: sizes.");
511      return ret;
512  }
513
514  size_t numValues;
515  RsScriptFieldID* fieldIDs;
516
517  if (fieldIDs_length != values_length || values_length != sizes_length) {
518      ALOGE("Unmatched field IDs, values, and sizes in closure creation.");
519      goto exit;
520  }
521
522  numValues = (size_t) fieldIDs_length;
523
524  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
525      ALOGE("Too many arguments or globals in closure creation");
526      goto exit;
527  }
528
529  fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
530  if (fieldIDs == nullptr) {
531      goto exit;
532  }
533
534  for (size_t i = 0; i< numValues; i++) {
535    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
536  }
537
538  ret = (jlong)(uintptr_t)rsInvokeClosureCreate(
539      (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
540      fieldIDs, numValues, jValues, numValues,
541      (int*)jSizes, numValues);
542
543exit:
544
545  _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
546  _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
547  _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
548  _env->ReleaseByteArrayElements(paramArray,      jParams,      JNI_ABORT);
549
550  return ret;
551}
552
553static void
554nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
555               jint index, jlong value, jint size) {
556  // Size is signed with -1 indicating the value is an Allocation
557  rsClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
558                  (uintptr_t)value, size);
559}
560
561static void
562nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
563                  jlong fieldID, jlong value, jint size) {
564  // Size is signed with -1 indicating the value is an Allocation
565  rsClosureSetGlobal((RsContext)con, (RsClosure)closureID,
566                     (RsScriptFieldID)fieldID, (int64_t)value, size);
567}
568
569static long
570nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name,
571                    jstring cacheDir, jlongArray closureArray) {
572  jlong ret = 0;
573
574  AutoJavaStringToUTF8 nameUTF(_env, name);
575  AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
576
577  jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
578  jsize numClosures = _env->GetArrayLength(closureArray);
579  if (jClosures == nullptr) {
580      ALOGE("Failed to get Java array elements: closures.");
581      return ret;
582  }
583
584  RsClosure* closures;
585
586  if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
587    ALOGE("Too many closures in script group");
588    goto exit;
589  }
590
591  closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
592  if (closures == nullptr) {
593      goto exit;
594  }
595
596  for (int i = 0; i < numClosures; i++) {
597    closures[i] = (RsClosure)jClosures[i];
598  }
599
600  ret = (jlong)(uintptr_t)rsScriptGroup2Create(
601      (RsContext)con, nameUTF.c_str(), nameUTF.length(),
602      cacheDirUTF.c_str(), cacheDirUTF.length(),
603      closures, numClosures);
604
605exit:
606
607  _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT);
608
609  return ret;
610}
611
612static void
613nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) {
614  rsScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID);
615}
616
617static void
618nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
619                            jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
620                            jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY,
621                            jint KL, jint KU) {
622    RsBlasCall call;
623    memset(&call, 0, sizeof(call));
624    call.func = (RsBlasFunction)func;
625    call.transA = (RsBlasTranspose)TransA;
626    call.transB = (RsBlasTranspose)TransB;
627    call.side = (RsBlasSide)Side;
628    call.uplo = (RsBlasUplo)Uplo;
629    call.diag = (RsBlasDiag)Diag;
630    call.M = M;
631    call.N = N;
632    call.K = K;
633    call.alpha.f = alpha;
634    call.beta.f = beta;
635    call.incX = incX;
636    call.incY = incY;
637    call.KL = KL;
638    call.KU = KU;
639
640    RsAllocation in_allocs[3];
641    in_allocs[0] = (RsAllocation)A;
642    in_allocs[1] = (RsAllocation)B;
643    in_allocs[2] = (RsAllocation)C;
644
645    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
646                         in_allocs, NELEM(in_allocs), nullptr,
647                         &call, sizeof(call), nullptr, 0);
648}
649
650static void
651nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
652                            jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
653                            jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY,
654                            jint KL, jint KU) {
655    RsBlasCall call;
656    memset(&call, 0, sizeof(call));
657    call.func = (RsBlasFunction)func;
658    call.transA = (RsBlasTranspose)TransA;
659    call.transB = (RsBlasTranspose)TransB;
660    call.side = (RsBlasSide)Side;
661    call.uplo = (RsBlasUplo)Uplo;
662    call.diag = (RsBlasDiag)Diag;
663    call.M = M;
664    call.N = N;
665    call.K = K;
666    call.alpha.d = alpha;
667    call.beta.d = beta;
668    call.incX = incX;
669    call.incY = incY;
670    call.KL = KL;
671    call.KU = KU;
672
673    RsAllocation in_allocs[3];
674    in_allocs[0] = (RsAllocation)A;
675    in_allocs[1] = (RsAllocation)B;
676    in_allocs[2] = (RsAllocation)C;
677
678    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
679                         in_allocs, NELEM(in_allocs), nullptr,
680                         &call, sizeof(call), nullptr, 0);
681}
682
683static void
684nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
685                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
686                             jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX,
687                             jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU) {
688    RsBlasCall call;
689    memset(&call, 0, sizeof(call));
690    call.func = (RsBlasFunction)func;
691    call.transA = (RsBlasTranspose)TransA;
692    call.transB = (RsBlasTranspose)TransB;
693    call.side = (RsBlasSide)Side;
694    call.uplo = (RsBlasUplo)Uplo;
695    call.diag = (RsBlasDiag)Diag;
696    call.M = M;
697    call.N = N;
698    call.K = K;
699    call.alpha.c.r = alphaX;
700    call.alpha.c.i = alphaY;
701    call.beta.c.r = betaX;
702    call.beta.c.i = betaY;
703    call.incX = incX;
704    call.incY = incY;
705    call.KL = KL;
706    call.KU = KU;
707
708    RsAllocation in_allocs[3];
709    in_allocs[0] = (RsAllocation)A;
710    in_allocs[1] = (RsAllocation)B;
711    in_allocs[2] = (RsAllocation)C;
712
713    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
714                         in_allocs, NELEM(in_allocs), nullptr,
715                         &call, sizeof(call), nullptr, 0);
716}
717
718static void
719nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
720                       jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
721                       jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX,
722                       jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU) {
723    RsBlasCall call;
724    memset(&call, 0, sizeof(call));
725    call.func = (RsBlasFunction)func;
726    call.transA = (RsBlasTranspose)TransA;
727    call.transB = (RsBlasTranspose)TransB;
728    call.side = (RsBlasSide)Side;
729    call.uplo = (RsBlasUplo)Uplo;
730    call.diag = (RsBlasDiag)Diag;
731    call.M = M;
732    call.N = N;
733    call.K = K;
734    call.alpha.z.r = alphaX;
735    call.alpha.z.i = alphaY;
736    call.beta.z.r = betaX;
737    call.beta.z.i = betaY;
738    call.incX = incX;
739    call.incY = incY;
740    call.KL = KL;
741    call.KU = KU;
742
743    RsAllocation in_allocs[3];
744    in_allocs[0] = (RsAllocation)A;
745    in_allocs[1] = (RsAllocation)B;
746    in_allocs[2] = (RsAllocation)C;
747
748    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
749                         in_allocs, NELEM(in_allocs), nullptr,
750                         &call, sizeof(call), nullptr, 0);
751}
752
753
754static void
755nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong id, jint M, jint N, jint K,
756                                             jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset,
757                                             jint c_mult_int) {
758    RsBlasCall call;
759    memset(&call, 0, sizeof(call));
760    call.func = RsBlas_bnnm;
761    call.M = M;
762    call.N = N;
763    call.K = K;
764    call.a_offset = a_offset & 0xFF;
765    call.b_offset = b_offset & 0xFF;
766    call.c_offset = c_offset;
767    call.c_mult_int = c_mult_int;
768
769    RsAllocation in_allocs[3];
770    in_allocs[0] = (RsAllocation)A;
771    in_allocs[1] = (RsAllocation)B;
772    in_allocs[2] = (RsAllocation)C;
773
774    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
775                         in_allocs, NELEM(in_allocs), nullptr,
776                         &call, sizeof(call), nullptr, 0);
777}
778
779
780static void
781nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str)
782{
783    if (kLogApi) {
784        ALOGD("nAssignName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
785    }
786    jint len = _env->GetArrayLength(str);
787    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
788    if (cptr == nullptr) {
789        ALOGE("Failed to get Java array elements");
790        return;
791    }
792
793    rsAssignName((RsContext)con, (void *)obj, (const char *)cptr, len);
794    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
795}
796
797static jstring
798nGetName(JNIEnv *_env, jobject _this, jlong con, jlong obj)
799{
800    if (kLogApi) {
801        ALOGD("nGetName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
802    }
803    const char *name = nullptr;
804    rsaGetName((RsContext)con, (void *)obj, &name);
805    if(name == nullptr || strlen(name) == 0) {
806        return nullptr;
807    }
808    return _env->NewStringUTF(name);
809}
810
811static void
812nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
813{
814    if (kLogApi) {
815        ALOGD("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
816    }
817    rsObjDestroy((RsContext)con, (void *)obj);
818}
819
820// ---------------------------------------------------------------------------
821
822static jlong
823nDeviceCreate(JNIEnv *_env, jobject _this)
824{
825    if (kLogApi) {
826        ALOGD("nDeviceCreate");
827    }
828    return (jlong)(uintptr_t)rsDeviceCreate();
829}
830
831static void
832nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
833{
834    if (kLogApi) {
835        ALOGD("nDeviceDestroy");
836    }
837    return rsDeviceDestroy((RsDevice)dev);
838}
839
840static void
841nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
842{
843    if (kLogApi) {
844        ALOGD("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
845    }
846    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
847}
848
849static jlong
850nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint flags, jint sdkVer, jint contextType)
851{
852    if (kLogApi) {
853        ALOGD("nContextCreate");
854    }
855    return (jlong)(uintptr_t)rsContextCreate((RsDevice)dev, 0, sdkVer, (RsContextType)contextType, flags);
856}
857
858static jlong
859nContextCreateGL(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
860                 jint colorMin, jint colorPref,
861                 jint alphaMin, jint alphaPref,
862                 jint depthMin, jint depthPref,
863                 jint stencilMin, jint stencilPref,
864                 jint samplesMin, jint samplesPref, jfloat samplesQ,
865                 jint dpi)
866{
867    RsSurfaceConfig sc = {};
868    sc.alphaMin = alphaMin;
869    sc.alphaPref = alphaPref;
870    sc.colorMin = colorMin;
871    sc.colorPref = colorPref;
872    sc.depthMin = depthMin;
873    sc.depthPref = depthPref;
874    sc.samplesMin = samplesMin;
875    sc.samplesPref = samplesPref;
876    sc.samplesQ = samplesQ;
877
878    if (kLogApi) {
879        ALOGD("nContextCreateGL");
880    }
881    return (jlong)(uintptr_t)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
882}
883
884static void
885nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
886{
887    if (kLogApi) {
888        ALOGD("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
889    }
890    rsContextSetPriority((RsContext)con, p);
891}
892
893static void
894nContextSetCacheDir(JNIEnv *_env, jobject _this, jlong con, jstring cacheDir)
895{
896    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
897
898    if (kLogApi) {
899        ALOGD("ContextSetCacheDir, con(%p), cacheDir(%s)", (RsContext)con, cacheDirUTF.c_str());
900    }
901    rsContextSetCacheDir((RsContext)con, cacheDirUTF.c_str(), cacheDirUTF.length());
902}
903
904
905
906static void
907nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd)
908{
909    if (kLogApi) {
910        ALOGD("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", (RsContext)con,
911              width, height, (Surface *)wnd);
912    }
913
914    ANativeWindow * window = nullptr;
915    if (wnd == nullptr) {
916
917    } else {
918        window = android_view_Surface_getNativeWindow(_env, wnd).get();
919    }
920
921    rsContextSetSurface((RsContext)con, width, height, window);
922}
923
924static void
925nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
926{
927    if (kLogApi) {
928        ALOGD("nContextDestroy, con(%p)", (RsContext)con);
929    }
930    rsContextDestroy((RsContext)con);
931}
932
933static void
934nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
935{
936    if (kLogApi) {
937        ALOGD("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
938    }
939    rsContextDump((RsContext)con, bits);
940}
941
942static void
943nContextPause(JNIEnv *_env, jobject _this, jlong con)
944{
945    if (kLogApi) {
946        ALOGD("nContextPause, con(%p)", (RsContext)con);
947    }
948    rsContextPause((RsContext)con);
949}
950
951static void
952nContextResume(JNIEnv *_env, jobject _this, jlong con)
953{
954    if (kLogApi) {
955        ALOGD("nContextResume, con(%p)", (RsContext)con);
956    }
957    rsContextResume((RsContext)con);
958}
959
960
961static jstring
962nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
963{
964    if (kLogApi) {
965        ALOGD("nContextGetErrorMessage, con(%p)", (RsContext)con);
966    }
967    char buf[1024];
968
969    size_t receiveLen;
970    uint32_t subID;
971    int id = rsContextGetMessage((RsContext)con,
972                                 buf, sizeof(buf),
973                                 &receiveLen, sizeof(receiveLen),
974                                 &subID, sizeof(subID));
975    if (!id && receiveLen) {
976        ALOGV("message receive buffer too small.  %zu", receiveLen);
977    }
978    return _env->NewStringUTF(buf);
979}
980
981static jint
982nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
983{
984    jint len = _env->GetArrayLength(data);
985    if (kLogApi) {
986        ALOGD("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
987    }
988    jint *ptr = _env->GetIntArrayElements(data, nullptr);
989    if (ptr == nullptr) {
990        ALOGE("Failed to get Java array elements");
991        return 0;
992    }
993    size_t receiveLen;
994    uint32_t subID;
995    int id = rsContextGetMessage((RsContext)con,
996                                 ptr, len * 4,
997                                 &receiveLen, sizeof(receiveLen),
998                                 &subID, sizeof(subID));
999    if (!id && receiveLen) {
1000        ALOGV("message receive buffer too small.  %zu", receiveLen);
1001    }
1002    _env->ReleaseIntArrayElements(data, ptr, 0);
1003    return (jint)id;
1004}
1005
1006static jint
1007nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
1008{
1009    if (kLogApi) {
1010        ALOGD("nContextPeekMessage, con(%p)", (RsContext)con);
1011    }
1012    jint *auxDataPtr = _env->GetIntArrayElements(auxData, nullptr);
1013    if (auxDataPtr == nullptr) {
1014        ALOGE("Failed to get Java array elements");
1015        return 0;
1016    }
1017    size_t receiveLen;
1018    uint32_t subID;
1019    int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
1020                                  &subID, sizeof(subID));
1021    auxDataPtr[0] = (jint)subID;
1022    auxDataPtr[1] = (jint)receiveLen;
1023    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
1024    return (jint)id;
1025}
1026
1027static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
1028{
1029    if (kLogApi) {
1030        ALOGD("nContextInitToClient, con(%p)", (RsContext)con);
1031    }
1032    rsContextInitToClient((RsContext)con);
1033}
1034
1035static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
1036{
1037    if (kLogApi) {
1038        ALOGD("nContextDeinitToClient, con(%p)", (RsContext)con);
1039    }
1040    rsContextDeinitToClient((RsContext)con);
1041}
1042
1043static void
1044nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
1045{
1046    jint *ptr = nullptr;
1047    jint len = 0;
1048    if (data) {
1049        len = _env->GetArrayLength(data);
1050        ptr = _env->GetIntArrayElements(data, nullptr);
1051        if (ptr == nullptr) {
1052            ALOGE("Failed to get Java array elements");
1053            return;
1054        }
1055    }
1056    if (kLogApi) {
1057        ALOGD("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
1058    }
1059    rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
1060    if (data) {
1061        _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
1062    }
1063}
1064
1065
1066
1067static jlong
1068nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm,
1069               jint size)
1070{
1071    if (kLogApi) {
1072        ALOGD("nElementCreate, con(%p), type(%" PRId64 "), kind(%i), norm(%i), size(%i)", (RsContext)con,
1073              type, kind, norm, size);
1074    }
1075    return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind,
1076                                             norm, size);
1077}
1078
1079static jlong
1080nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
1081                jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
1082{
1083    int fieldCount = _env->GetArrayLength(_ids);
1084    if (kLogApi) {
1085        ALOGD("nElementCreate2, con(%p)", (RsContext)con);
1086    }
1087
1088    jlong *jIds = _env->GetLongArrayElements(_ids, nullptr);
1089    if (jIds == nullptr) {
1090        ALOGE("Failed to get Java array elements: ids");
1091        return 0;
1092    }
1093    jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, nullptr);
1094    if (jArraySizes == nullptr) {
1095        ALOGE("Failed to get Java array elements: arraySizes");
1096        return 0;
1097    }
1098
1099    RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
1100    uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
1101
1102    for(int i = 0; i < fieldCount; i ++) {
1103        ids[i] = (RsElement)jIds[i];
1104        arraySizes[i] = (uint32_t)jArraySizes[i];
1105    }
1106
1107    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
1108
1109    const char **nameArray = names.c_str();
1110    size_t *sizeArray = names.c_str_len();
1111
1112    jlong id = (jlong)(uintptr_t)rsElementCreate2((RsContext)con,
1113                                     (const RsElement *)ids, fieldCount,
1114                                     nameArray, fieldCount * sizeof(size_t),  sizeArray,
1115                                     (const uint32_t *)arraySizes, fieldCount);
1116
1117    free(ids);
1118    free(arraySizes);
1119    _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
1120    _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
1121
1122    return (jlong)(uintptr_t)id;
1123}
1124
1125static void
1126nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData)
1127{
1128    int dataSize = _env->GetArrayLength(_elementData);
1129    if (kLogApi) {
1130        ALOGD("nElementGetNativeData, con(%p)", (RsContext)con);
1131    }
1132
1133    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
1134    assert(dataSize == 5);
1135
1136    uint32_t elementData[5];
1137    rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize);
1138
1139    for(jint i = 0; i < dataSize; i ++) {
1140        const jint data = (jint)elementData[i];
1141        _env->SetIntArrayRegion(_elementData, i, 1, &data);
1142    }
1143}
1144
1145
1146static void
1147nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
1148                       jlongArray _IDs,
1149                       jobjectArray _names,
1150                       jintArray _arraySizes)
1151{
1152    uint32_t dataSize = _env->GetArrayLength(_IDs);
1153    if (kLogApi) {
1154        ALOGD("nElementGetSubElements, con(%p)", (RsContext)con);
1155    }
1156
1157    uintptr_t *ids = (uintptr_t*)malloc(dataSize * sizeof(uintptr_t));
1158    const char **names = (const char **)malloc(dataSize * sizeof(const char *));
1159    size_t *arraySizes = (size_t *)malloc(dataSize * sizeof(size_t));
1160
1161    rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
1162                             (uint32_t)dataSize);
1163
1164    for(uint32_t i = 0; i < dataSize; i++) {
1165        const jlong id = (jlong)(uintptr_t)ids[i];
1166        const jint arraySize = (jint)arraySizes[i];
1167        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
1168        _env->SetLongArrayRegion(_IDs, i, 1, &id);
1169        _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
1170    }
1171
1172    free(ids);
1173    free(names);
1174    free(arraySizes);
1175}
1176
1177// -----------------------------------
1178
1179static jlong
1180nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
1181            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
1182{
1183    if (kLogApi) {
1184        ALOGD("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
1185              (RsContext)con, (void*)eid, dimx, dimy, dimz, mips, faces, yuv);
1186    }
1187
1188    return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips,
1189                                          faces, yuv);
1190}
1191
1192static void
1193nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jlongArray _typeData)
1194{
1195    // We are packing 6 items: mDimX; mDimY; mDimZ;
1196    // mDimLOD; mDimFaces; mElement; into typeData
1197    int elementCount = _env->GetArrayLength(_typeData);
1198
1199    assert(elementCount == 6);
1200    if (kLogApi) {
1201        ALOGD("nTypeGetNativeData, con(%p)", (RsContext)con);
1202    }
1203
1204    uintptr_t typeData[6];
1205    rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
1206
1207    for(jint i = 0; i < elementCount; i ++) {
1208        const jlong data = (jlong)(uintptr_t)typeData[i];
1209        _env->SetLongArrayRegion(_typeData, i, 1, &data);
1210    }
1211}
1212
1213// -----------------------------------
1214
1215static jlong
1216nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
1217                       jlong pointer)
1218{
1219    if (kLogApi) {
1220        ALOGD("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
1221              (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
1222    }
1223    return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type,
1224                                                      (RsAllocationMipmapControl)mips,
1225                                                      (uint32_t)usage, (uintptr_t)pointer);
1226}
1227
1228static void
1229nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
1230{
1231    if (kLogApi) {
1232        ALOGD("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a,
1233              bits);
1234    }
1235    rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
1236}
1237
1238static void
1239nAllocationSetupBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint numAlloc)
1240{
1241    if (kLogApi) {
1242        ALOGD("nAllocationSetupBufferQueue, con(%p), alloc(%p), numAlloc(%d)", (RsContext)con,
1243              (RsAllocation)alloc, numAlloc);
1244    }
1245    rsAllocationSetupBufferQueue((RsContext)con, (RsAllocation)alloc, (uint32_t)numAlloc);
1246}
1247
1248static void
1249nAllocationShareBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc1, jlong alloc2)
1250{
1251    if (kLogApi) {
1252        ALOGD("nAllocationShareBufferQueue, con(%p), alloc1(%p), alloc2(%p)", (RsContext)con,
1253              (RsAllocation)alloc1, (RsAllocation)alloc2);
1254    }
1255
1256    rsAllocationShareBufferQueue((RsContext)con, (RsAllocation)alloc1, (RsAllocation)alloc2);
1257}
1258
1259static jobject
1260nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
1261{
1262    if (kLogApi) {
1263        ALOGD("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1264    }
1265
1266    ANativeWindow *anw = (ANativeWindow *)rsAllocationGetSurface((RsContext)con, (RsAllocation)a);
1267
1268    sp<Surface> surface(static_cast<Surface*>(anw));
1269    sp<IGraphicBufferProducer> bp = surface->getIGraphicBufferProducer();
1270
1271    jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp);
1272    return o;
1273}
1274
1275static void
1276nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
1277{
1278    if (kLogApi) {
1279        ALOGD("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)", (RsContext)con,
1280              (RsAllocation)alloc, (Surface *)sur);
1281    }
1282
1283    ANativeWindow *anw = nullptr;
1284    if (sur != 0) {
1285        // Connect the native window handle to buffer queue.
1286        anw = ANativeWindow_fromSurface(_env, sur);
1287        native_window_api_connect(anw, NATIVE_WINDOW_API_CPU);
1288    }
1289
1290    rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, anw);
1291}
1292
1293static void
1294nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1295{
1296    if (kLogApi) {
1297        ALOGD("nAllocationIoSend, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1298    }
1299    rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
1300}
1301
1302static jlong
1303nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1304{
1305    if (kLogApi) {
1306        ALOGD("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1307    }
1308    return (jlong) rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
1309}
1310
1311static void
1312nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1313{
1314    if (kLogApi) {
1315        ALOGD("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
1316    }
1317    rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
1318}
1319
1320static jlong
1321nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
1322                            jobject jbitmap, jint usage)
1323{
1324    SkBitmap bitmap;
1325    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1326
1327    bitmap.lockPixels();
1328    const void* ptr = bitmap.getPixels();
1329    jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
1330                                                  (RsType)type, (RsAllocationMipmapControl)mip,
1331                                                  ptr, bitmap.getSize(), usage);
1332    bitmap.unlockPixels();
1333    return id;
1334}
1335
1336static jlong
1337nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
1338                                        jint mip, jobject jbitmap, jint usage)
1339{
1340    SkBitmap bitmap;
1341    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1342
1343    bitmap.lockPixels();
1344    const void* ptr = bitmap.getPixels();
1345    jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
1346                                            (RsType)type, (RsAllocationMipmapControl)mip,
1347                                            (uint32_t)usage, (uintptr_t)ptr);
1348    bitmap.unlockPixels();
1349    return id;
1350}
1351
1352static jlong
1353nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
1354                                jobject jbitmap, jint usage)
1355{
1356    SkBitmap bitmap;
1357    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1358
1359    bitmap.lockPixels();
1360    const void* ptr = bitmap.getPixels();
1361    jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
1362                                                      (RsType)type, (RsAllocationMipmapControl)mip,
1363                                                      ptr, bitmap.getSize(), usage);
1364    bitmap.unlockPixels();
1365    return id;
1366}
1367
1368static void
1369nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1370{
1371    SkBitmap bitmap;
1372    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1373    int w = bitmap.width();
1374    int h = bitmap.height();
1375
1376    bitmap.lockPixels();
1377    const void* ptr = bitmap.getPixels();
1378    rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
1379                       0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
1380                       w, h, ptr, bitmap.getSize(), 0);
1381    bitmap.unlockPixels();
1382}
1383
1384static void
1385nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1386{
1387    SkBitmap bitmap;
1388    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1389
1390    bitmap.lockPixels();
1391    void* ptr = bitmap.getPixels();
1392    rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
1393    bitmap.unlockPixels();
1394    bitmap.notifyPixelsChanged();
1395}
1396
1397// Copies from the Java object data into the Allocation pointed to by _alloc.
1398static void
1399nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1400                  jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
1401                  jboolean usePadding)
1402{
1403    RsAllocation *alloc = (RsAllocation *)_alloc;
1404    if (kLogApi) {
1405        ALOGD("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1406              "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
1407              dataType);
1408    }
1409    PER_ARRAY_TYPE(nullptr, rsAllocation1DData, true,
1410                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1411}
1412
1413static void
1414nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1415                       jint xoff, jint yoff, jint zoff,
1416                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1417{
1418    if (kLogApi) {
1419        jint len = _env->GetArrayLength(data);
1420        ALOGD("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1421              "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1422              sizeBytes);
1423    }
1424    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1425    if (ptr == nullptr) {
1426        ALOGE("Failed to get Java array elements");
1427        return;
1428    }
1429    rsAllocationElementData((RsContext)con, (RsAllocation)alloc,
1430                            xoff, yoff, zoff,
1431                            lod, ptr, sizeBytes, compIdx);
1432    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1433}
1434
1435
1436// Copies from the Java object data into the Allocation pointed to by _alloc.
1437static void
1438nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1439                  jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
1440                  jboolean usePadding)
1441{
1442    RsAllocation *alloc = (RsAllocation *)_alloc;
1443    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1444    if (kLogApi) {
1445        ALOGD("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1446              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1447    }
1448    int count = w * h;
1449    PER_ARRAY_TYPE(nullptr, rsAllocation2DData, true,
1450                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1451}
1452
1453// Copies from the Allocation pointed to by srcAlloc into the Allocation
1454// pointed to by dstAlloc.
1455static void
1456nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
1457                        jlong dstAlloc, jint dstXoff, jint dstYoff,
1458                        jint dstMip, jint dstFace,
1459                        jint width, jint height,
1460                        jlong srcAlloc, jint srcXoff, jint srcYoff,
1461                        jint srcMip, jint srcFace)
1462{
1463    if (kLogApi) {
1464        ALOGD("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1465              " dstMip(%i), dstFace(%i), width(%i), height(%i),"
1466              " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
1467              (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
1468              width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
1469    }
1470
1471    rsAllocationCopy2DRange((RsContext)con,
1472                            (RsAllocation)dstAlloc,
1473                            dstXoff, dstYoff,
1474                            dstMip, dstFace,
1475                            width, height,
1476                            (RsAllocation)srcAlloc,
1477                            srcXoff, srcYoff,
1478                            srcMip, srcFace);
1479}
1480
1481// Copies from the Java object data into the Allocation pointed to by _alloc.
1482static void
1483nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1484                  jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
1485                  jint mSize, jboolean usePadding)
1486{
1487    RsAllocation *alloc = (RsAllocation *)_alloc;
1488    if (kLogApi) {
1489        ALOGD("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1490              " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1491              lod, w, h, d, sizeBytes);
1492    }
1493    int count = w * h * d;
1494    PER_ARRAY_TYPE(nullptr, rsAllocation3DData, true,
1495                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1496}
1497
1498// Copies from the Allocation pointed to by srcAlloc into the Allocation
1499// pointed to by dstAlloc.
1500static void
1501nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
1502                        jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
1503                        jint dstMip,
1504                        jint width, jint height, jint depth,
1505                        jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
1506                        jint srcMip)
1507{
1508    if (kLogApi) {
1509        ALOGD("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1510              " dstMip(%i), width(%i), height(%i),"
1511              " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
1512              (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip,
1513              width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip);
1514    }
1515
1516    rsAllocationCopy3DRange((RsContext)con,
1517                            (RsAllocation)dstAlloc,
1518                            dstXoff, dstYoff, dstZoff, dstMip,
1519                            width, height, depth,
1520                            (RsAllocation)srcAlloc,
1521                            srcXoff, srcYoff, srcZoff, srcMip);
1522}
1523
1524
1525// Copies from the Allocation pointed to by _alloc into the Java object data.
1526static void
1527nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
1528                jint mSize, jboolean usePadding)
1529{
1530    RsAllocation *alloc = (RsAllocation *)_alloc;
1531    if (kLogApi) {
1532        ALOGD("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1533    }
1534    int count = 0;
1535    PER_ARRAY_TYPE(0, rsAllocationRead, false,
1536                   (RsContext)con, alloc, ptr, len * typeBytes);
1537}
1538
1539// Copies from the Allocation pointed to by _alloc into the Java object data.
1540static void
1541nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1542                  jint count, jobject data, jint sizeBytes, jint dataType,
1543                  jint mSize, jboolean usePadding)
1544{
1545    RsAllocation *alloc = (RsAllocation *)_alloc;
1546    if (kLogApi) {
1547        ALOGD("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1548              "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
1549    }
1550    PER_ARRAY_TYPE(0, rsAllocation1DRead, false,
1551                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1552}
1553
1554// Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
1555static void
1556nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1557                       jint xoff, jint yoff, jint zoff,
1558                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1559{
1560    if (kLogApi) {
1561        jint len = _env->GetArrayLength(data);
1562        ALOGD("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1563              "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1564              sizeBytes);
1565    }
1566    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1567    if (ptr == nullptr) {
1568        ALOGE("Failed to get Java array elements");
1569        return;
1570    }
1571    rsAllocationElementRead((RsContext)con, (RsAllocation)alloc,
1572                            xoff, yoff, zoff,
1573                            lod, ptr, sizeBytes, compIdx);
1574    _env->ReleaseByteArrayElements(data, ptr, 0);
1575}
1576
1577// Copies from the Allocation pointed to by _alloc into the Java object data.
1578static void
1579nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1580                  jint w, jint h, jobject data, jint sizeBytes, jint dataType,
1581                  jint mSize, jboolean usePadding)
1582{
1583    RsAllocation *alloc = (RsAllocation *)_alloc;
1584    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1585    if (kLogApi) {
1586        ALOGD("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1587              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1588    }
1589    int count = w * h;
1590    PER_ARRAY_TYPE(0, rsAllocation2DRead, false,
1591                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1592}
1593
1594// Copies from the Allocation pointed to by _alloc into the Java object data.
1595static void
1596nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1597                  jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
1598                  jint mSize, jboolean usePadding)
1599{
1600    RsAllocation *alloc = (RsAllocation *)_alloc;
1601    if (kLogApi) {
1602        ALOGD("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1603              " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1604              lod, w, h, d, sizeBytes);
1605    }
1606    int count = w * h * d;
1607    PER_ARRAY_TYPE(nullptr, rsAllocation3DRead, false,
1608                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1609}
1610
1611static jlong
1612nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
1613{
1614    if (kLogApi) {
1615        ALOGD("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1616    }
1617    return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
1618}
1619
1620static void
1621nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
1622{
1623    if (kLogApi) {
1624        ALOGD("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
1625              (RsAllocation)alloc, dimX);
1626    }
1627    rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
1628}
1629
1630
1631static jlong
1632nAllocationAdapterCreate(JNIEnv *_env, jobject _this, jlong con, jlong basealloc, jlong type)
1633{
1634    if (kLogApi) {
1635        ALOGD("nAllocationAdapterCreate, con(%p), base(%p), type(%p)",
1636              (RsContext)con, (RsAllocation)basealloc, (RsElement)type);
1637    }
1638    return (jlong)(uintptr_t) rsAllocationAdapterCreate((RsContext)con, (RsType)type,
1639                                                        (RsAllocation)basealloc);
1640
1641}
1642
1643static void
1644nAllocationAdapterOffset(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1645                        jint x, jint y, jint z, jint face, jint lod,
1646                        jint a1, jint a2, jint a3, jint a4)
1647{
1648    uint32_t params[] = {
1649        (uint32_t)x, (uint32_t)y, (uint32_t)z, (uint32_t)face,
1650        (uint32_t)lod, (uint32_t)a1, (uint32_t)a2, (uint32_t)a3, (uint32_t)a4
1651    };
1652    if (kLogApi) {
1653        ALOGD("nAllocationAdapterOffset, con(%p), alloc(%p), x(%i), y(%i), z(%i), face(%i), lod(%i), arrays(%i %i %i %i)",
1654              (RsContext)con, (RsAllocation)alloc, x, y, z, face, lod, a1, a2, a3, a4);
1655    }
1656    rsAllocationAdapterOffset((RsContext)con, (RsAllocation)alloc,
1657                              params, sizeof(params));
1658}
1659
1660
1661// -----------------------------------
1662
1663static jlong
1664nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset)
1665{
1666    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1667    ALOGV("______nFileA3D %p", asset);
1668
1669    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
1670    return id;
1671}
1672
1673static jlong
1674nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
1675{
1676    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1677    if (mgr == nullptr) {
1678        return 0;
1679    }
1680
1681    AutoJavaStringToUTF8 str(_env, _path);
1682    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1683    if (asset == nullptr) {
1684        return 0;
1685    }
1686
1687    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
1688    return id;
1689}
1690
1691static jlong
1692nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
1693{
1694    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1695    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
1696
1697    return id;
1698}
1699
1700static jint
1701nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D)
1702{
1703    int32_t numEntries = 0;
1704    rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D);
1705    return (jint)numEntries;
1706}
1707
1708static void
1709nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
1710{
1711    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1712    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
1713
1714    rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
1715
1716    for(jint i = 0; i < numEntries; i ++) {
1717        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
1718        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
1719    }
1720
1721    free(fileEntries);
1722}
1723
1724static jlong
1725nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
1726{
1727    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1728    jlong id = (jlong)(uintptr_t)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
1729    return id;
1730}
1731
1732// -----------------------------------
1733
1734static jlong
1735nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con,
1736                    jstring fileName, jfloat fontSize, jint dpi)
1737{
1738    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1739    jlong id = (jlong)(uintptr_t)rsFontCreateFromFile((RsContext)con,
1740                                         fileNameUTF.c_str(), fileNameUTF.length(),
1741                                         fontSize, dpi);
1742
1743    return id;
1744}
1745
1746static jlong
1747nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con,
1748                           jstring name, jfloat fontSize, jint dpi, jlong native_asset)
1749{
1750    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1751    AutoJavaStringToUTF8 nameUTF(_env, name);
1752
1753    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1754                                           nameUTF.c_str(), nameUTF.length(),
1755                                           fontSize, dpi,
1756                                           asset->getBuffer(false), asset->getLength());
1757    return id;
1758}
1759
1760static jlong
1761nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
1762                     jfloat fontSize, jint dpi)
1763{
1764    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1765    if (mgr == nullptr) {
1766        return 0;
1767    }
1768
1769    AutoJavaStringToUTF8 str(_env, _path);
1770    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1771    if (asset == nullptr) {
1772        return 0;
1773    }
1774
1775    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1776                                           str.c_str(), str.length(),
1777                                           fontSize, dpi,
1778                                           asset->getBuffer(false), asset->getLength());
1779    delete asset;
1780    return id;
1781}
1782
1783// -----------------------------------
1784
1785static void
1786nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
1787{
1788    if (kLogApi) {
1789        ALOGD("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con,
1790              (RsScript)script, (RsAllocation)alloc, slot);
1791    }
1792    rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1793}
1794
1795static void
1796nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
1797{
1798    if (kLogApi) {
1799        ALOGD("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script,
1800              slot, val);
1801    }
1802    rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1803}
1804
1805static jint
1806nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1807{
1808    if (kLogApi) {
1809        ALOGD("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1810    }
1811    int value = 0;
1812    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1813    return value;
1814}
1815
1816static void
1817nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1818{
1819    if (kLogApi) {
1820        ALOGD("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1821              slot, val);
1822    }
1823    rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1824}
1825
1826static void
1827nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1828{
1829    if (kLogApi) {
1830        ALOGD("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1831              slot, val);
1832    }
1833    rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1834}
1835
1836static jlong
1837nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1838{
1839    if (kLogApi) {
1840        ALOGD("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1841    }
1842    jlong value = 0;
1843    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1844    return value;
1845}
1846
1847static void
1848nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
1849{
1850    if (kLogApi) {
1851        ALOGD("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script,
1852              slot, val);
1853    }
1854    rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1855}
1856
1857static jfloat
1858nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1859{
1860    if (kLogApi) {
1861        ALOGD("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1862    }
1863    jfloat value = 0;
1864    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1865    return value;
1866}
1867
1868static void
1869nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
1870{
1871    if (kLogApi) {
1872        ALOGD("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script,
1873              slot, val);
1874    }
1875    rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1876}
1877
1878static jdouble
1879nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1880{
1881    if (kLogApi) {
1882        ALOGD("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1883    }
1884    jdouble value = 0;
1885    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1886    return value;
1887}
1888
1889static void
1890nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1891{
1892    if (kLogApi) {
1893        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1894    }
1895    jint len = _env->GetArrayLength(data);
1896    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1897    if (ptr == nullptr) {
1898        ALOGE("Failed to get Java array elements");
1899        return;
1900    }
1901    rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1902    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1903}
1904
1905static void
1906nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1907{
1908    if (kLogApi) {
1909        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1910    }
1911    jint len = _env->GetArrayLength(data);
1912    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1913    if (ptr == nullptr) {
1914        ALOGE("Failed to get Java array elements");
1915        return;
1916    }
1917    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1918    _env->ReleaseByteArrayElements(data, ptr, 0);
1919}
1920
1921static void
1922nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
1923                jlong elem, jintArray dims)
1924{
1925    if (kLogApi) {
1926        ALOGD("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1927    }
1928    jint len = _env->GetArrayLength(data);
1929    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1930    if (ptr == nullptr) {
1931        ALOGE("Failed to get Java array elements");
1932        return;
1933    }
1934    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1935    jint *dimsPtr = _env->GetIntArrayElements(dims, nullptr);
1936    if (dimsPtr == nullptr) {
1937        ALOGE("Failed to get Java array elements");
1938        return;
1939    }
1940    rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1941                     (const uint32_t*) dimsPtr, dimsLen);
1942    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1943    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1944}
1945
1946
1947static void
1948nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
1949{
1950    if (kLogApi) {
1951        ALOGD("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
1952    }
1953
1954    jint length = _env->GetArrayLength(timeZone);
1955    jbyte* timeZone_ptr;
1956    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1957    if (timeZone_ptr == nullptr) {
1958        ALOGE("Failed to get Java array elements");
1959        return;
1960    }
1961
1962    rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1963
1964    if (timeZone_ptr) {
1965        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1966    }
1967}
1968
1969static void
1970nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
1971{
1972    if (kLogApi) {
1973        ALOGD("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1974    }
1975    rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
1976}
1977
1978static void
1979nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1980{
1981    if (kLogApi) {
1982        ALOGD("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1983    }
1984    jint len = _env->GetArrayLength(data);
1985    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1986    if (ptr == nullptr) {
1987        ALOGE("Failed to get Java array elements");
1988        return;
1989    }
1990    rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1991    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1992}
1993
1994static void
1995nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
1996               jlongArray ains, jlong aout, jbyteArray params,
1997               jintArray limits)
1998{
1999    if (kLogApi) {
2000        ALOGD("nScriptForEach, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
2001    }
2002
2003    jint   in_len = 0;
2004    jlong *in_ptr = nullptr;
2005
2006    RsAllocation *in_allocs = nullptr;
2007
2008    if (ains != nullptr) {
2009        in_len = _env->GetArrayLength(ains);
2010        if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
2011            ALOGE("Too many arguments in kernel launch.");
2012            // TODO (b/20758983): Report back to Java and throw an exception
2013            return;
2014        }
2015
2016        in_ptr = _env->GetLongArrayElements(ains, nullptr);
2017        if (in_ptr == nullptr) {
2018            ALOGE("Failed to get Java array elements");
2019            return;
2020        }
2021
2022        if (sizeof(RsAllocation) == sizeof(jlong)) {
2023            in_allocs = (RsAllocation*)in_ptr;
2024        } else {
2025            // Convert from 64-bit jlong types to the native pointer type.
2026
2027            in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
2028            if (in_allocs == nullptr) {
2029                ALOGE("Failed launching kernel for lack of memory.");
2030                _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2031                return;
2032            }
2033
2034            for (int index = in_len; --index >= 0;) {
2035                in_allocs[index] = (RsAllocation)in_ptr[index];
2036            }
2037        }
2038    }
2039
2040    jint   param_len = 0;
2041    jbyte *param_ptr = nullptr;
2042
2043    if (params != nullptr) {
2044        param_len = _env->GetArrayLength(params);
2045        param_ptr = _env->GetByteArrayElements(params, nullptr);
2046        if (param_ptr == nullptr) {
2047            ALOGE("Failed to get Java array elements");
2048            return;
2049        }
2050    }
2051
2052    RsScriptCall sc, *sca = nullptr;
2053    uint32_t sc_size = 0;
2054
2055    jint  limit_len = 0;
2056    jint *limit_ptr = nullptr;
2057
2058    if (limits != nullptr) {
2059        limit_len = _env->GetArrayLength(limits);
2060        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
2061        if (limit_ptr == nullptr) {
2062            ALOGE("Failed to get Java array elements");
2063            return;
2064        }
2065
2066        assert(limit_len == 6);
2067        UNUSED(limit_len);  // As the assert might not be compiled.
2068
2069        sc.xStart     = limit_ptr[0];
2070        sc.xEnd       = limit_ptr[1];
2071        sc.yStart     = limit_ptr[2];
2072        sc.yEnd       = limit_ptr[3];
2073        sc.zStart     = limit_ptr[4];
2074        sc.zEnd       = limit_ptr[5];
2075        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
2076        sc.arrayStart = 0;
2077        sc.arrayEnd = 0;
2078        sc.array2Start = 0;
2079        sc.array2End = 0;
2080        sc.array3Start = 0;
2081        sc.array3End = 0;
2082        sc.array4Start = 0;
2083        sc.array4End = 0;
2084
2085        sca = &sc;
2086        // sc_size is required, but unused, by the runtime and drivers.
2087        sc_size = sizeof(sc);
2088    }
2089
2090    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
2091                         in_allocs, in_len, (RsAllocation)aout,
2092                         param_ptr, param_len, sca, sc_size);
2093
2094    if (ains != nullptr) {
2095        _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2096    }
2097
2098    if (params != nullptr) {
2099        _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
2100    }
2101
2102    if (limits != nullptr) {
2103        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2104    }
2105}
2106
2107static void
2108nScriptReduce(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
2109              jlongArray ains, jlong aout, jintArray limits)
2110{
2111    if (kLogApi) {
2112        ALOGD("nScriptReduce, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
2113    }
2114
2115    if (ains == nullptr) {
2116        ALOGE("At least one input required.");
2117        // TODO (b/20758983): Report back to Java and throw an exception
2118        return;
2119    }
2120    jint in_len = _env->GetArrayLength(ains);
2121    if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
2122        ALOGE("Too many arguments in kernel launch.");
2123        // TODO (b/20758983): Report back to Java and throw an exception
2124        return;
2125    }
2126
2127    jlong *in_ptr = _env->GetLongArrayElements(ains, nullptr);
2128    if (in_ptr == nullptr) {
2129        ALOGE("Failed to get Java array elements");
2130        // TODO (b/20758983): Report back to Java and throw an exception
2131        return;
2132    }
2133
2134    RsAllocation *in_allocs = nullptr;
2135    if (sizeof(RsAllocation) == sizeof(jlong)) {
2136        in_allocs = (RsAllocation*)in_ptr;
2137    } else {
2138        // Convert from 64-bit jlong types to the native pointer type.
2139
2140        in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
2141        if (in_allocs == nullptr) {
2142            ALOGE("Failed launching kernel for lack of memory.");
2143            // TODO (b/20758983): Report back to Java and throw an exception
2144            _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2145            return;
2146        }
2147
2148        for (int index = in_len; --index >= 0;) {
2149            in_allocs[index] = (RsAllocation)in_ptr[index];
2150        }
2151    }
2152
2153    RsScriptCall sc, *sca = nullptr;
2154    uint32_t sc_size = 0;
2155
2156    jint  limit_len = 0;
2157    jint *limit_ptr = nullptr;
2158
2159    if (limits != nullptr) {
2160        limit_len = _env->GetArrayLength(limits);
2161        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
2162        if (limit_ptr == nullptr) {
2163            ALOGE("Failed to get Java array elements");
2164            // TODO (b/20758983): Report back to Java and throw an exception
2165            return;
2166        }
2167
2168        assert(limit_len == 6);
2169        UNUSED(limit_len);  // As the assert might not be compiled.
2170
2171        sc.xStart     = limit_ptr[0];
2172        sc.xEnd       = limit_ptr[1];
2173        sc.yStart     = limit_ptr[2];
2174        sc.yEnd       = limit_ptr[3];
2175        sc.zStart     = limit_ptr[4];
2176        sc.zEnd       = limit_ptr[5];
2177        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
2178        sc.arrayStart = 0;
2179        sc.arrayEnd = 0;
2180        sc.array2Start = 0;
2181        sc.array2End = 0;
2182        sc.array3Start = 0;
2183        sc.array3End = 0;
2184        sc.array4Start = 0;
2185        sc.array4End = 0;
2186
2187        sca = &sc;
2188        sc_size = sizeof(sc);
2189    }
2190
2191    rsScriptReduce((RsContext)con, (RsScript)script, slot,
2192                   in_allocs, in_len, (RsAllocation)aout,
2193                   sca, sc_size);
2194
2195    _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2196
2197    if (limits != nullptr) {
2198        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2199    }
2200}
2201
2202// -----------------------------------
2203
2204static jlong
2205nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
2206               jstring resName, jstring cacheDir,
2207               jbyteArray scriptRef, jint length)
2208{
2209    if (kLogApi) {
2210        ALOGD("nScriptCCreate, con(%p)", (RsContext)con);
2211    }
2212
2213    AutoJavaStringToUTF8 resNameUTF(_env, resName);
2214    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
2215    jlong ret = 0;
2216    jbyte* script_ptr = nullptr;
2217    jint _exception = 0;
2218    jint remaining;
2219    if (!scriptRef) {
2220        _exception = 1;
2221        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
2222        goto exit;
2223    }
2224    if (length < 0) {
2225        _exception = 1;
2226        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
2227        goto exit;
2228    }
2229    remaining = _env->GetArrayLength(scriptRef);
2230    if (remaining < length) {
2231        _exception = 1;
2232        //jniThrowException(_env, "java/lang/IllegalArgumentException",
2233        //        "length > script.length - offset");
2234        goto exit;
2235    }
2236    script_ptr = (jbyte *)
2237        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
2238    if (script_ptr == nullptr) {
2239        ALOGE("Failed to get Java array elements");
2240        return ret;
2241    }
2242
2243    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
2244
2245    ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
2246                                resNameUTF.c_str(), resNameUTF.length(),
2247                                cacheDirUTF.c_str(), cacheDirUTF.length(),
2248                                (const char *)script_ptr, length);
2249
2250exit:
2251    if (script_ptr) {
2252        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
2253                _exception ? JNI_ABORT: 0);
2254    }
2255
2256    return (jlong)(uintptr_t)ret;
2257}
2258
2259static jlong
2260nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
2261{
2262    if (kLogApi) {
2263        ALOGD("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id,
2264              (void *)eid);
2265    }
2266    return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
2267}
2268
2269static jlong
2270nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
2271{
2272    if (kLogApi) {
2273        ALOGD("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
2274              (void *)sid, slot, sig);
2275    }
2276    return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
2277}
2278
2279static jlong
2280nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
2281{
2282    if (kLogApi) {
2283        ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con,
2284              (void *)sid, slot);
2285    }
2286    return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
2287}
2288
2289static jlong
2290nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
2291{
2292    if (kLogApi) {
2293        ALOGD("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid,
2294              slot);
2295    }
2296    return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
2297}
2298
2299static jlong
2300nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
2301    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
2302{
2303    if (kLogApi) {
2304        ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
2305    }
2306
2307    jlong id = 0;
2308
2309    RsScriptKernelID* kernelsPtr;
2310    jint kernelsLen = _env->GetArrayLength(_kernels);
2311    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
2312
2313    RsScriptKernelID* srcPtr;
2314    jint srcLen = _env->GetArrayLength(_src);
2315    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
2316
2317    RsScriptKernelID* dstkPtr;
2318    jint dstkLen = _env->GetArrayLength(_dstk);
2319    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
2320
2321    RsScriptKernelID* dstfPtr;
2322    jint dstfLen = _env->GetArrayLength(_dstf);
2323    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
2324
2325    RsType* typesPtr;
2326    jint typesLen = _env->GetArrayLength(_types);
2327    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
2328
2329    if (jKernelsPtr == nullptr) {
2330        ALOGE("Failed to get Java array elements: kernels");
2331        goto cleanup;
2332    }
2333    if (jSrcPtr == nullptr) {
2334        ALOGE("Failed to get Java array elements: src");
2335        goto cleanup;
2336    }
2337    if (jDstkPtr == nullptr) {
2338        ALOGE("Failed to get Java array elements: dstk");
2339        goto cleanup;
2340    }
2341    if (jDstfPtr == nullptr) {
2342        ALOGE("Failed to get Java array elements: dstf");
2343        goto cleanup;
2344    }
2345    if (jTypesPtr == nullptr) {
2346        ALOGE("Failed to get Java array elements: types");
2347        goto cleanup;
2348    }
2349
2350    kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
2351    for(int i = 0; i < kernelsLen; ++i) {
2352        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
2353    }
2354
2355    srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
2356    for(int i = 0; i < srcLen; ++i) {
2357        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
2358    }
2359
2360    dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
2361    for(int i = 0; i < dstkLen; ++i) {
2362        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
2363    }
2364
2365    dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
2366    for(int i = 0; i < dstfLen; ++i) {
2367        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
2368    }
2369
2370    typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
2371    for(int i = 0; i < typesLen; ++i) {
2372        typesPtr[i] = (RsType)jTypesPtr[i];
2373    }
2374
2375    id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
2376                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
2377                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
2378                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
2379                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
2380                               (RsType *)typesPtr, typesLen * sizeof(RsType));
2381
2382    free(kernelsPtr);
2383    free(srcPtr);
2384    free(dstkPtr);
2385    free(dstfPtr);
2386    free(typesPtr);
2387
2388cleanup:
2389    if (jKernelsPtr != nullptr) {
2390        _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
2391    }
2392    if (jSrcPtr != nullptr) {
2393        _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
2394    }
2395    if (jDstkPtr != nullptr) {
2396        _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
2397    }
2398    if (jDstfPtr != nullptr) {
2399        _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
2400    }
2401    if (jTypesPtr != nullptr) {
2402        _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
2403    }
2404
2405    return id;
2406}
2407
2408static void
2409nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2410{
2411    if (kLogApi) {
2412        ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2413              (void *)gid, (void *)kid, (void *)alloc);
2414    }
2415    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2416}
2417
2418static void
2419nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2420{
2421    if (kLogApi) {
2422        ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2423              (void *)gid, (void *)kid, (void *)alloc);
2424    }
2425    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2426}
2427
2428static void
2429nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
2430{
2431    if (kLogApi) {
2432        ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
2433    }
2434    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
2435}
2436
2437// ---------------------------------------------------------------------------
2438
2439static jlong
2440nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
2441                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
2442                    jboolean depthMask, jboolean ditherEnable,
2443                    jint srcFunc, jint destFunc,
2444                    jint depthFunc)
2445{
2446    if (kLogApi) {
2447        ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
2448    }
2449    return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
2450                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
2451                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
2452}
2453
2454// ---------------------------------------------------------------------------
2455
2456static void
2457nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
2458{
2459    if (kLogApi) {
2460        ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
2461              (RsProgramVertex)vpv, slot, (RsAllocation)a);
2462    }
2463    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
2464}
2465
2466static void
2467nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2468{
2469    if (kLogApi) {
2470        ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2471              (RsProgramFragment)vpf, slot, (RsAllocation)a);
2472    }
2473    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
2474}
2475
2476static void
2477nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2478{
2479    if (kLogApi) {
2480        ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2481              (RsProgramFragment)vpf, slot, (RsSampler)a);
2482    }
2483    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
2484}
2485
2486// ---------------------------------------------------------------------------
2487
2488static jlong
2489nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2490                       jobjectArray texNames, jlongArray params)
2491{
2492    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2493    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2494    jint paramLen = _env->GetArrayLength(params);
2495    if (jParamPtr == nullptr) {
2496        ALOGE("Failed to get Java array elements");
2497        return 0;
2498    }
2499
2500    int texCount = _env->GetArrayLength(texNames);
2501    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2502    const char ** nameArray = names.c_str();
2503    size_t* sizeArray = names.c_str_len();
2504
2505    if (kLogApi) {
2506        ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2507    }
2508
2509    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2510    for(int i = 0; i < paramLen; ++i) {
2511        paramPtr[i] = (uintptr_t)jParamPtr[i];
2512    }
2513    jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2514                                             nameArray, texCount, sizeArray,
2515                                             paramPtr, paramLen);
2516
2517    free(paramPtr);
2518    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2519    return ret;
2520}
2521
2522
2523// ---------------------------------------------------------------------------
2524
2525static jlong
2526nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2527                     jobjectArray texNames, jlongArray params)
2528{
2529    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2530    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2531    jint paramLen = _env->GetArrayLength(params);
2532    if (jParamPtr == nullptr) {
2533        ALOGE("Failed to get Java array elements");
2534        return 0;
2535    }
2536
2537    if (kLogApi) {
2538        ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2539    }
2540
2541    int texCount = _env->GetArrayLength(texNames);
2542    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2543    const char ** nameArray = names.c_str();
2544    size_t* sizeArray = names.c_str_len();
2545
2546    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2547    for(int i = 0; i < paramLen; ++i) {
2548        paramPtr[i] = (uintptr_t)jParamPtr[i];
2549    }
2550
2551    jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2552                                           nameArray, texCount, sizeArray,
2553                                           paramPtr, paramLen);
2554
2555    free(paramPtr);
2556    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2557    return ret;
2558}
2559
2560// ---------------------------------------------------------------------------
2561
2562static jlong
2563nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
2564{
2565    if (kLogApi) {
2566        ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
2567              pointSprite, cull);
2568    }
2569    return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
2570}
2571
2572
2573// ---------------------------------------------------------------------------
2574
2575static void
2576nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
2577{
2578    if (kLogApi) {
2579        ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
2580    }
2581    rsContextBindRootScript((RsContext)con, (RsScript)script);
2582}
2583
2584static void
2585nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
2586{
2587    if (kLogApi) {
2588        ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
2589    }
2590    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
2591}
2592
2593static void
2594nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2595{
2596    if (kLogApi) {
2597        ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
2598              (RsProgramFragment)pf);
2599    }
2600    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
2601}
2602
2603static void
2604nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2605{
2606    if (kLogApi) {
2607        ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
2608    }
2609    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
2610}
2611
2612static void
2613nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2614{
2615    if (kLogApi) {
2616        ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
2617    }
2618    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
2619}
2620
2621
2622// ---------------------------------------------------------------------------
2623
2624static jlong
2625nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
2626               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
2627{
2628    if (kLogApi) {
2629        ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
2630    }
2631    return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
2632                                 (RsSamplerValue)magFilter,
2633                                 (RsSamplerValue)minFilter,
2634                                 (RsSamplerValue)wrapS,
2635                                 (RsSamplerValue)wrapT,
2636                                 (RsSamplerValue)wrapR,
2637                                 aniso);
2638}
2639
2640// ---------------------------------------------------------------------------
2641
2642static jlong
2643nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
2644{
2645    if (kLogApi) {
2646        ALOGD("nMeshCreate, con(%p)", (RsContext)con);
2647    }
2648
2649    jlong id = 0;
2650
2651    RsAllocation* vtxPtr;
2652    jint vtxLen = _env->GetArrayLength(_vtx);
2653    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
2654
2655    RsAllocation* idxPtr;
2656    jint idxLen = _env->GetArrayLength(_idx);
2657    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
2658
2659    jint primLen = _env->GetArrayLength(_prim);
2660    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
2661
2662    if (jVtxPtr == nullptr) {
2663        ALOGE("Failed to get Java array elements: vtx");
2664        goto cleanupMesh;
2665    }
2666    if (jIdxPtr == nullptr) {
2667        ALOGE("Failed to get Java array elements: idx");
2668        goto cleanupMesh;
2669    }
2670    if (primPtr == nullptr) {
2671        ALOGE("Failed to get Java array elements: prim");
2672        goto cleanupMesh;
2673    }
2674
2675    vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
2676    for(int i = 0; i < vtxLen; ++i) {
2677        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
2678    }
2679
2680    idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
2681    for(int i = 0; i < idxLen; ++i) {
2682        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
2683    }
2684
2685    id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
2686                                        (RsAllocation *)vtxPtr, vtxLen,
2687                                        (RsAllocation *)idxPtr, idxLen,
2688                                        (uint32_t *)primPtr, primLen);
2689
2690    free(vtxPtr);
2691    free(idxPtr);
2692
2693cleanupMesh:
2694    if (jVtxPtr != nullptr) {
2695        _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
2696    }
2697    if (jIdxPtr != nullptr) {
2698        _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
2699    }
2700    if (primPtr != nullptr) {
2701        _env->ReleaseIntArrayElements(_prim, primPtr, 0);
2702    }
2703
2704    return id;
2705}
2706
2707static jint
2708nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2709{
2710    if (kLogApi) {
2711        ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2712    }
2713    jint vtxCount = 0;
2714    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
2715    return vtxCount;
2716}
2717
2718static jint
2719nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2720{
2721    if (kLogApi) {
2722        ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2723    }
2724    jint idxCount = 0;
2725    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
2726    return idxCount;
2727}
2728
2729static void
2730nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
2731{
2732    if (kLogApi) {
2733        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2734    }
2735
2736    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
2737    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
2738
2739    for(jint i = 0; i < numVtxIDs; i ++) {
2740        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2741        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
2742    }
2743
2744    free(allocs);
2745}
2746
2747static void
2748nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
2749{
2750    if (kLogApi) {
2751        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2752    }
2753
2754    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
2755    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
2756
2757    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
2758
2759    for(jint i = 0; i < numIndices; i ++) {
2760        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2761        const jint prim = (jint)prims[i];
2762        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
2763        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
2764    }
2765
2766    free(allocs);
2767    free(prims);
2768}
2769
2770static jint
2771nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
2772    return (jint)sizeof(void*);
2773}
2774
2775static jobject
2776nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
2777                        jlongArray strideArr, jint xBytesSize,
2778                        jint dimY, jint dimZ) {
2779    if (kLogApi) {
2780        ALOGD("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
2781    }
2782
2783    jlong *jStridePtr = _env->GetLongArrayElements(strideArr, nullptr);
2784    if (jStridePtr == nullptr) {
2785        ALOGE("Failed to get Java array elements: strideArr");
2786        return 0;
2787    }
2788
2789    size_t strideIn = xBytesSize;
2790    void* ptr = nullptr;
2791    if (alloc != 0) {
2792        ptr = rsAllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
2793                                     RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
2794                                     &strideIn, sizeof(size_t));
2795    }
2796
2797    jobject byteBuffer = nullptr;
2798    if (ptr != nullptr) {
2799        size_t bufferSize = strideIn;
2800        jStridePtr[0] = strideIn;
2801        if (dimY > 0) {
2802            bufferSize *= dimY;
2803        }
2804        if (dimZ > 0) {
2805            bufferSize *= dimZ;
2806        }
2807        byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize);
2808    }
2809    _env->ReleaseLongArrayElements(strideArr, jStridePtr, 0);
2810    return byteBuffer;
2811}
2812// ---------------------------------------------------------------------------
2813
2814
2815static const char *classPathName = "android/renderscript/RenderScript";
2816
2817static const JNINativeMethod methods[] = {
2818{"_nInit",                         "()V",                                     (void*)_nInit },
2819
2820{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
2821{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
2822{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
2823{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
2824{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
2825{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
2826
2827{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
2828{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
2829
2830
2831// All methods below are thread protected in java.
2832{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
2833{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
2834{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
2835{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
2836{"rsnContextSetCacheDir",            "(JLjava/lang/String;)V",                (void*)nContextSetCacheDir },
2837{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
2838{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
2839{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
2840{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
2841{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
2842{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
2843{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
2844{"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
2845{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
2846{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
2847{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
2848{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
2849{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
2850
2851{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
2852{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
2853{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
2854{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
2855{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
2856{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
2857
2858{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
2859{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
2860{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
2861
2862{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
2863{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
2864{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
2865{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
2866
2867{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
2868{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
2869
2870{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
2871{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
2872{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
2873{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
2874
2875{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
2876{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
2877
2878{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
2879{"rsnAllocationSetupBufferQueue",    "(JJI)V",                                (void*)nAllocationSetupBufferQueue },
2880{"rsnAllocationShareBufferQueue",    "(JJJ)V",                                (void*)nAllocationShareBufferQueue },
2881{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
2882{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
2883{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
2884{"rsnAllocationIoReceive",           "(JJ)J",                                 (void*)nAllocationIoReceive },
2885{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
2886{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
2887{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
2888{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
2889{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
2890{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
2891{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
2892{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
2893{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
2894{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
2895{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationRead3D },
2896{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
2897{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
2898{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
2899
2900{"rsnAllocationAdapterCreate",       "(JJJ)J",                                (void*)nAllocationAdapterCreate },
2901{"rsnAllocationAdapterOffset",       "(JJIIIIIIIII)V",                        (void*)nAllocationAdapterOffset },
2902
2903{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
2904{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
2905{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
2906{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
2907
2908{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
2909{"rsnScriptReduce",                  "(JJI[JJ[I)V",                           (void*)nScriptReduce },
2910
2911{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
2912{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
2913{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
2914{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
2915{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
2916{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
2917{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
2918{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
2919{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
2920{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
2921{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
2922{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
2923
2924{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
2925{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
2926{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
2927{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
2928{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
2929{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
2930{"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
2931{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
2932{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
2933{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
2934{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
2935
2936{"rsnScriptIntrinsicBLAS_Single",    "(JJIIIIIIIIIFJJFJIIII)V",               (void*)nScriptIntrinsicBLAS_Single },
2937{"rsnScriptIntrinsicBLAS_Double",    "(JJIIIIIIIIIDJJDJIIII)V",               (void*)nScriptIntrinsicBLAS_Double },
2938{"rsnScriptIntrinsicBLAS_Complex",   "(JJIIIIIIIIIFFJJFFJIIII)V",             (void*)nScriptIntrinsicBLAS_Complex },
2939{"rsnScriptIntrinsicBLAS_Z",         "(JJIIIIIIIIIDDJJDDJIIII)V",             (void*)nScriptIntrinsicBLAS_Z },
2940
2941{"rsnScriptIntrinsicBLAS_BNNM",      "(JJIIIJIJIJII)V",                       (void*)nScriptIntrinsicBLAS_BNNM },
2942
2943{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
2944
2945{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
2946{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
2947{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
2948
2949{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
2950{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
2951{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
2952
2953{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
2954{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
2955{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
2956{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
2957{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
2958
2959{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
2960
2961{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
2962
2963{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
2964{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
2965{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
2966{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
2967
2968{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
2969{"rsnAllocationGetByteBuffer",       "(JJ[JIII)Ljava/nio/ByteBuffer;",        (void*)nAllocationGetByteBuffer },
2970};
2971
2972static int registerFuncs(JNIEnv *_env)
2973{
2974    return android::AndroidRuntime::registerNativeMethods(
2975            _env, classPathName, methods, NELEM(methods));
2976}
2977
2978// ---------------------------------------------------------------------------
2979
2980jint JNI_OnLoad(JavaVM* vm, void* reserved)
2981{
2982    JNIEnv* env = nullptr;
2983    jint result = -1;
2984
2985    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
2986        ALOGE("ERROR: GetEnv failed\n");
2987        goto bail;
2988    }
2989    assert(env != nullptr);
2990
2991    if (registerFuncs(env) < 0) {
2992        ALOGE("ERROR: Renderscript native registration failed\n");
2993        goto bail;
2994    }
2995
2996    /* success -- return valid version number */
2997    result = JNI_VERSION_1_4;
2998
2999bail:
3000    return result;
3001}
3002