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