android_renderscript_RenderScript.cpp revision 45cec0a9711f736df26fd097c6d74834e350f9bc
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, jbyteArray data, jint sizeBytes)
1308{
1309    jint len = _env->GetArrayLength(data);
1310    if (kLogApi) {
1311        ALOGD("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1312              "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1313              sizeBytes);
1314    }
1315    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1316    rsAllocationElementRead((RsContext)con, (RsAllocation)alloc,
1317                            xoff, yoff, zoff,
1318                            lod, ptr, sizeBytes, compIdx);
1319    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1320}
1321
1322// Copies from the Allocation pointed to by _alloc into the Java object data.
1323static void
1324nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1325                  jint w, jint h, jobject data, jint sizeBytes, jint dataType,
1326                  jint mSize, jboolean usePadding)
1327{
1328    RsAllocation *alloc = (RsAllocation *)_alloc;
1329    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1330    if (kLogApi) {
1331        ALOGD("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1332              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1333    }
1334    int count = w * h;
1335    PER_ARRAY_TYPE(0, rsAllocation2DRead, false,
1336                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1337}
1338
1339// Copies from the Allocation pointed to by _alloc into the Java object data.
1340static void
1341nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1342                  jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
1343                  jint mSize, jboolean usePadding)
1344{
1345    RsAllocation *alloc = (RsAllocation *)_alloc;
1346    if (kLogApi) {
1347        ALOGD("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1348              " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1349              lod, w, h, d, sizeBytes);
1350    }
1351    int count = w * h * d;
1352    PER_ARRAY_TYPE(nullptr, rsAllocation3DRead, false,
1353                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1354}
1355
1356static jlong
1357nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
1358{
1359    if (kLogApi) {
1360        ALOGD("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1361    }
1362    return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
1363}
1364
1365static void
1366nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
1367{
1368    if (kLogApi) {
1369        ALOGD("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
1370              (RsAllocation)alloc, dimX);
1371    }
1372    rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
1373}
1374
1375
1376static jlong
1377nAllocationAdapterCreate(JNIEnv *_env, jobject _this, jlong con, jlong basealloc, jlong type)
1378{
1379    if (kLogApi) {
1380        ALOGD("nAllocationAdapterCreate, con(%p), base(%p), type(%p)",
1381              (RsContext)con, (RsAllocation)basealloc, (RsElement)type);
1382    }
1383    return (jlong)(uintptr_t) rsAllocationAdapterCreate((RsContext)con, (RsType)type,
1384                                                        (RsAllocation)basealloc);
1385
1386}
1387
1388static void
1389nAllocationAdapterOffset(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1390                        jint x, jint y, jint z, jint face, jint lod,
1391                        jint a1, jint a2, jint a3, jint a4)
1392{
1393    uint32_t params[] = {
1394        (uint32_t)x, (uint32_t)y, (uint32_t)z, (uint32_t)face,
1395        (uint32_t)lod, (uint32_t)a1, (uint32_t)a2, (uint32_t)a3, (uint32_t)a4
1396    };
1397    if (kLogApi) {
1398        ALOGD("nAllocationAdapterOffset, con(%p), alloc(%p), x(%i), y(%i), z(%i), face(%i), lod(%i), arrays(%i %i %i %i)",
1399              (RsContext)con, (RsAllocation)alloc, x, y, z, face, lod, a1, a2, a3, a4);
1400    }
1401    rsAllocationAdapterOffset((RsContext)con, (RsAllocation)alloc,
1402                              params, sizeof(params));
1403}
1404
1405
1406// -----------------------------------
1407
1408static jlong
1409nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset)
1410{
1411    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1412    ALOGV("______nFileA3D %p", asset);
1413
1414    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
1415    return id;
1416}
1417
1418static jlong
1419nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
1420{
1421    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1422    if (mgr == nullptr) {
1423        return 0;
1424    }
1425
1426    AutoJavaStringToUTF8 str(_env, _path);
1427    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1428    if (asset == nullptr) {
1429        return 0;
1430    }
1431
1432    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
1433    return id;
1434}
1435
1436static jlong
1437nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
1438{
1439    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1440    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
1441
1442    return id;
1443}
1444
1445static jint
1446nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D)
1447{
1448    int32_t numEntries = 0;
1449    rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D);
1450    return (jint)numEntries;
1451}
1452
1453static void
1454nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
1455{
1456    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1457    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
1458
1459    rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
1460
1461    for(jint i = 0; i < numEntries; i ++) {
1462        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
1463        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
1464    }
1465
1466    free(fileEntries);
1467}
1468
1469static jlong
1470nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
1471{
1472    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1473    jlong id = (jlong)(uintptr_t)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
1474    return id;
1475}
1476
1477// -----------------------------------
1478
1479static jlong
1480nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con,
1481                    jstring fileName, jfloat fontSize, jint dpi)
1482{
1483    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1484    jlong id = (jlong)(uintptr_t)rsFontCreateFromFile((RsContext)con,
1485                                         fileNameUTF.c_str(), fileNameUTF.length(),
1486                                         fontSize, dpi);
1487
1488    return id;
1489}
1490
1491static jlong
1492nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con,
1493                           jstring name, jfloat fontSize, jint dpi, jlong native_asset)
1494{
1495    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1496    AutoJavaStringToUTF8 nameUTF(_env, name);
1497
1498    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1499                                           nameUTF.c_str(), nameUTF.length(),
1500                                           fontSize, dpi,
1501                                           asset->getBuffer(false), asset->getLength());
1502    return id;
1503}
1504
1505static jlong
1506nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
1507                     jfloat fontSize, jint dpi)
1508{
1509    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1510    if (mgr == nullptr) {
1511        return 0;
1512    }
1513
1514    AutoJavaStringToUTF8 str(_env, _path);
1515    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1516    if (asset == nullptr) {
1517        return 0;
1518    }
1519
1520    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1521                                           str.c_str(), str.length(),
1522                                           fontSize, dpi,
1523                                           asset->getBuffer(false), asset->getLength());
1524    delete asset;
1525    return id;
1526}
1527
1528// -----------------------------------
1529
1530static void
1531nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
1532{
1533    if (kLogApi) {
1534        ALOGD("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con,
1535              (RsScript)script, (RsAllocation)alloc, slot);
1536    }
1537    rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1538}
1539
1540static void
1541nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
1542{
1543    if (kLogApi) {
1544        ALOGD("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script,
1545              slot, val);
1546    }
1547    rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1548}
1549
1550static jint
1551nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1552{
1553    if (kLogApi) {
1554        ALOGD("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1555    }
1556    int value = 0;
1557    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1558    return value;
1559}
1560
1561static void
1562nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1563{
1564    if (kLogApi) {
1565        ALOGD("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1566              slot, val);
1567    }
1568    rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1569}
1570
1571static void
1572nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1573{
1574    if (kLogApi) {
1575        ALOGD("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1576              slot, val);
1577    }
1578    rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1579}
1580
1581static jlong
1582nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1583{
1584    if (kLogApi) {
1585        ALOGD("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1586    }
1587    jlong value = 0;
1588    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1589    return value;
1590}
1591
1592static void
1593nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
1594{
1595    if (kLogApi) {
1596        ALOGD("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script,
1597              slot, val);
1598    }
1599    rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1600}
1601
1602static jfloat
1603nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1604{
1605    if (kLogApi) {
1606        ALOGD("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1607    }
1608    jfloat value = 0;
1609    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1610    return value;
1611}
1612
1613static void
1614nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
1615{
1616    if (kLogApi) {
1617        ALOGD("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script,
1618              slot, val);
1619    }
1620    rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1621}
1622
1623static jdouble
1624nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1625{
1626    if (kLogApi) {
1627        ALOGD("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1628    }
1629    jdouble value = 0;
1630    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1631    return value;
1632}
1633
1634static void
1635nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1636{
1637    if (kLogApi) {
1638        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1639    }
1640    jint len = _env->GetArrayLength(data);
1641    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1642    rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1643    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1644}
1645
1646static void
1647nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1648{
1649    if (kLogApi) {
1650        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1651    }
1652    jint len = _env->GetArrayLength(data);
1653    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1654    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1655    _env->ReleaseByteArrayElements(data, ptr, 0);
1656}
1657
1658static void
1659nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
1660                jlong elem, jintArray dims)
1661{
1662    if (kLogApi) {
1663        ALOGD("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1664    }
1665    jint len = _env->GetArrayLength(data);
1666    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1667    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1668    jint *dimsPtr = _env->GetIntArrayElements(dims, nullptr);
1669    rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1670                     (const uint32_t*) dimsPtr, dimsLen);
1671    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1672    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1673}
1674
1675
1676static void
1677nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
1678{
1679    if (kLogApi) {
1680        ALOGD("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
1681    }
1682
1683    jint length = _env->GetArrayLength(timeZone);
1684    jbyte* timeZone_ptr;
1685    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1686
1687    rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1688
1689    if (timeZone_ptr) {
1690        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1691    }
1692}
1693
1694static void
1695nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
1696{
1697    if (kLogApi) {
1698        ALOGD("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1699    }
1700    rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
1701}
1702
1703static void
1704nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1705{
1706    if (kLogApi) {
1707        ALOGD("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1708    }
1709    jint len = _env->GetArrayLength(data);
1710    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1711    rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1712    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1713}
1714
1715static void
1716nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
1717               jlongArray ains, jlong aout, jbyteArray params,
1718               jintArray limits)
1719{
1720    if (kLogApi) {
1721        ALOGD("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1722    }
1723
1724    jint   in_len = 0;
1725    jlong *in_ptr = nullptr;
1726
1727    RsAllocation *in_allocs = nullptr;
1728
1729    if (ains != nullptr) {
1730        in_len = _env->GetArrayLength(ains);
1731        in_ptr = _env->GetLongArrayElements(ains, nullptr);
1732
1733        if (sizeof(RsAllocation) == sizeof(jlong)) {
1734            in_allocs = (RsAllocation*)in_ptr;
1735
1736        } else {
1737            // Convert from 64-bit jlong types to the native pointer type.
1738
1739            in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
1740
1741            for (int index = in_len; --index >= 0;) {
1742                in_allocs[index] = (RsAllocation)in_ptr[index];
1743            }
1744        }
1745    }
1746
1747    jint   param_len = 0;
1748    jbyte *param_ptr = nullptr;
1749
1750    if (params != nullptr) {
1751        param_len = _env->GetArrayLength(params);
1752        param_ptr = _env->GetByteArrayElements(params, nullptr);
1753    }
1754
1755    RsScriptCall sc, *sca = nullptr;
1756    uint32_t sc_size = 0;
1757
1758    jint  limit_len = 0;
1759    jint *limit_ptr = nullptr;
1760
1761    if (limits != nullptr) {
1762        limit_len = _env->GetArrayLength(limits);
1763        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
1764
1765        assert(limit_len == 6);
1766        UNUSED(limit_len);  // As the assert might not be compiled.
1767
1768        sc.xStart     = limit_ptr[0];
1769        sc.xEnd       = limit_ptr[1];
1770        sc.yStart     = limit_ptr[2];
1771        sc.yEnd       = limit_ptr[3];
1772        sc.zStart     = limit_ptr[4];
1773        sc.zEnd       = limit_ptr[5];
1774        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
1775        sc.arrayStart = 0;
1776        sc.arrayEnd = 0;
1777        sc.array2Start = 0;
1778        sc.array2End = 0;
1779        sc.array3Start = 0;
1780        sc.array3End = 0;
1781        sc.array4Start = 0;
1782        sc.array4End = 0;
1783
1784        sca = &sc;
1785    }
1786
1787    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
1788                         in_allocs, in_len, (RsAllocation)aout,
1789                         param_ptr, param_len, sca, sc_size);
1790
1791    if (ains != nullptr) {
1792        _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
1793    }
1794
1795    if (params != nullptr) {
1796        _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
1797    }
1798
1799    if (limits != nullptr) {
1800        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
1801    }
1802}
1803
1804// -----------------------------------
1805
1806static jlong
1807nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
1808               jstring resName, jstring cacheDir,
1809               jbyteArray scriptRef, jint length)
1810{
1811    if (kLogApi) {
1812        ALOGD("nScriptCCreate, con(%p)", (RsContext)con);
1813    }
1814
1815    AutoJavaStringToUTF8 resNameUTF(_env, resName);
1816    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1817    jlong ret = 0;
1818    jbyte* script_ptr = nullptr;
1819    jint _exception = 0;
1820    jint remaining;
1821    if (!scriptRef) {
1822        _exception = 1;
1823        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1824        goto exit;
1825    }
1826    if (length < 0) {
1827        _exception = 1;
1828        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1829        goto exit;
1830    }
1831    remaining = _env->GetArrayLength(scriptRef);
1832    if (remaining < length) {
1833        _exception = 1;
1834        //jniThrowException(_env, "java/lang/IllegalArgumentException",
1835        //        "length > script.length - offset");
1836        goto exit;
1837    }
1838    script_ptr = (jbyte *)
1839        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1840
1841    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
1842
1843    ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
1844                                resNameUTF.c_str(), resNameUTF.length(),
1845                                cacheDirUTF.c_str(), cacheDirUTF.length(),
1846                                (const char *)script_ptr, length);
1847
1848exit:
1849    if (script_ptr) {
1850        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1851                _exception ? JNI_ABORT: 0);
1852    }
1853
1854    return (jlong)(uintptr_t)ret;
1855}
1856
1857static jlong
1858nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
1859{
1860    if (kLogApi) {
1861        ALOGD("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id,
1862              (void *)eid);
1863    }
1864    return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1865}
1866
1867static jlong
1868nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
1869{
1870    if (kLogApi) {
1871        ALOGD("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
1872              (void *)sid, slot, sig);
1873    }
1874    return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
1875}
1876
1877static jlong
1878nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1879{
1880    if (kLogApi) {
1881        ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con,
1882              (void *)sid, slot);
1883    }
1884    return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
1885}
1886
1887static jlong
1888nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1889{
1890    if (kLogApi) {
1891        ALOGD("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid,
1892              slot);
1893    }
1894    return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1895}
1896
1897static jlong
1898nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
1899    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
1900{
1901    if (kLogApi) {
1902        ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
1903    }
1904
1905    jint kernelsLen = _env->GetArrayLength(_kernels);
1906    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
1907    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
1908    for(int i = 0; i < kernelsLen; ++i) {
1909        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
1910    }
1911
1912    jint srcLen = _env->GetArrayLength(_src);
1913    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
1914    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
1915    for(int i = 0; i < srcLen; ++i) {
1916        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
1917    }
1918
1919    jint dstkLen = _env->GetArrayLength(_dstk);
1920    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
1921    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
1922    for(int i = 0; i < dstkLen; ++i) {
1923        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
1924    }
1925
1926    jint dstfLen = _env->GetArrayLength(_dstf);
1927    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
1928    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
1929    for(int i = 0; i < dstfLen; ++i) {
1930        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
1931    }
1932
1933    jint typesLen = _env->GetArrayLength(_types);
1934    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
1935    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
1936    for(int i = 0; i < typesLen; ++i) {
1937        typesPtr[i] = (RsType)jTypesPtr[i];
1938    }
1939
1940    jlong id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
1941                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
1942                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
1943                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
1944                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
1945                               (RsType *)typesPtr, typesLen * sizeof(RsType));
1946
1947    free(kernelsPtr);
1948    free(srcPtr);
1949    free(dstkPtr);
1950    free(dstfPtr);
1951    free(typesPtr);
1952    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
1953    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
1954    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
1955    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
1956    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
1957    return id;
1958}
1959
1960static void
1961nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1962{
1963    if (kLogApi) {
1964        ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1965              (void *)gid, (void *)kid, (void *)alloc);
1966    }
1967    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1968}
1969
1970static void
1971nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1972{
1973    if (kLogApi) {
1974        ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1975              (void *)gid, (void *)kid, (void *)alloc);
1976    }
1977    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1978}
1979
1980static void
1981nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
1982{
1983    if (kLogApi) {
1984        ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
1985    }
1986    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
1987}
1988
1989// ---------------------------------------------------------------------------
1990
1991static jlong
1992nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
1993                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
1994                    jboolean depthMask, jboolean ditherEnable,
1995                    jint srcFunc, jint destFunc,
1996                    jint depthFunc)
1997{
1998    if (kLogApi) {
1999        ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
2000    }
2001    return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
2002                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
2003                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
2004}
2005
2006// ---------------------------------------------------------------------------
2007
2008static void
2009nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
2010{
2011    if (kLogApi) {
2012        ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
2013              (RsProgramVertex)vpv, slot, (RsAllocation)a);
2014    }
2015    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
2016}
2017
2018static void
2019nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2020{
2021    if (kLogApi) {
2022        ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2023              (RsProgramFragment)vpf, slot, (RsAllocation)a);
2024    }
2025    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
2026}
2027
2028static void
2029nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2030{
2031    if (kLogApi) {
2032        ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2033              (RsProgramFragment)vpf, slot, (RsSampler)a);
2034    }
2035    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
2036}
2037
2038// ---------------------------------------------------------------------------
2039
2040static jlong
2041nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2042                       jobjectArray texNames, jlongArray params)
2043{
2044    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2045    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2046    jint paramLen = _env->GetArrayLength(params);
2047
2048    int texCount = _env->GetArrayLength(texNames);
2049    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2050    const char ** nameArray = names.c_str();
2051    size_t* sizeArray = names.c_str_len();
2052
2053    if (kLogApi) {
2054        ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2055    }
2056
2057    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2058    for(int i = 0; i < paramLen; ++i) {
2059        paramPtr[i] = (uintptr_t)jParamPtr[i];
2060    }
2061    jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2062                                             nameArray, texCount, sizeArray,
2063                                             paramPtr, paramLen);
2064
2065    free(paramPtr);
2066    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2067    return ret;
2068}
2069
2070
2071// ---------------------------------------------------------------------------
2072
2073static jlong
2074nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2075                     jobjectArray texNames, jlongArray params)
2076{
2077    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2078    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2079    jint paramLen = _env->GetArrayLength(params);
2080
2081    if (kLogApi) {
2082        ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2083    }
2084
2085    int texCount = _env->GetArrayLength(texNames);
2086    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2087    const char ** nameArray = names.c_str();
2088    size_t* sizeArray = names.c_str_len();
2089
2090    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2091    for(int i = 0; i < paramLen; ++i) {
2092        paramPtr[i] = (uintptr_t)jParamPtr[i];
2093    }
2094
2095    jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2096                                           nameArray, texCount, sizeArray,
2097                                           paramPtr, paramLen);
2098
2099    free(paramPtr);
2100    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2101    return ret;
2102}
2103
2104// ---------------------------------------------------------------------------
2105
2106static jlong
2107nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
2108{
2109    if (kLogApi) {
2110        ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
2111              pointSprite, cull);
2112    }
2113    return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
2114}
2115
2116
2117// ---------------------------------------------------------------------------
2118
2119static void
2120nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
2121{
2122    if (kLogApi) {
2123        ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
2124    }
2125    rsContextBindRootScript((RsContext)con, (RsScript)script);
2126}
2127
2128static void
2129nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
2130{
2131    if (kLogApi) {
2132        ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
2133    }
2134    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
2135}
2136
2137static void
2138nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2139{
2140    if (kLogApi) {
2141        ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
2142              (RsProgramFragment)pf);
2143    }
2144    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
2145}
2146
2147static void
2148nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2149{
2150    if (kLogApi) {
2151        ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
2152    }
2153    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
2154}
2155
2156static void
2157nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2158{
2159    if (kLogApi) {
2160        ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
2161    }
2162    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
2163}
2164
2165
2166// ---------------------------------------------------------------------------
2167
2168static jlong
2169nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
2170               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
2171{
2172    if (kLogApi) {
2173        ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
2174    }
2175    return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
2176                                 (RsSamplerValue)magFilter,
2177                                 (RsSamplerValue)minFilter,
2178                                 (RsSamplerValue)wrapS,
2179                                 (RsSamplerValue)wrapT,
2180                                 (RsSamplerValue)wrapR,
2181                                 aniso);
2182}
2183
2184// ---------------------------------------------------------------------------
2185
2186static jlong
2187nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jlong _loop, jfloat q) {
2188    if (kLogApi) {
2189        ALOGD("nPathCreate, con(%p)", (RsContext)con);
2190    }
2191
2192    jlong id = (jlong)(uintptr_t)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
2193                                   (RsAllocation)_vtx,
2194                                   (RsAllocation)_loop, q);
2195    return id;
2196}
2197
2198static jlong
2199nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
2200{
2201    if (kLogApi) {
2202        ALOGD("nMeshCreate, con(%p)", (RsContext)con);
2203    }
2204
2205    jint vtxLen = _env->GetArrayLength(_vtx);
2206    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
2207    RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
2208    for(int i = 0; i < vtxLen; ++i) {
2209        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
2210    }
2211
2212    jint idxLen = _env->GetArrayLength(_idx);
2213    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
2214    RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
2215    for(int i = 0; i < idxLen; ++i) {
2216        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
2217    }
2218
2219    jint primLen = _env->GetArrayLength(_prim);
2220    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
2221
2222    jlong id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
2223                               (RsAllocation *)vtxPtr, vtxLen,
2224                               (RsAllocation *)idxPtr, idxLen,
2225                               (uint32_t *)primPtr, primLen);
2226
2227    free(vtxPtr);
2228    free(idxPtr);
2229    _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
2230    _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
2231    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
2232    return id;
2233}
2234
2235static jint
2236nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2237{
2238    if (kLogApi) {
2239        ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2240    }
2241    jint vtxCount = 0;
2242    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
2243    return vtxCount;
2244}
2245
2246static jint
2247nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2248{
2249    if (kLogApi) {
2250        ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2251    }
2252    jint idxCount = 0;
2253    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
2254    return idxCount;
2255}
2256
2257static void
2258nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
2259{
2260    if (kLogApi) {
2261        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2262    }
2263
2264    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
2265    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
2266
2267    for(jint i = 0; i < numVtxIDs; i ++) {
2268        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2269        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
2270    }
2271
2272    free(allocs);
2273}
2274
2275static void
2276nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
2277{
2278    if (kLogApi) {
2279        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2280    }
2281
2282    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
2283    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
2284
2285    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
2286
2287    for(jint i = 0; i < numIndices; i ++) {
2288        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2289        const jint prim = (jint)prims[i];
2290        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
2291        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
2292    }
2293
2294    free(allocs);
2295    free(prims);
2296}
2297
2298static jint
2299nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
2300    return (jint)sizeof(void*);
2301}
2302
2303
2304// ---------------------------------------------------------------------------
2305
2306
2307static const char *classPathName = "android/renderscript/RenderScript";
2308
2309static JNINativeMethod methods[] = {
2310{"_nInit",                         "()V",                                     (void*)_nInit },
2311
2312{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
2313{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
2314{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
2315{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
2316{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
2317{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
2318
2319{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
2320{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
2321
2322
2323// All methods below are thread protected in java.
2324{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
2325{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
2326{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
2327{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
2328{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
2329{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
2330{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
2331{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
2332{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
2333{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
2334{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
2335{"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
2336{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
2337{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
2338{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
2339{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
2340{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
2341
2342{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
2343{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
2344{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
2345{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
2346{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
2347{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
2348
2349{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
2350{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
2351{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
2352
2353{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
2354{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
2355{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
2356{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
2357
2358{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
2359{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
2360
2361{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
2362{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
2363{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
2364{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
2365
2366{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
2367{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
2368
2369{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
2370{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
2371{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
2372{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
2373{"rsnAllocationIoReceive",           "(JJ)V",                                 (void*)nAllocationIoReceive },
2374{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
2375{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
2376{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
2377{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
2378{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
2379{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
2380{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
2381{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
2382{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
2383{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
2384{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationRead3D },
2385{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
2386{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
2387{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
2388
2389{"rsnAllocationAdapterCreate",       "(JJJ)J",                                (void*)nAllocationAdapterCreate },
2390{"rsnAllocationAdapterOffset",       "(JJIIIIIIIII)V",                        (void*)nAllocationAdapterOffset },
2391
2392{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
2393{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
2394{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
2395{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
2396
2397{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
2398
2399{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
2400{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
2401{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
2402{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
2403{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
2404{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
2405{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
2406{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
2407{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
2408{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
2409{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
2410{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
2411
2412{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
2413{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
2414{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
2415{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
2416{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
2417{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
2418{"rsnScriptGroup2Create",            "(JLjava/lang/String;[J)J",               (void*)nScriptGroup2Create },
2419{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
2420{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
2421{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
2422{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
2423
2424{"rsnScriptIntrinsicBLAS_Single",    "(JJIIIIIIIIIFJJFJIIII)V",               (void*)nScriptIntrinsicBLAS_Single },
2425{"rsnScriptIntrinsicBLAS_Double",    "(JJIIIIIIIIIDJJDJIIII)V",               (void*)nScriptIntrinsicBLAS_Double },
2426{"rsnScriptIntrinsicBLAS_Complex",   "(JJIIIIIIIIIFFJJFFJIIII)V",             (void*)nScriptIntrinsicBLAS_Complex },
2427{"rsnScriptIntrinsicBLAS_Z",         "(JJIIIIIIIIIDDJJDDJIIII)V",             (void*)nScriptIntrinsicBLAS_Z },
2428
2429{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
2430
2431{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
2432{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
2433{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
2434
2435{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
2436{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
2437{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
2438
2439{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
2440{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
2441{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
2442{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
2443{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
2444
2445{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
2446
2447{"rsnPathCreate",                    "(JIZJJF)J",                             (void*)nPathCreate },
2448{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
2449
2450{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
2451{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
2452{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
2453{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
2454
2455{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
2456};
2457
2458static int registerFuncs(JNIEnv *_env)
2459{
2460    return android::AndroidRuntime::registerNativeMethods(
2461            _env, classPathName, methods, NELEM(methods));
2462}
2463
2464// ---------------------------------------------------------------------------
2465
2466jint JNI_OnLoad(JavaVM* vm, void* reserved)
2467{
2468    JNIEnv* env = nullptr;
2469    jint result = -1;
2470
2471    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
2472        ALOGE("ERROR: GetEnv failed\n");
2473        goto bail;
2474    }
2475    assert(env != nullptr);
2476
2477    if (registerFuncs(env) < 0) {
2478        ALOGE("ERROR: Renderscript native registration failed\n");
2479        goto bail;
2480    }
2481
2482    /* success -- return valid version number */
2483    result = JNI_VERSION_1_4;
2484
2485bail:
2486    return result;
2487}
2488