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