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