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