android_renderscript_RenderScript.cpp revision 073f36c6c1bc937a55393f7fe9a21b95e822bfda
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
687static void
688nContextSetCacheDir(JNIEnv *_env, jobject _this, jlong con, jstring cacheDir)
689{
690    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
691
692    if (kLogApi) {
693        ALOGD("ContextSetCacheDir, con(%p), cacheDir(%s)", (RsContext)con, cacheDirUTF.c_str());
694    }
695    rsContextSetCacheDir((RsContext)con, cacheDirUTF.c_str(), cacheDirUTF.length());
696}
697
698
699
700static void
701nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd)
702{
703    if (kLogApi) {
704        ALOGD("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", (RsContext)con,
705              width, height, (Surface *)wnd);
706    }
707
708    ANativeWindow * window = nullptr;
709    if (wnd == nullptr) {
710
711    } else {
712        window = android_view_Surface_getNativeWindow(_env, wnd).get();
713    }
714
715    rsContextSetSurface((RsContext)con, width, height, window);
716}
717
718static void
719nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
720{
721    if (kLogApi) {
722        ALOGD("nContextDestroy, con(%p)", (RsContext)con);
723    }
724    rsContextDestroy((RsContext)con);
725}
726
727static void
728nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
729{
730    if (kLogApi) {
731        ALOGD("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
732    }
733    rsContextDump((RsContext)con, bits);
734}
735
736static void
737nContextPause(JNIEnv *_env, jobject _this, jlong con)
738{
739    if (kLogApi) {
740        ALOGD("nContextPause, con(%p)", (RsContext)con);
741    }
742    rsContextPause((RsContext)con);
743}
744
745static void
746nContextResume(JNIEnv *_env, jobject _this, jlong con)
747{
748    if (kLogApi) {
749        ALOGD("nContextResume, con(%p)", (RsContext)con);
750    }
751    rsContextResume((RsContext)con);
752}
753
754
755static jstring
756nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
757{
758    if (kLogApi) {
759        ALOGD("nContextGetErrorMessage, con(%p)", (RsContext)con);
760    }
761    char buf[1024];
762
763    size_t receiveLen;
764    uint32_t subID;
765    int id = rsContextGetMessage((RsContext)con,
766                                 buf, sizeof(buf),
767                                 &receiveLen, sizeof(receiveLen),
768                                 &subID, sizeof(subID));
769    if (!id && receiveLen) {
770        ALOGV("message receive buffer too small.  %zu", receiveLen);
771    }
772    return _env->NewStringUTF(buf);
773}
774
775static jint
776nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
777{
778    jint len = _env->GetArrayLength(data);
779    if (kLogApi) {
780        ALOGD("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
781    }
782    jint *ptr = _env->GetIntArrayElements(data, nullptr);
783    size_t receiveLen;
784    uint32_t subID;
785    int id = rsContextGetMessage((RsContext)con,
786                                 ptr, len * 4,
787                                 &receiveLen, sizeof(receiveLen),
788                                 &subID, sizeof(subID));
789    if (!id && receiveLen) {
790        ALOGV("message receive buffer too small.  %zu", receiveLen);
791    }
792    _env->ReleaseIntArrayElements(data, ptr, 0);
793    return (jint)id;
794}
795
796static jint
797nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
798{
799    if (kLogApi) {
800        ALOGD("nContextPeekMessage, con(%p)", (RsContext)con);
801    }
802    jint *auxDataPtr = _env->GetIntArrayElements(auxData, nullptr);
803    size_t receiveLen;
804    uint32_t subID;
805    int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
806                                  &subID, sizeof(subID));
807    auxDataPtr[0] = (jint)subID;
808    auxDataPtr[1] = (jint)receiveLen;
809    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
810    return (jint)id;
811}
812
813static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
814{
815    if (kLogApi) {
816        ALOGD("nContextInitToClient, con(%p)", (RsContext)con);
817    }
818    rsContextInitToClient((RsContext)con);
819}
820
821static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
822{
823    if (kLogApi) {
824        ALOGD("nContextDeinitToClient, con(%p)", (RsContext)con);
825    }
826    rsContextDeinitToClient((RsContext)con);
827}
828
829static void
830nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
831{
832    jint *ptr = nullptr;
833    jint len = 0;
834    if (data) {
835        len = _env->GetArrayLength(data);
836        ptr = _env->GetIntArrayElements(data, nullptr);
837    }
838    if (kLogApi) {
839        ALOGD("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
840    }
841    rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
842    if (data) {
843        _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
844    }
845}
846
847
848
849static jlong
850nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm,
851               jint size)
852{
853    if (kLogApi) {
854        ALOGD("nElementCreate, con(%p), type(%" PRId64 "), kind(%i), norm(%i), size(%i)", (RsContext)con,
855              type, kind, norm, size);
856    }
857    return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind,
858                                             norm, size);
859}
860
861static jlong
862nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
863                jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
864{
865    int fieldCount = _env->GetArrayLength(_ids);
866    if (kLogApi) {
867        ALOGD("nElementCreate2, con(%p)", (RsContext)con);
868    }
869
870    jlong *jIds = _env->GetLongArrayElements(_ids, nullptr);
871    jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, nullptr);
872
873    RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
874    uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
875
876    for(int i = 0; i < fieldCount; i ++) {
877        ids[i] = (RsElement)jIds[i];
878        arraySizes[i] = (uint32_t)jArraySizes[i];
879    }
880
881    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
882
883    const char **nameArray = names.c_str();
884    size_t *sizeArray = names.c_str_len();
885
886    jlong id = (jlong)(uintptr_t)rsElementCreate2((RsContext)con,
887                                     (const RsElement *)ids, fieldCount,
888                                     nameArray, fieldCount * sizeof(size_t),  sizeArray,
889                                     (const uint32_t *)arraySizes, fieldCount);
890
891    free(ids);
892    free(arraySizes);
893    _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
894    _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
895
896    return (jlong)(uintptr_t)id;
897}
898
899static void
900nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData)
901{
902    int dataSize = _env->GetArrayLength(_elementData);
903    if (kLogApi) {
904        ALOGD("nElementGetNativeData, con(%p)", (RsContext)con);
905    }
906
907    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
908    assert(dataSize == 5);
909
910    uintptr_t elementData[5];
911    rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize);
912
913    for(jint i = 0; i < dataSize; i ++) {
914        const jint data = (jint)elementData[i];
915        _env->SetIntArrayRegion(_elementData, i, 1, &data);
916    }
917}
918
919
920static void
921nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
922                       jlongArray _IDs,
923                       jobjectArray _names,
924                       jintArray _arraySizes)
925{
926    uint32_t dataSize = _env->GetArrayLength(_IDs);
927    if (kLogApi) {
928        ALOGD("nElementGetSubElements, con(%p)", (RsContext)con);
929    }
930
931    uintptr_t *ids = (uintptr_t*)malloc(dataSize * sizeof(uintptr_t));
932    const char **names = (const char **)malloc(dataSize * sizeof(const char *));
933    uint32_t *arraySizes = (uint32_t *)malloc(dataSize * sizeof(uint32_t));
934
935    rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
936                             (uint32_t)dataSize);
937
938    for(uint32_t i = 0; i < dataSize; i++) {
939        const jlong id = (jlong)(uintptr_t)ids[i];
940        const jint arraySize = (jint)arraySizes[i];
941        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
942        _env->SetLongArrayRegion(_IDs, i, 1, &id);
943        _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
944    }
945
946    free(ids);
947    free(names);
948    free(arraySizes);
949}
950
951// -----------------------------------
952
953static jlong
954nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
955            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
956{
957    if (kLogApi) {
958        ALOGD("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
959              (RsContext)con, (void*)eid, dimx, dimy, dimz, mips, faces, yuv);
960    }
961
962    return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips,
963                                          faces, yuv);
964}
965
966static void
967nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jlongArray _typeData)
968{
969    // We are packing 6 items: mDimX; mDimY; mDimZ;
970    // mDimLOD; mDimFaces; mElement; into typeData
971    int elementCount = _env->GetArrayLength(_typeData);
972
973    assert(elementCount == 6);
974    if (kLogApi) {
975        ALOGD("nTypeGetNativeData, con(%p)", (RsContext)con);
976    }
977
978    uintptr_t typeData[6];
979    rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
980
981    for(jint i = 0; i < elementCount; i ++) {
982        const jlong data = (jlong)(uintptr_t)typeData[i];
983        _env->SetLongArrayRegion(_typeData, i, 1, &data);
984    }
985}
986
987// -----------------------------------
988
989static jlong
990nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
991                       jlong pointer)
992{
993    if (kLogApi) {
994        ALOGD("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
995              (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
996    }
997    return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type,
998                                                      (RsAllocationMipmapControl)mips,
999                                                      (uint32_t)usage, (uintptr_t)pointer);
1000}
1001
1002static void
1003nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
1004{
1005    if (kLogApi) {
1006        ALOGD("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a,
1007              bits);
1008    }
1009    rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
1010}
1011
1012static jobject
1013nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
1014{
1015    if (kLogApi) {
1016        ALOGD("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1017    }
1018
1019    IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con,
1020                                                                                 (RsAllocation)a);
1021    sp<IGraphicBufferProducer> bp = v;
1022    v->decStrong(nullptr);
1023
1024    jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp);
1025    return o;
1026}
1027
1028static void
1029nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
1030{
1031    if (kLogApi) {
1032        ALOGD("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)", (RsContext)con,
1033              (RsAllocation)alloc, (Surface *)sur);
1034    }
1035
1036    sp<Surface> s;
1037    if (sur != 0) {
1038        s = android_view_Surface_getSurface(_env, sur);
1039    }
1040
1041    rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc,
1042                           static_cast<ANativeWindow *>(s.get()));
1043}
1044
1045static void
1046nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1047{
1048    if (kLogApi) {
1049        ALOGD("nAllocationIoSend, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1050    }
1051    rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
1052}
1053
1054static void
1055nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1056{
1057    if (kLogApi) {
1058        ALOGD("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1059    }
1060    rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
1061}
1062
1063
1064static void
1065nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1066{
1067    if (kLogApi) {
1068        ALOGD("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
1069    }
1070    rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
1071}
1072
1073static jlong
1074nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
1075                            jobject jbitmap, jint usage)
1076{
1077    SkBitmap bitmap;
1078    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1079
1080    bitmap.lockPixels();
1081    const void* ptr = bitmap.getPixels();
1082    jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
1083                                                  (RsType)type, (RsAllocationMipmapControl)mip,
1084                                                  ptr, bitmap.getSize(), usage);
1085    bitmap.unlockPixels();
1086    return id;
1087}
1088
1089static jlong
1090nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
1091                                        jint mip, jobject jbitmap, jint usage)
1092{
1093    SkBitmap bitmap;
1094    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1095
1096    bitmap.lockPixels();
1097    const void* ptr = bitmap.getPixels();
1098    jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
1099                                            (RsType)type, (RsAllocationMipmapControl)mip,
1100                                            (uint32_t)usage, (uintptr_t)ptr);
1101    bitmap.unlockPixels();
1102    return id;
1103}
1104
1105static jlong
1106nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
1107                                jobject jbitmap, jint usage)
1108{
1109    SkBitmap bitmap;
1110    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1111
1112    bitmap.lockPixels();
1113    const void* ptr = bitmap.getPixels();
1114    jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
1115                                                      (RsType)type, (RsAllocationMipmapControl)mip,
1116                                                      ptr, bitmap.getSize(), usage);
1117    bitmap.unlockPixels();
1118    return id;
1119}
1120
1121static void
1122nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1123{
1124    SkBitmap bitmap;
1125    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1126    int w = bitmap.width();
1127    int h = bitmap.height();
1128
1129    bitmap.lockPixels();
1130    const void* ptr = bitmap.getPixels();
1131    rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
1132                       0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
1133                       w, h, ptr, bitmap.getSize(), 0);
1134    bitmap.unlockPixels();
1135}
1136
1137static void
1138nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1139{
1140    SkBitmap bitmap;
1141    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1142
1143    bitmap.lockPixels();
1144    void* ptr = bitmap.getPixels();
1145    rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
1146    bitmap.unlockPixels();
1147    bitmap.notifyPixelsChanged();
1148}
1149
1150// Copies from the Java object data into the Allocation pointed to by _alloc.
1151static void
1152nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1153                  jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
1154                  jboolean usePadding)
1155{
1156    RsAllocation *alloc = (RsAllocation *)_alloc;
1157    if (kLogApi) {
1158        ALOGD("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1159              "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
1160              dataType);
1161    }
1162    PER_ARRAY_TYPE(nullptr, rsAllocation1DData, true,
1163                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1164}
1165
1166static void
1167nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1168                       jint xoff, jint yoff, jint zoff,
1169                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1170{
1171    jint len = _env->GetArrayLength(data);
1172    if (kLogApi) {
1173        ALOGD("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1174              "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1175              sizeBytes);
1176    }
1177    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1178    rsAllocationElementData((RsContext)con, (RsAllocation)alloc,
1179                            xoff, yoff, zoff,
1180                            lod, ptr, sizeBytes, compIdx);
1181    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1182}
1183
1184
1185// Copies from the Java object data into the Allocation pointed to by _alloc.
1186static void
1187nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1188                  jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
1189                  jboolean usePadding)
1190{
1191    RsAllocation *alloc = (RsAllocation *)_alloc;
1192    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1193    if (kLogApi) {
1194        ALOGD("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1195              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1196    }
1197    int count = w * h;
1198    PER_ARRAY_TYPE(nullptr, rsAllocation2DData, true,
1199                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1200}
1201
1202// Copies from the Allocation pointed to by srcAlloc into the Allocation
1203// pointed to by dstAlloc.
1204static void
1205nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
1206                        jlong dstAlloc, jint dstXoff, jint dstYoff,
1207                        jint dstMip, jint dstFace,
1208                        jint width, jint height,
1209                        jlong srcAlloc, jint srcXoff, jint srcYoff,
1210                        jint srcMip, jint srcFace)
1211{
1212    if (kLogApi) {
1213        ALOGD("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1214              " dstMip(%i), dstFace(%i), width(%i), height(%i),"
1215              " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
1216              (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
1217              width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
1218    }
1219
1220    rsAllocationCopy2DRange((RsContext)con,
1221                            (RsAllocation)dstAlloc,
1222                            dstXoff, dstYoff,
1223                            dstMip, dstFace,
1224                            width, height,
1225                            (RsAllocation)srcAlloc,
1226                            srcXoff, srcYoff,
1227                            srcMip, srcFace);
1228}
1229
1230// Copies from the Java object data into the Allocation pointed to by _alloc.
1231static void
1232nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1233                  jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
1234                  jint mSize, jboolean usePadding)
1235{
1236    RsAllocation *alloc = (RsAllocation *)_alloc;
1237    if (kLogApi) {
1238        ALOGD("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1239              " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1240              lod, w, h, d, sizeBytes);
1241    }
1242    int count = w * h * d;
1243    PER_ARRAY_TYPE(nullptr, rsAllocation3DData, true,
1244                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1245}
1246
1247// Copies from the Allocation pointed to by srcAlloc into the Allocation
1248// pointed to by dstAlloc.
1249static void
1250nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
1251                        jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
1252                        jint dstMip,
1253                        jint width, jint height, jint depth,
1254                        jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
1255                        jint srcMip)
1256{
1257    if (kLogApi) {
1258        ALOGD("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1259              " dstMip(%i), width(%i), height(%i),"
1260              " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
1261              (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip,
1262              width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip);
1263    }
1264
1265    rsAllocationCopy3DRange((RsContext)con,
1266                            (RsAllocation)dstAlloc,
1267                            dstXoff, dstYoff, dstZoff, dstMip,
1268                            width, height, depth,
1269                            (RsAllocation)srcAlloc,
1270                            srcXoff, srcYoff, srcZoff, srcMip);
1271}
1272
1273
1274// Copies from the Allocation pointed to by _alloc into the Java object data.
1275static void
1276nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
1277                jint mSize, jboolean usePadding)
1278{
1279    RsAllocation *alloc = (RsAllocation *)_alloc;
1280    if (kLogApi) {
1281        ALOGD("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1282    }
1283    int count = 0;
1284    PER_ARRAY_TYPE(0, rsAllocationRead, false,
1285                   (RsContext)con, alloc, ptr, len * typeBytes);
1286}
1287
1288// Copies from the Allocation pointed to by _alloc into the Java object data.
1289static void
1290nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1291                  jint count, jobject data, jint sizeBytes, jint dataType,
1292                  jint mSize, jboolean usePadding)
1293{
1294    RsAllocation *alloc = (RsAllocation *)_alloc;
1295    if (kLogApi) {
1296        ALOGD("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1297              "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
1298    }
1299    PER_ARRAY_TYPE(0, rsAllocation1DRead, false,
1300                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1301}
1302
1303// Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
1304static void
1305nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1306                       jint xoff, jint yoff, jint zoff,
1307                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1308{
1309    jint len = _env->GetArrayLength(data);
1310    if (kLogApi) {
1311        ALOGD("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1312              "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1313              sizeBytes);
1314    }
1315    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1316    rsAllocationElementRead((RsContext)con, (RsAllocation)alloc,
1317                            xoff, yoff, zoff,
1318                            lod, ptr, sizeBytes, compIdx);
1319    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1320}
1321
1322// Copies from the Allocation pointed to by _alloc into the Java object data.
1323static void
1324nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1325                  jint w, jint h, jobject data, jint sizeBytes, jint dataType,
1326                  jint mSize, jboolean usePadding)
1327{
1328    RsAllocation *alloc = (RsAllocation *)_alloc;
1329    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1330    if (kLogApi) {
1331        ALOGD("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1332              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1333    }
1334    int count = w * h;
1335    PER_ARRAY_TYPE(0, rsAllocation2DRead, false,
1336                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1337}
1338
1339// Copies from the Allocation pointed to by _alloc into the Java object data.
1340static void
1341nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1342                  jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
1343                  jint mSize, jboolean usePadding)
1344{
1345    RsAllocation *alloc = (RsAllocation *)_alloc;
1346    if (kLogApi) {
1347        ALOGD("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1348              " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1349              lod, w, h, d, sizeBytes);
1350    }
1351    int count = w * h * d;
1352    PER_ARRAY_TYPE(nullptr, rsAllocation3DRead, false,
1353                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1354}
1355
1356static jlong
1357nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
1358{
1359    if (kLogApi) {
1360        ALOGD("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1361    }
1362    return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
1363}
1364
1365static void
1366nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
1367{
1368    if (kLogApi) {
1369        ALOGD("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
1370              (RsAllocation)alloc, dimX);
1371    }
1372    rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
1373}
1374
1375
1376static jlong
1377nAllocationAdapterCreate(JNIEnv *_env, jobject _this, jlong con, jlong basealloc, jlong type)
1378{
1379    if (kLogApi) {
1380        ALOGD("nAllocationAdapterCreate, con(%p), base(%p), type(%p)",
1381              (RsContext)con, (RsAllocation)basealloc, (RsElement)type);
1382    }
1383    return (jlong)(uintptr_t) rsAllocationAdapterCreate((RsContext)con, (RsType)type,
1384                                                        (RsAllocation)basealloc);
1385
1386}
1387
1388static void
1389nAllocationAdapterOffset(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1390                        jint x, jint y, jint z, jint face, jint lod,
1391                        jint a1, jint a2, jint a3, jint a4)
1392{
1393    uint32_t params[] = {
1394        (uint32_t)x, (uint32_t)y, (uint32_t)z, (uint32_t)face,
1395        (uint32_t)lod, (uint32_t)a1, (uint32_t)a2, (uint32_t)a3, (uint32_t)a4
1396    };
1397    if (kLogApi) {
1398        ALOGD("nAllocationAdapterOffset, con(%p), alloc(%p), x(%i), y(%i), z(%i), face(%i), lod(%i), arrays(%i %i %i %i)",
1399              (RsContext)con, (RsAllocation)alloc, x, y, z, face, lod, a1, a2, a3, a4);
1400    }
1401    rsAllocationAdapterOffset((RsContext)con, (RsAllocation)alloc,
1402                              params, sizeof(params));
1403}
1404
1405
1406// -----------------------------------
1407
1408static jlong
1409nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset)
1410{
1411    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1412    ALOGV("______nFileA3D %p", asset);
1413
1414    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
1415    return id;
1416}
1417
1418static jlong
1419nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
1420{
1421    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1422    if (mgr == nullptr) {
1423        return 0;
1424    }
1425
1426    AutoJavaStringToUTF8 str(_env, _path);
1427    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1428    if (asset == nullptr) {
1429        return 0;
1430    }
1431
1432    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
1433    return id;
1434}
1435
1436static jlong
1437nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
1438{
1439    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1440    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
1441
1442    return id;
1443}
1444
1445static jint
1446nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D)
1447{
1448    int32_t numEntries = 0;
1449    rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D);
1450    return (jint)numEntries;
1451}
1452
1453static void
1454nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
1455{
1456    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1457    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
1458
1459    rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
1460
1461    for(jint i = 0; i < numEntries; i ++) {
1462        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
1463        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
1464    }
1465
1466    free(fileEntries);
1467}
1468
1469static jlong
1470nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
1471{
1472    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1473    jlong id = (jlong)(uintptr_t)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
1474    return id;
1475}
1476
1477// -----------------------------------
1478
1479static jlong
1480nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con,
1481                    jstring fileName, jfloat fontSize, jint dpi)
1482{
1483    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1484    jlong id = (jlong)(uintptr_t)rsFontCreateFromFile((RsContext)con,
1485                                         fileNameUTF.c_str(), fileNameUTF.length(),
1486                                         fontSize, dpi);
1487
1488    return id;
1489}
1490
1491static jlong
1492nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con,
1493                           jstring name, jfloat fontSize, jint dpi, jlong native_asset)
1494{
1495    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1496    AutoJavaStringToUTF8 nameUTF(_env, name);
1497
1498    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1499                                           nameUTF.c_str(), nameUTF.length(),
1500                                           fontSize, dpi,
1501                                           asset->getBuffer(false), asset->getLength());
1502    return id;
1503}
1504
1505static jlong
1506nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
1507                     jfloat fontSize, jint dpi)
1508{
1509    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1510    if (mgr == nullptr) {
1511        return 0;
1512    }
1513
1514    AutoJavaStringToUTF8 str(_env, _path);
1515    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1516    if (asset == nullptr) {
1517        return 0;
1518    }
1519
1520    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1521                                           str.c_str(), str.length(),
1522                                           fontSize, dpi,
1523                                           asset->getBuffer(false), asset->getLength());
1524    delete asset;
1525    return id;
1526}
1527
1528// -----------------------------------
1529
1530static void
1531nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
1532{
1533    if (kLogApi) {
1534        ALOGD("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con,
1535              (RsScript)script, (RsAllocation)alloc, slot);
1536    }
1537    rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1538}
1539
1540static void
1541nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
1542{
1543    if (kLogApi) {
1544        ALOGD("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script,
1545              slot, val);
1546    }
1547    rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1548}
1549
1550static jint
1551nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1552{
1553    if (kLogApi) {
1554        ALOGD("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1555    }
1556    int value = 0;
1557    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1558    return value;
1559}
1560
1561static void
1562nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1563{
1564    if (kLogApi) {
1565        ALOGD("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1566              slot, val);
1567    }
1568    rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1569}
1570
1571static void
1572nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1573{
1574    if (kLogApi) {
1575        ALOGD("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1576              slot, val);
1577    }
1578    rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1579}
1580
1581static jlong
1582nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1583{
1584    if (kLogApi) {
1585        ALOGD("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1586    }
1587    jlong value = 0;
1588    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1589    return value;
1590}
1591
1592static void
1593nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
1594{
1595    if (kLogApi) {
1596        ALOGD("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script,
1597              slot, val);
1598    }
1599    rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1600}
1601
1602static jfloat
1603nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1604{
1605    if (kLogApi) {
1606        ALOGD("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1607    }
1608    jfloat value = 0;
1609    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1610    return value;
1611}
1612
1613static void
1614nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
1615{
1616    if (kLogApi) {
1617        ALOGD("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script,
1618              slot, val);
1619    }
1620    rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1621}
1622
1623static jdouble
1624nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1625{
1626    if (kLogApi) {
1627        ALOGD("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1628    }
1629    jdouble value = 0;
1630    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1631    return value;
1632}
1633
1634static void
1635nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1636{
1637    if (kLogApi) {
1638        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1639    }
1640    jint len = _env->GetArrayLength(data);
1641    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1642    rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1643    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1644}
1645
1646static void
1647nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1648{
1649    if (kLogApi) {
1650        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1651    }
1652    jint len = _env->GetArrayLength(data);
1653    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1654    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1655    _env->ReleaseByteArrayElements(data, ptr, 0);
1656}
1657
1658static void
1659nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
1660                jlong elem, jintArray dims)
1661{
1662    if (kLogApi) {
1663        ALOGD("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1664    }
1665    jint len = _env->GetArrayLength(data);
1666    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1667    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1668    jint *dimsPtr = _env->GetIntArrayElements(dims, nullptr);
1669    rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1670                     (const uint32_t*) dimsPtr, dimsLen);
1671    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1672    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1673}
1674
1675
1676static void
1677nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
1678{
1679    if (kLogApi) {
1680        ALOGD("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
1681    }
1682
1683    jint length = _env->GetArrayLength(timeZone);
1684    jbyte* timeZone_ptr;
1685    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1686
1687    rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1688
1689    if (timeZone_ptr) {
1690        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1691    }
1692}
1693
1694static void
1695nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
1696{
1697    if (kLogApi) {
1698        ALOGD("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1699    }
1700    rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
1701}
1702
1703static void
1704nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1705{
1706    if (kLogApi) {
1707        ALOGD("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1708    }
1709    jint len = _env->GetArrayLength(data);
1710    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1711    rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1712    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1713}
1714
1715static void
1716nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
1717               jlongArray ains, jlong aout, jbyteArray params,
1718               jintArray limits)
1719{
1720    if (kLogApi) {
1721        ALOGD("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1722    }
1723
1724    jint   in_len = 0;
1725    jlong *in_ptr = nullptr;
1726
1727    RsAllocation *in_allocs = nullptr;
1728
1729    if (ains != nullptr) {
1730        in_len = _env->GetArrayLength(ains);
1731        in_ptr = _env->GetLongArrayElements(ains, nullptr);
1732
1733        if (sizeof(RsAllocation) == sizeof(jlong)) {
1734            in_allocs = (RsAllocation*)in_ptr;
1735
1736        } else {
1737            // Convert from 64-bit jlong types to the native pointer type.
1738
1739            in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
1740
1741            for (int index = in_len; --index >= 0;) {
1742                in_allocs[index] = (RsAllocation)in_ptr[index];
1743            }
1744        }
1745    }
1746
1747    jint   param_len = 0;
1748    jbyte *param_ptr = nullptr;
1749
1750    if (params != nullptr) {
1751        param_len = _env->GetArrayLength(params);
1752        param_ptr = _env->GetByteArrayElements(params, nullptr);
1753    }
1754
1755    RsScriptCall sc, *sca = nullptr;
1756    uint32_t sc_size = 0;
1757
1758    jint  limit_len = 0;
1759    jint *limit_ptr = nullptr;
1760
1761    if (limits != nullptr) {
1762        limit_len = _env->GetArrayLength(limits);
1763        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
1764
1765        assert(limit_len == 6);
1766        UNUSED(limit_len);  // As the assert might not be compiled.
1767
1768        sc.xStart     = limit_ptr[0];
1769        sc.xEnd       = limit_ptr[1];
1770        sc.yStart     = limit_ptr[2];
1771        sc.yEnd       = limit_ptr[3];
1772        sc.zStart     = limit_ptr[4];
1773        sc.zEnd       = limit_ptr[5];
1774        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
1775        sc.arrayStart = 0;
1776        sc.arrayEnd = 0;
1777        sc.array2Start = 0;
1778        sc.array2End = 0;
1779        sc.array3Start = 0;
1780        sc.array3End = 0;
1781        sc.array4Start = 0;
1782        sc.array4End = 0;
1783
1784        sca = &sc;
1785    }
1786
1787    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
1788                         in_allocs, in_len, (RsAllocation)aout,
1789                         param_ptr, param_len, sca, sc_size);
1790
1791    if (ains != nullptr) {
1792        _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
1793    }
1794
1795    if (params != nullptr) {
1796        _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
1797    }
1798
1799    if (limits != nullptr) {
1800        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
1801    }
1802}
1803
1804// -----------------------------------
1805
1806static jlong
1807nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
1808               jstring resName, jstring cacheDir,
1809               jbyteArray scriptRef, jint length)
1810{
1811    if (kLogApi) {
1812        ALOGD("nScriptCCreate, con(%p)", (RsContext)con);
1813    }
1814
1815    AutoJavaStringToUTF8 resNameUTF(_env, resName);
1816    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1817    jlong ret = 0;
1818    jbyte* script_ptr = nullptr;
1819    jint _exception = 0;
1820    jint remaining;
1821    if (!scriptRef) {
1822        _exception = 1;
1823        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1824        goto exit;
1825    }
1826    if (length < 0) {
1827        _exception = 1;
1828        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1829        goto exit;
1830    }
1831    remaining = _env->GetArrayLength(scriptRef);
1832    if (remaining < length) {
1833        _exception = 1;
1834        //jniThrowException(_env, "java/lang/IllegalArgumentException",
1835        //        "length > script.length - offset");
1836        goto exit;
1837    }
1838    script_ptr = (jbyte *)
1839        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1840
1841    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
1842
1843    ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
1844                                resNameUTF.c_str(), resNameUTF.length(),
1845                                cacheDirUTF.c_str(), cacheDirUTF.length(),
1846                                (const char *)script_ptr, length);
1847
1848exit:
1849    if (script_ptr) {
1850        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1851                _exception ? JNI_ABORT: 0);
1852    }
1853
1854    return (jlong)(uintptr_t)ret;
1855}
1856
1857static jlong
1858nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
1859{
1860    if (kLogApi) {
1861        ALOGD("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id,
1862              (void *)eid);
1863    }
1864    return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1865}
1866
1867static jlong
1868nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
1869{
1870    if (kLogApi) {
1871        ALOGD("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
1872              (void *)sid, slot, sig);
1873    }
1874    return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
1875}
1876
1877static jlong
1878nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1879{
1880    if (kLogApi) {
1881        ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con,
1882              (void *)sid, slot);
1883    }
1884    return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
1885}
1886
1887static jlong
1888nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1889{
1890    if (kLogApi) {
1891        ALOGD("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid,
1892              slot);
1893    }
1894    return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1895}
1896
1897static jlong
1898nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
1899    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
1900{
1901    if (kLogApi) {
1902        ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
1903    }
1904
1905    jint kernelsLen = _env->GetArrayLength(_kernels);
1906    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
1907    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
1908    for(int i = 0; i < kernelsLen; ++i) {
1909        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
1910    }
1911
1912    jint srcLen = _env->GetArrayLength(_src);
1913    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
1914    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
1915    for(int i = 0; i < srcLen; ++i) {
1916        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
1917    }
1918
1919    jint dstkLen = _env->GetArrayLength(_dstk);
1920    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
1921    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
1922    for(int i = 0; i < dstkLen; ++i) {
1923        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
1924    }
1925
1926    jint dstfLen = _env->GetArrayLength(_dstf);
1927    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
1928    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
1929    for(int i = 0; i < dstfLen; ++i) {
1930        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
1931    }
1932
1933    jint typesLen = _env->GetArrayLength(_types);
1934    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
1935    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
1936    for(int i = 0; i < typesLen; ++i) {
1937        typesPtr[i] = (RsType)jTypesPtr[i];
1938    }
1939
1940    jlong id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
1941                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
1942                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
1943                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
1944                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
1945                               (RsType *)typesPtr, typesLen * sizeof(RsType));
1946
1947    free(kernelsPtr);
1948    free(srcPtr);
1949    free(dstkPtr);
1950    free(dstfPtr);
1951    free(typesPtr);
1952    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
1953    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
1954    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
1955    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
1956    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
1957    return id;
1958}
1959
1960static void
1961nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1962{
1963    if (kLogApi) {
1964        ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1965              (void *)gid, (void *)kid, (void *)alloc);
1966    }
1967    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1968}
1969
1970static void
1971nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1972{
1973    if (kLogApi) {
1974        ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1975              (void *)gid, (void *)kid, (void *)alloc);
1976    }
1977    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1978}
1979
1980static void
1981nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
1982{
1983    if (kLogApi) {
1984        ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
1985    }
1986    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
1987}
1988
1989// ---------------------------------------------------------------------------
1990
1991static jlong
1992nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
1993                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
1994                    jboolean depthMask, jboolean ditherEnable,
1995                    jint srcFunc, jint destFunc,
1996                    jint depthFunc)
1997{
1998    if (kLogApi) {
1999        ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
2000    }
2001    return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
2002                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
2003                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
2004}
2005
2006// ---------------------------------------------------------------------------
2007
2008static void
2009nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
2010{
2011    if (kLogApi) {
2012        ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
2013              (RsProgramVertex)vpv, slot, (RsAllocation)a);
2014    }
2015    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
2016}
2017
2018static void
2019nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2020{
2021    if (kLogApi) {
2022        ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2023              (RsProgramFragment)vpf, slot, (RsAllocation)a);
2024    }
2025    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
2026}
2027
2028static void
2029nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2030{
2031    if (kLogApi) {
2032        ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2033              (RsProgramFragment)vpf, slot, (RsSampler)a);
2034    }
2035    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
2036}
2037
2038// ---------------------------------------------------------------------------
2039
2040static jlong
2041nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2042                       jobjectArray texNames, jlongArray params)
2043{
2044    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2045    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2046    jint paramLen = _env->GetArrayLength(params);
2047
2048    int texCount = _env->GetArrayLength(texNames);
2049    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2050    const char ** nameArray = names.c_str();
2051    size_t* sizeArray = names.c_str_len();
2052
2053    if (kLogApi) {
2054        ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2055    }
2056
2057    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2058    for(int i = 0; i < paramLen; ++i) {
2059        paramPtr[i] = (uintptr_t)jParamPtr[i];
2060    }
2061    jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2062                                             nameArray, texCount, sizeArray,
2063                                             paramPtr, paramLen);
2064
2065    free(paramPtr);
2066    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2067    return ret;
2068}
2069
2070
2071// ---------------------------------------------------------------------------
2072
2073static jlong
2074nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2075                     jobjectArray texNames, jlongArray params)
2076{
2077    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2078    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2079    jint paramLen = _env->GetArrayLength(params);
2080
2081    if (kLogApi) {
2082        ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2083    }
2084
2085    int texCount = _env->GetArrayLength(texNames);
2086    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2087    const char ** nameArray = names.c_str();
2088    size_t* sizeArray = names.c_str_len();
2089
2090    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2091    for(int i = 0; i < paramLen; ++i) {
2092        paramPtr[i] = (uintptr_t)jParamPtr[i];
2093    }
2094
2095    jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2096                                           nameArray, texCount, sizeArray,
2097                                           paramPtr, paramLen);
2098
2099    free(paramPtr);
2100    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2101    return ret;
2102}
2103
2104// ---------------------------------------------------------------------------
2105
2106static jlong
2107nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
2108{
2109    if (kLogApi) {
2110        ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
2111              pointSprite, cull);
2112    }
2113    return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
2114}
2115
2116
2117// ---------------------------------------------------------------------------
2118
2119static void
2120nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
2121{
2122    if (kLogApi) {
2123        ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
2124    }
2125    rsContextBindRootScript((RsContext)con, (RsScript)script);
2126}
2127
2128static void
2129nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
2130{
2131    if (kLogApi) {
2132        ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
2133    }
2134    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
2135}
2136
2137static void
2138nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2139{
2140    if (kLogApi) {
2141        ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
2142              (RsProgramFragment)pf);
2143    }
2144    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
2145}
2146
2147static void
2148nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2149{
2150    if (kLogApi) {
2151        ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
2152    }
2153    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
2154}
2155
2156static void
2157nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2158{
2159    if (kLogApi) {
2160        ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
2161    }
2162    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
2163}
2164
2165
2166// ---------------------------------------------------------------------------
2167
2168static jlong
2169nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
2170               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
2171{
2172    if (kLogApi) {
2173        ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
2174    }
2175    return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
2176                                 (RsSamplerValue)magFilter,
2177                                 (RsSamplerValue)minFilter,
2178                                 (RsSamplerValue)wrapS,
2179                                 (RsSamplerValue)wrapT,
2180                                 (RsSamplerValue)wrapR,
2181                                 aniso);
2182}
2183
2184// ---------------------------------------------------------------------------
2185
2186static jlong
2187nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
2188{
2189    if (kLogApi) {
2190        ALOGD("nMeshCreate, con(%p)", (RsContext)con);
2191    }
2192
2193    jint vtxLen = _env->GetArrayLength(_vtx);
2194    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
2195    RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
2196    for(int i = 0; i < vtxLen; ++i) {
2197        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
2198    }
2199
2200    jint idxLen = _env->GetArrayLength(_idx);
2201    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
2202    RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
2203    for(int i = 0; i < idxLen; ++i) {
2204        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
2205    }
2206
2207    jint primLen = _env->GetArrayLength(_prim);
2208    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
2209
2210    jlong id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
2211                               (RsAllocation *)vtxPtr, vtxLen,
2212                               (RsAllocation *)idxPtr, idxLen,
2213                               (uint32_t *)primPtr, primLen);
2214
2215    free(vtxPtr);
2216    free(idxPtr);
2217    _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
2218    _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
2219    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
2220    return id;
2221}
2222
2223static jint
2224nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2225{
2226    if (kLogApi) {
2227        ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2228    }
2229    jint vtxCount = 0;
2230    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
2231    return vtxCount;
2232}
2233
2234static jint
2235nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2236{
2237    if (kLogApi) {
2238        ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2239    }
2240    jint idxCount = 0;
2241    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
2242    return idxCount;
2243}
2244
2245static void
2246nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
2247{
2248    if (kLogApi) {
2249        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2250    }
2251
2252    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
2253    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
2254
2255    for(jint i = 0; i < numVtxIDs; i ++) {
2256        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2257        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
2258    }
2259
2260    free(allocs);
2261}
2262
2263static void
2264nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
2265{
2266    if (kLogApi) {
2267        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2268    }
2269
2270    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
2271    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
2272
2273    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
2274
2275    for(jint i = 0; i < numIndices; i ++) {
2276        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2277        const jint prim = (jint)prims[i];
2278        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
2279        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
2280    }
2281
2282    free(allocs);
2283    free(prims);
2284}
2285
2286static jint
2287nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
2288    return (jint)sizeof(void*);
2289}
2290
2291
2292// ---------------------------------------------------------------------------
2293
2294
2295static const char *classPathName = "android/renderscript/RenderScript";
2296
2297static JNINativeMethod methods[] = {
2298{"_nInit",                         "()V",                                     (void*)_nInit },
2299
2300{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
2301{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
2302{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
2303{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
2304{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
2305{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
2306
2307{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
2308{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
2309
2310
2311// All methods below are thread protected in java.
2312{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
2313{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
2314{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
2315{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
2316{"rsnContextSetCacheDir",            "(JLjava/lang/String;)V",                (void*)nContextSetCacheDir },
2317{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
2318{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
2319{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
2320{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
2321{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
2322{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
2323{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
2324{"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
2325{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
2326{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
2327{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
2328{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
2329{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
2330
2331{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
2332{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
2333{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
2334{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
2335{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
2336{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
2337
2338{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
2339{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
2340{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
2341
2342{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
2343{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
2344{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
2345{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
2346
2347{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
2348{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
2349
2350{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
2351{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
2352{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
2353{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
2354
2355{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
2356{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
2357
2358{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
2359{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
2360{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
2361{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
2362{"rsnAllocationIoReceive",           "(JJ)V",                                 (void*)nAllocationIoReceive },
2363{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
2364{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
2365{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
2366{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
2367{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
2368{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
2369{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
2370{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
2371{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
2372{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
2373{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationRead3D },
2374{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
2375{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
2376{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
2377
2378{"rsnAllocationAdapterCreate",       "(JJJ)J",                                (void*)nAllocationAdapterCreate },
2379{"rsnAllocationAdapterOffset",       "(JJIIIIIIIII)V",                        (void*)nAllocationAdapterOffset },
2380
2381{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
2382{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
2383{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
2384{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
2385
2386{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
2387
2388{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
2389{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
2390{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
2391{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
2392{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
2393{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
2394{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
2395{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
2396{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
2397{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
2398{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
2399{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
2400
2401{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
2402{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
2403{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
2404{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
2405{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
2406{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
2407{"rsnScriptGroup2Create",            "(JLjava/lang/String;[J)J",               (void*)nScriptGroup2Create },
2408{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
2409{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
2410{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
2411{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
2412
2413{"rsnScriptIntrinsicBLAS_Single",    "(JJIIIIIIIIIFJJFJIIII)V",               (void*)nScriptIntrinsicBLAS_Single },
2414{"rsnScriptIntrinsicBLAS_Double",    "(JJIIIIIIIIIDJJDJIIII)V",               (void*)nScriptIntrinsicBLAS_Double },
2415{"rsnScriptIntrinsicBLAS_Complex",   "(JJIIIIIIIIIFFJJFFJIIII)V",             (void*)nScriptIntrinsicBLAS_Complex },
2416{"rsnScriptIntrinsicBLAS_Z",         "(JJIIIIIIIIIDDJJDDJIIII)V",             (void*)nScriptIntrinsicBLAS_Z },
2417
2418{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
2419
2420{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
2421{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
2422{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
2423
2424{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
2425{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
2426{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
2427
2428{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
2429{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
2430{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
2431{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
2432{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
2433
2434{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
2435
2436{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
2437
2438{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
2439{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
2440{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
2441{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
2442
2443{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
2444};
2445
2446static int registerFuncs(JNIEnv *_env)
2447{
2448    return android::AndroidRuntime::registerNativeMethods(
2449            _env, classPathName, methods, NELEM(methods));
2450}
2451
2452// ---------------------------------------------------------------------------
2453
2454jint JNI_OnLoad(JavaVM* vm, void* reserved)
2455{
2456    JNIEnv* env = nullptr;
2457    jint result = -1;
2458
2459    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
2460        ALOGE("ERROR: GetEnv failed\n");
2461        goto bail;
2462    }
2463    assert(env != nullptr);
2464
2465    if (registerFuncs(env) < 0) {
2466        ALOGE("ERROR: Renderscript native registration failed\n");
2467        goto bail;
2468    }
2469
2470    /* success -- return valid version number */
2471    result = JNI_VERSION_1_4;
2472
2473bail:
2474    return result;
2475}
2476