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