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