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