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