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