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