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