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