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