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