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