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