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