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