android_renderscript_RenderScript.cpp revision 93697c5f8eba2e0e9e67222f5505a6cd44416022
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)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 ver, jint sdkVer, jint ct)
244{
245    LOG_API("nContextCreate");
246    return (jlong)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
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)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)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)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)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)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)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)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) 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)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)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)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) 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)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)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)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)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)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)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)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, jlong script, jint slot,
1095               jlongArray ains, jlong aout, jbyteArray params,
1096               jintArray limits)
1097{
1098    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con,
1099            (void *)script, slot);
1100
1101    jint   in_len = 0;
1102    jlong *in_ptr = NULL;
1103
1104    RsAllocation *in_allocs = NULL;
1105
1106    if (ains != NULL) {
1107        in_len = _env->GetArrayLength(ains);
1108        in_ptr = _env->GetLongArrayElements(ains, NULL);
1109
1110        if (sizeof(RsAllocation) == sizeof(jlong)) {
1111            in_allocs = (RsAllocation*)in_ptr;
1112
1113        } else {
1114            // Convert from 64-bit jlong types to the native pointer type.
1115
1116            in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
1117
1118            for (int index = in_len; --index >= 0;) {
1119                in_allocs[index] = (RsAllocation)in_ptr[index];
1120            }
1121        }
1122    }
1123
1124    jint   param_len = 0;
1125    jbyte *param_ptr = NULL;
1126
1127    if (params != NULL) {
1128        param_len = _env->GetArrayLength(params);
1129        param_ptr = _env->GetByteArrayElements(params, NULL);
1130    }
1131
1132    RsScriptCall sc, *sca = NULL;
1133    uint32_t sc_size = 0;
1134
1135    jint  limit_len = 0;
1136    jint *limit_ptr = NULL;
1137
1138    if (limits != NULL) {
1139        limit_len = _env->GetArrayLength(limits);
1140        limit_ptr = _env->GetIntArrayElements(limits, NULL);
1141
1142        assert(limit_len == 6);
1143
1144        sc.xStart     = limit_ptr[0];
1145        sc.xEnd       = limit_ptr[1];
1146        sc.yStart     = limit_ptr[2];
1147        sc.yEnd       = limit_ptr[3];
1148        sc.zStart     = limit_ptr[4];
1149        sc.zEnd       = limit_ptr[5];
1150        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
1151
1152        sca = &sc;
1153    }
1154
1155    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
1156                         in_allocs, in_len, (RsAllocation)aout,
1157                         param_ptr, param_len, sca, sc_size);
1158
1159    if (ains != NULL) {
1160        _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
1161    }
1162
1163    if (params != NULL) {
1164        _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
1165    }
1166
1167    if (limits != NULL) {
1168        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
1169    }
1170}
1171
1172// -----------------------------------
1173
1174static jlong
1175nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
1176               jstring resName, jstring cacheDir,
1177               jbyteArray scriptRef, jint length)
1178{
1179    LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
1180
1181    AutoJavaStringToUTF8 resNameUTF(_env, resName);
1182    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1183    jlong ret = 0;
1184    jbyte* script_ptr = NULL;
1185    jint _exception = 0;
1186    jint remaining;
1187    if (!scriptRef) {
1188        _exception = 1;
1189        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1190        goto exit;
1191    }
1192    if (length < 0) {
1193        _exception = 1;
1194        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1195        goto exit;
1196    }
1197    remaining = _env->GetArrayLength(scriptRef);
1198    if (remaining < length) {
1199        _exception = 1;
1200        //jniThrowException(_env, "java/lang/IllegalArgumentException",
1201        //        "length > script.length - offset");
1202        goto exit;
1203    }
1204    script_ptr = (jbyte *)
1205        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1206
1207    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
1208
1209    ret = (jlong)rsScriptCCreate((RsContext)con,
1210                                resNameUTF.c_str(), resNameUTF.length(),
1211                                cacheDirUTF.c_str(), cacheDirUTF.length(),
1212                                (const char *)script_ptr, length);
1213
1214exit:
1215    if (script_ptr) {
1216        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1217                _exception ? JNI_ABORT: 0);
1218    }
1219
1220    return (jlong)ret;
1221}
1222
1223static jlong
1224nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
1225{
1226    LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
1227    return (jlong)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1228}
1229
1230static jlong
1231nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
1232{
1233    LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con, (void *)sid, slot, sig);
1234    return (jlong)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
1235}
1236
1237static jlong
1238nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1239{
1240    LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
1241    return (jlong)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1242}
1243
1244static jlong
1245nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
1246    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
1247{
1248    LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
1249
1250    jint kernelsLen = _env->GetArrayLength(_kernels);
1251    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, NULL);
1252    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
1253    for(int i = 0; i < kernelsLen; ++i) {
1254        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
1255    }
1256
1257    jint srcLen = _env->GetArrayLength(_src);
1258    jlong *jSrcPtr = _env->GetLongArrayElements(_src, NULL);
1259    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
1260    for(int i = 0; i < srcLen; ++i) {
1261        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
1262    }
1263
1264    jint dstkLen = _env->GetArrayLength(_dstk);
1265    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, NULL);
1266    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
1267    for(int i = 0; i < dstkLen; ++i) {
1268        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
1269    }
1270
1271    jint dstfLen = _env->GetArrayLength(_dstf);
1272    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, NULL);
1273    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
1274    for(int i = 0; i < dstfLen; ++i) {
1275        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
1276    }
1277
1278    jint typesLen = _env->GetArrayLength(_types);
1279    jlong *jTypesPtr = _env->GetLongArrayElements(_types, NULL);
1280    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
1281    for(int i = 0; i < typesLen; ++i) {
1282        typesPtr[i] = (RsType)jTypesPtr[i];
1283    }
1284
1285    jlong id = (jlong)rsScriptGroupCreate((RsContext)con,
1286                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
1287                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
1288                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
1289                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
1290                               (RsType *)typesPtr, typesLen * sizeof(RsType));
1291
1292    free(kernelsPtr);
1293    free(srcPtr);
1294    free(dstkPtr);
1295    free(dstfPtr);
1296    free(typesPtr);
1297    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
1298    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
1299    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
1300    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
1301    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
1302    return id;
1303}
1304
1305static void
1306nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1307{
1308    LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1309        (void *)gid, (void *)kid, (void *)alloc);
1310    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1311}
1312
1313static void
1314nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1315{
1316    LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1317        (void *)gid, (void *)kid, (void *)alloc);
1318    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1319}
1320
1321static void
1322nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
1323{
1324    LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
1325    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
1326}
1327
1328// ---------------------------------------------------------------------------
1329
1330static jlong
1331nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
1332                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
1333                    jboolean depthMask, jboolean ditherEnable,
1334                    jint srcFunc, jint destFunc,
1335                    jint depthFunc)
1336{
1337    LOG_API("nProgramStoreCreate, con(%p)", (RsContext)con);
1338    return (jlong)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
1339                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
1340                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
1341}
1342
1343// ---------------------------------------------------------------------------
1344
1345static void
1346nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
1347{
1348    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
1349    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
1350}
1351
1352static void
1353nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
1354{
1355    LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1356    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1357}
1358
1359static void
1360nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
1361{
1362    LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1363    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1364}
1365
1366// ---------------------------------------------------------------------------
1367
1368static jlong
1369nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
1370                       jobjectArray texNames, jlongArray params)
1371{
1372    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1373    jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
1374    jint paramLen = _env->GetArrayLength(params);
1375
1376    int texCount = _env->GetArrayLength(texNames);
1377    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
1378    const char ** nameArray = names.c_str();
1379    size_t* sizeArray = names.c_str_len();
1380
1381    LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
1382
1383    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
1384    for(int i = 0; i < paramLen; ++i) {
1385        paramPtr[i] = (uintptr_t)jParamPtr[i];
1386    }
1387    jlong ret = (jlong)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
1388                                             nameArray, texCount, sizeArray,
1389                                             paramPtr, paramLen);
1390
1391    free(paramPtr);
1392    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
1393    return ret;
1394}
1395
1396
1397// ---------------------------------------------------------------------------
1398
1399static jlong
1400nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
1401                     jobjectArray texNames, jlongArray params)
1402{
1403    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1404    jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
1405    jint paramLen = _env->GetArrayLength(params);
1406
1407    LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
1408
1409    int texCount = _env->GetArrayLength(texNames);
1410    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
1411    const char ** nameArray = names.c_str();
1412    size_t* sizeArray = names.c_str_len();
1413
1414    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
1415    for(int i = 0; i < paramLen; ++i) {
1416        paramPtr[i] = (uintptr_t)jParamPtr[i];
1417    }
1418
1419    jlong ret = (jlong)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
1420                                           nameArray, texCount, sizeArray,
1421                                           paramPtr, paramLen);
1422
1423    free(paramPtr);
1424    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
1425    return ret;
1426}
1427
1428// ---------------------------------------------------------------------------
1429
1430static jlong
1431nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
1432{
1433    LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con, pointSprite, cull);
1434    return (jlong)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
1435}
1436
1437
1438// ---------------------------------------------------------------------------
1439
1440static void
1441nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
1442{
1443    LOG_API("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
1444    rsContextBindRootScript((RsContext)con, (RsScript)script);
1445}
1446
1447static void
1448nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
1449{
1450    LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
1451    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
1452}
1453
1454static void
1455nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
1456{
1457    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con, (RsProgramFragment)pf);
1458    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
1459}
1460
1461static void
1462nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
1463{
1464    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
1465    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
1466}
1467
1468static void
1469nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
1470{
1471    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
1472    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
1473}
1474
1475
1476// ---------------------------------------------------------------------------
1477
1478static jlong
1479nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
1480               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1481{
1482    LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
1483    return (jlong)rsSamplerCreate((RsContext)con,
1484                                 (RsSamplerValue)magFilter,
1485                                 (RsSamplerValue)minFilter,
1486                                 (RsSamplerValue)wrapS,
1487                                 (RsSamplerValue)wrapT,
1488                                 (RsSamplerValue)wrapR,
1489                                 aniso);
1490}
1491
1492// ---------------------------------------------------------------------------
1493
1494static jlong
1495nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jlong _loop, jfloat q) {
1496    LOG_API("nPathCreate, con(%p)", (RsContext)con);
1497
1498    jlong id = (jlong)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
1499                                   (RsAllocation)_vtx,
1500                                   (RsAllocation)_loop, q);
1501    return id;
1502}
1503
1504static jlong
1505nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
1506{
1507    LOG_API("nMeshCreate, con(%p)", (RsContext)con);
1508
1509    jint vtxLen = _env->GetArrayLength(_vtx);
1510    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, NULL);
1511    RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
1512    for(int i = 0; i < vtxLen; ++i) {
1513        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
1514    }
1515
1516    jint idxLen = _env->GetArrayLength(_idx);
1517    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, NULL);
1518    RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
1519    for(int i = 0; i < idxLen; ++i) {
1520        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
1521    }
1522
1523    jint primLen = _env->GetArrayLength(_prim);
1524    jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
1525
1526    jlong id = (jlong)rsMeshCreate((RsContext)con,
1527                               (RsAllocation *)vtxPtr, vtxLen,
1528                               (RsAllocation *)idxPtr, idxLen,
1529                               (uint32_t *)primPtr, primLen);
1530
1531    free(vtxPtr);
1532    free(idxPtr);
1533    _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
1534    _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
1535    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
1536    return id;
1537}
1538
1539static jint
1540nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
1541{
1542    LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1543    jint vtxCount = 0;
1544    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
1545    return vtxCount;
1546}
1547
1548static jint
1549nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
1550{
1551    LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1552    jint idxCount = 0;
1553    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
1554    return idxCount;
1555}
1556
1557static void
1558nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
1559{
1560    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1561
1562    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
1563    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
1564
1565    for(jint i = 0; i < numVtxIDs; i ++) {
1566        const jlong alloc = (jlong)allocs[i];
1567        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
1568    }
1569
1570    free(allocs);
1571}
1572
1573static void
1574nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
1575{
1576    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1577
1578    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
1579    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
1580
1581    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
1582
1583    for(jint i = 0; i < numIndices; i ++) {
1584        const jlong alloc = (jlong)allocs[i];
1585        const jint prim = (jint)prims[i];
1586        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
1587        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
1588    }
1589
1590    free(allocs);
1591    free(prims);
1592}
1593
1594static jint
1595nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
1596    return (jint)sizeof(void*);
1597}
1598
1599
1600// ---------------------------------------------------------------------------
1601
1602
1603static const char *classPathName = "android/renderscript/RenderScript";
1604
1605static JNINativeMethod methods[] = {
1606{"_nInit",                         "()V",                                     (void*)_nInit },
1607
1608{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
1609{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
1610{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
1611{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
1612{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1613{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
1614
1615{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
1616{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
1617
1618
1619// All methods below are thread protected in java.
1620{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
1621{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
1622{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
1623{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
1624{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
1625{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
1626{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
1627{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
1628{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
1629{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
1630{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
1631{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
1632{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
1633
1634{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
1635{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
1636{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
1637{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
1638{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
1639{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
1640
1641{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
1642{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
1643{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
1644
1645{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
1646{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
1647{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
1648{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
1649
1650{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
1651{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
1652
1653{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
1654{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
1655{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
1656{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
1657
1658{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1659{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1660
1661{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
1662{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
1663{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
1664{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
1665{"rsnAllocationIoReceive",           "(JJ)V",                                 (void*)nAllocationIoReceive },
1666{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;II)V",          (void*)nAllocationData1D },
1667{"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
1668{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;II)V",       (void*)nAllocationData2D },
1669{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
1670{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;II)V",      (void*)nAllocationData3D },
1671{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
1672{"rsnAllocationRead",                "(JJLjava/lang/Object;I)V",              (void*)nAllocationRead },
1673{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;II)V",          (void*)nAllocationRead1D },
1674{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;II)V",       (void*)nAllocationRead2D },
1675{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
1676{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
1677{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
1678
1679{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
1680{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
1681{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
1682{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
1683
1684{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
1685
1686{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
1687{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
1688{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
1689{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
1690{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
1691{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
1692{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
1693{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
1694{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
1695{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
1696{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
1697{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
1698
1699{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
1700{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
1701{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
1702{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
1703{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
1704{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
1705{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
1706{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
1707
1708{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
1709
1710{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
1711{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
1712{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
1713
1714{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
1715{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
1716{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
1717
1718{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
1719{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
1720{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
1721{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
1722{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
1723
1724{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
1725
1726{"rsnPathCreate",                    "(JIZJJF)J",                             (void*)nPathCreate },
1727{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
1728
1729{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
1730{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
1731{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
1732{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
1733
1734{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
1735};
1736
1737static int registerFuncs(JNIEnv *_env)
1738{
1739    return android::AndroidRuntime::registerNativeMethods(
1740            _env, classPathName, methods, NELEM(methods));
1741}
1742
1743// ---------------------------------------------------------------------------
1744
1745jint JNI_OnLoad(JavaVM* vm, void* reserved)
1746{
1747    JNIEnv* env = NULL;
1748    jint result = -1;
1749
1750    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1751        ALOGE("ERROR: GetEnv failed\n");
1752        goto bail;
1753    }
1754    assert(env != NULL);
1755
1756    if (registerFuncs(env) < 0) {
1757        ALOGE("ERROR: Renderscript native registration failed\n");
1758        goto bail;
1759    }
1760
1761    /* success -- return valid version number */
1762    result = JNI_VERSION_1_4;
1763
1764bail:
1765    return result;
1766}
1767