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