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