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