android_renderscript_RenderScript.cpp revision fb9f82ca4f11cf7e43a001f3e6fd1b381cc86210
1/*
2 * Copyright (C) 2006 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 <surfaceflinger/Surface.h>
27
28#include <core/SkBitmap.h>
29#include <core/SkPixelRef.h>
30#include <core/SkStream.h>
31#include <core/SkTemplates.h>
32#include <images/SkImageDecoder.h>
33
34#include <utils/Asset.h>
35#include <utils/AssetManager.h>
36#include <utils/ResourceTypes.h>
37
38#include "jni.h"
39#include "JNIHelp.h"
40#include "android_runtime/AndroidRuntime.h"
41#include "android_runtime/android_view_Surface.h"
42#include "android_runtime/android_util_AssetManager.h"
43
44#include <RenderScript.h>
45#include <RenderScriptEnv.h>
46
47//#define LOG_API LOGE
48#define LOG_API(...)
49
50using namespace android;
51
52class AutoJavaStringToUTF8 {
53public:
54    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str)
55    {
56        fCStr = env->GetStringUTFChars(str, NULL);
57        fLength = env->GetStringUTFLength(str);
58    }
59    ~AutoJavaStringToUTF8()
60    {
61        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
62    }
63    const char* c_str() const { return fCStr; }
64    jsize length() const { return fLength; }
65
66private:
67    JNIEnv*     fEnv;
68    jstring     fJStr;
69    const char* fCStr;
70    jsize       fLength;
71};
72
73// ---------------------------------------------------------------------------
74
75static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
76{
77    jclass npeClazz = env->FindClass(exc);
78    env->ThrowNew(npeClazz, msg);
79}
80
81static jfieldID gContextId = 0;
82static jfieldID gNativeBitmapID = 0;
83static jfieldID gTypeNativeCache = 0;
84
85static void _nInit(JNIEnv *_env, jclass _this)
86{
87    gContextId             = _env->GetFieldID(_this, "mContext", "I");
88
89    jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
90    gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
91}
92
93// ---------------------------------------------------------------------------
94
95static void
96nContextFinish(JNIEnv *_env, jobject _this, RsContext con)
97{
98    LOG_API("nContextFinish, con(%p)", con);
99    rsContextFinish(con);
100}
101
102static void
103nAssignName(JNIEnv *_env, jobject _this, RsContext con, jint obj, jbyteArray str)
104{
105    LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj);
106    jint len = _env->GetArrayLength(str);
107    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
108    rsAssignName(con, (void *)obj, (const char *)cptr, len);
109    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
110}
111
112static jstring
113nGetName(JNIEnv *_env, jobject _this, RsContext con, jint obj)
114{
115    LOG_API("nGetName, con(%p), obj(%p)", con, (void *)obj);
116    const char *name = NULL;
117    rsaGetName(con, (void *)obj, &name);
118    if(name == NULL || strlen(name) == 0) {
119        return NULL;
120    }
121    return _env->NewStringUTF(name);
122}
123
124static void
125nObjDestroy(JNIEnv *_env, jobject _this, RsContext con, jint obj)
126{
127    LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
128    rsObjDestroy(con, (void *)obj);
129}
130
131// ---------------------------------------------------------------------------
132
133static jint
134nDeviceCreate(JNIEnv *_env, jobject _this)
135{
136    LOG_API("nDeviceCreate");
137    return (jint)rsDeviceCreate();
138}
139
140static void
141nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev)
142{
143    LOG_API("nDeviceDestroy");
144    return rsDeviceDestroy((RsDevice)dev);
145}
146
147static void
148nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value)
149{
150    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
151    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
152}
153
154static jint
155nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver)
156{
157    LOG_API("nContextCreate");
158    return (jint)rsContextCreate((RsDevice)dev, ver);
159}
160
161static jint
162nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver,
163                 int colorMin, int colorPref,
164                 int alphaMin, int alphaPref,
165                 int depthMin, int depthPref,
166                 int stencilMin, int stencilPref,
167                 int samplesMin, int samplesPref, float samplesQ)
168{
169    RsSurfaceConfig sc;
170    sc.alphaMin = alphaMin;
171    sc.alphaPref = alphaPref;
172    sc.colorMin = colorMin;
173    sc.colorPref = colorPref;
174    sc.depthMin = depthMin;
175    sc.depthPref = depthPref;
176    sc.samplesMin = samplesMin;
177    sc.samplesPref = samplesPref;
178    sc.samplesQ = samplesQ;
179
180    LOG_API("nContextCreateGL");
181    return (jint)rsContextCreateGL((RsDevice)dev, ver, sc);
182}
183
184static void
185nContextSetPriority(JNIEnv *_env, jobject _this, RsContext con, jint p)
186{
187    LOG_API("ContextSetPriority, con(%p), priority(%i)", con, p);
188    rsContextSetPriority(con, p);
189}
190
191
192
193static void
194nContextSetSurface(JNIEnv *_env, jobject _this, RsContext con, jint width, jint height, jobject wnd)
195{
196    LOG_API("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", con, width, height, (Surface *)wnd);
197
198    Surface * window = NULL;
199    if (wnd == NULL) {
200
201    } else {
202        window = (Surface*) android_Surface_getNativeWindow(_env, wnd).get();
203    }
204
205    rsContextSetSurface(con, width, height, window);
206}
207
208static void
209nContextDestroy(JNIEnv *_env, jobject _this, RsContext con)
210{
211    LOG_API("nContextDestroy, con(%p)", con);
212    rsContextDestroy(con);
213}
214
215static void
216nContextDump(JNIEnv *_env, jobject _this, RsContext con, jint bits)
217{
218    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
219    rsContextDump((RsContext)con, bits);
220}
221
222static void
223nContextPause(JNIEnv *_env, jobject _this, RsContext con)
224{
225    LOG_API("nContextPause, con(%p)", con);
226    rsContextPause(con);
227}
228
229static void
230nContextResume(JNIEnv *_env, jobject _this, RsContext con)
231{
232    LOG_API("nContextResume, con(%p)", con);
233    rsContextResume(con);
234}
235
236
237static jstring
238nContextGetErrorMessage(JNIEnv *_env, jobject _this, RsContext con)
239{
240    LOG_API("nContextGetErrorMessage, con(%p)", con);
241    char buf[1024];
242
243    size_t receiveLen;
244    uint32_t subID;
245    int id = rsContextGetMessage(con, buf, &receiveLen, &subID, sizeof(buf), true);
246    if (!id && receiveLen) {
247        LOGV("message receive buffer too small.  %i", receiveLen);
248    }
249    return _env->NewStringUTF(buf);
250}
251
252static void
253nContextGetUserMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data)
254{
255    jint len = _env->GetArrayLength(data);
256    LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
257    jint *ptr = _env->GetIntArrayElements(data, NULL);
258    size_t receiveLen;
259    uint32_t subID;
260    int id = rsContextGetMessage(con, ptr, &receiveLen, &subID, len * 4, true);
261    if (!id && receiveLen) {
262        LOGV("message receive buffer too small.  %i", receiveLen);
263    }
264    _env->ReleaseIntArrayElements(data, ptr, 0);
265}
266
267static jint
268nContextPeekMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray auxData, jboolean wait)
269{
270    LOG_API("nContextPeekMessage, con(%p)", con);
271    jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
272    size_t receiveLen;
273    uint32_t subID;
274    int id = rsContextPeekMessage(con, &receiveLen, &subID, wait);
275    auxDataPtr[0] = (jint)subID;
276    auxDataPtr[1] = (jint)receiveLen;
277    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
278    return id;
279}
280
281static void nContextInitToClient(JNIEnv *_env, jobject _this, RsContext con)
282{
283    LOG_API("nContextInitToClient, con(%p)", con);
284    rsContextInitToClient(con);
285}
286
287static void nContextDeinitToClient(JNIEnv *_env, jobject _this, RsContext con)
288{
289    LOG_API("nContextDeinitToClient, con(%p)", con);
290    rsContextDeinitToClient(con);
291}
292
293
294static jint
295nElementCreate(JNIEnv *_env, jobject _this, RsContext con, jint type, jint kind, jboolean norm, jint size)
296{
297    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size);
298    return (jint)rsElementCreate(con, (RsDataType)type, (RsDataKind)kind, norm, size);
299}
300
301static jint
302nElementCreate2(JNIEnv *_env, jobject _this, RsContext con, jintArray _ids, jobjectArray _names, jintArray _arraySizes)
303{
304    int fieldCount = _env->GetArrayLength(_ids);
305    LOG_API("nElementCreate2, con(%p)", con);
306
307    jint *ids = _env->GetIntArrayElements(_ids, NULL);
308    jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
309    const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
310    size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t));
311
312    for (int ct=0; ct < fieldCount; ct++) {
313        jstring s = (jstring)_env->GetObjectArrayElement(_names, ct);
314        nameArray[ct] = _env->GetStringUTFChars(s, NULL);
315        sizeArray[ct] = _env->GetStringUTFLength(s);
316    }
317    jint id = (jint)rsElementCreate2(con, fieldCount, (RsElement *)ids, nameArray, sizeArray, (const uint32_t *)arraySizes);
318    for (int ct=0; ct < fieldCount; ct++) {
319        jstring s = (jstring)_env->GetObjectArrayElement(_names, ct);
320        _env->ReleaseStringUTFChars(s, nameArray[ct]);
321    }
322    _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT);
323    _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT);
324    free(nameArray);
325    free(sizeArray);
326    return (jint)id;
327}
328
329static void
330nElementGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _elementData)
331{
332    int dataSize = _env->GetArrayLength(_elementData);
333    LOG_API("nElementGetNativeData, con(%p)", con);
334
335    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
336    assert(dataSize == 5);
337
338    uint32_t elementData[5];
339    rsaElementGetNativeData(con, (RsElement)id, elementData, dataSize);
340
341    for(jint i = 0; i < dataSize; i ++) {
342        _env->SetIntArrayRegion(_elementData, i, 1, (const jint*)&elementData[i]);
343    }
344}
345
346
347static void
348nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _IDs, jobjectArray _names)
349{
350    int dataSize = _env->GetArrayLength(_IDs);
351    LOG_API("nElementGetSubElements, con(%p)", con);
352
353    uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
354    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
355
356    rsaElementGetSubElements(con, (RsElement)id, ids, names, (uint32_t)dataSize);
357
358    for(jint i = 0; i < dataSize; i++) {
359        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
360        _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
361    }
362
363    free(ids);
364    free(names);
365}
366
367// -----------------------------------
368
369static int
370nTypeCreate(JNIEnv *_env, jobject _this, RsContext con, RsElement eid,
371            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces)
372{
373    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i)",
374            con, eid, dimx, dimy, dimz, mips, faces);
375
376    jint id = (jint)rsaTypeCreate(con, (RsElement)eid, dimx, dimy, dimz, mips, faces);
377    return (jint)id;
378}
379
380static void
381nTypeGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _typeData)
382{
383    // We are packing 6 items: mDimX; mDimY; mDimZ;
384    // mDimLOD; mDimFaces; mElement; into typeData
385    int elementCount = _env->GetArrayLength(_typeData);
386
387    assert(elementCount == 6);
388    LOG_API("nTypeCreate, con(%p)", con);
389
390    uint32_t typeData[6];
391    rsaTypeGetNativeData(con, (RsType)id, typeData, 6);
392
393    for(jint i = 0; i < elementCount; i ++) {
394        _env->SetIntArrayRegion(_typeData, i, 1, (const jint*)&typeData[i]);
395    }
396}
397
398// -----------------------------------
399
400static jint
401nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage)
402{
403    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i)", con, (RsElement)type, mips, usage);
404    return (jint) rsaAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage);
405}
406
407static void
408nAllocationSyncAll(JNIEnv *_env, jobject _this, RsContext con, jint a, jint bits)
409{
410    LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", con, (RsAllocation)a, bits);
411    rsAllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
412}
413
414static void
415nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
416{
417    LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", con, (RsAllocation)alloc);
418    rsAllocationGenerateMipmaps(con, (RsAllocation)alloc);
419}
420
421static int
422nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
423{
424    SkBitmap const * nativeBitmap =
425            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
426    const SkBitmap& bitmap(*nativeBitmap);
427
428    bitmap.lockPixels();
429    const void* ptr = bitmap.getPixels();
430    jint id = (jint)rsaAllocationCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapControl)mip, ptr, usage);
431    bitmap.unlockPixels();
432    return id;
433}
434
435static int
436nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
437{
438    SkBitmap const * nativeBitmap =
439            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
440    const SkBitmap& bitmap(*nativeBitmap);
441
442    bitmap.lockPixels();
443    const void* ptr = bitmap.getPixels();
444    jint id = (jint)rsaAllocationCubeCreateFromBitmap(con, (RsType)type, (RsAllocationMipmapControl)mip, ptr, usage);
445    bitmap.unlockPixels();
446    return id;
447}
448
449static void
450nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
451{
452    SkBitmap const * nativeBitmap =
453            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
454    const SkBitmap& bitmap(*nativeBitmap);
455    int w = bitmap.width();
456    int h = bitmap.height();
457
458    bitmap.lockPixels();
459    const void* ptr = bitmap.getPixels();
460    rsAllocation2DData(con, (RsAllocation)alloc, 0, 0,
461                       0, RS_ALLOCATION_CUBMAP_FACE_POSITVE_X,
462                       w, h, ptr, bitmap.getSize());
463    bitmap.unlockPixels();
464}
465
466static void
467nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
468{
469    SkBitmap const * nativeBitmap =
470            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
471    const SkBitmap& bitmap(*nativeBitmap);
472
473    bitmap.lockPixels();
474    void* ptr = bitmap.getPixels();
475    rsAllocationCopyToBitmap(con, (RsAllocation)alloc, ptr, bitmap.getSize());
476    bitmap.unlockPixels();
477}
478
479static void ReleaseBitmapCallback(void *bmp)
480{
481    SkBitmap const * nativeBitmap = (SkBitmap const *)bmp;
482    nativeBitmap->unlockPixels();
483}
484
485
486static void
487nAllocationData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jintArray data, int sizeBytes)
488{
489    jint len = _env->GetArrayLength(data);
490    LOG_API("nAllocation1DData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
491    jint *ptr = _env->GetIntArrayElements(data, NULL);
492    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
493    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
494}
495
496static void
497nAllocationData1D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jshortArray data, int sizeBytes)
498{
499    jint len = _env->GetArrayLength(data);
500    LOG_API("nAllocation1DData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
501    jshort *ptr = _env->GetShortArrayElements(data, NULL);
502    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
503    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
504}
505
506static void
507nAllocationData1D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jbyteArray data, int sizeBytes)
508{
509    jint len = _env->GetArrayLength(data);
510    LOG_API("nAllocation1DData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
511    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
512    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
513    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
514}
515
516static void
517nAllocationData1D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jfloatArray data, int sizeBytes)
518{
519    jint len = _env->GetArrayLength(data);
520    LOG_API("nAllocation1DData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
521    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
522    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
523    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
524}
525
526static void
527//    native void rsnAllocationElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
528nAllocationElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes)
529{
530    jint len = _env->GetArrayLength(data);
531    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
532    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
533    rsAllocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, compIdx, sizeBytes);
534    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
535}
536
537static void
538nAllocationData2D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
539                    jint w, jint h, jshortArray data, int sizeBytes)
540{
541    jint len = _env->GetArrayLength(data);
542    LOG_API("nAllocation2DData_s, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
543    jshort *ptr = _env->GetShortArrayElements(data, NULL);
544    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
545    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
546}
547
548static void
549nAllocationData2D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
550                    jint w, jint h, jbyteArray data, int sizeBytes)
551{
552    jint len = _env->GetArrayLength(data);
553    LOG_API("nAllocation2DData_b, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
554    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
555    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
556    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
557}
558
559static void
560nAllocationData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
561                    jint w, jint h, jintArray data, int sizeBytes)
562{
563    jint len = _env->GetArrayLength(data);
564    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
565    jint *ptr = _env->GetIntArrayElements(data, NULL);
566    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
567    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
568}
569
570static void
571nAllocationData2D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
572                    jint w, jint h, jfloatArray data, int sizeBytes)
573{
574    jint len = _env->GetArrayLength(data);
575    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
576    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
577    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
578    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
579}
580
581static void
582nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
583{
584    jint len = _env->GetArrayLength(data);
585    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
586    jint *ptr = _env->GetIntArrayElements(data, NULL);
587    rsAllocationRead(con, (RsAllocation)alloc, ptr);
588    _env->ReleaseIntArrayElements(data, ptr, 0);
589}
590
591static void
592nAllocationRead_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jshortArray data)
593{
594    jint len = _env->GetArrayLength(data);
595    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
596    jshort *ptr = _env->GetShortArrayElements(data, NULL);
597    rsAllocationRead(con, (RsAllocation)alloc, ptr);
598    _env->ReleaseShortArrayElements(data, ptr, 0);
599}
600
601static void
602nAllocationRead_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jbyteArray data)
603{
604    jint len = _env->GetArrayLength(data);
605    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
606    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
607    rsAllocationRead(con, (RsAllocation)alloc, ptr);
608    _env->ReleaseByteArrayElements(data, ptr, 0);
609}
610
611static void
612nAllocationRead_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jfloatArray data)
613{
614    jint len = _env->GetArrayLength(data);
615    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
616    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
617    rsAllocationRead(con, (RsAllocation)alloc, ptr);
618    _env->ReleaseFloatArrayElements(data, ptr, 0);
619}
620
621static jint
622nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
623{
624    LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a);
625    return (jint) rsaAllocationGetType(con, (RsAllocation)a);
626}
627
628static void
629nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
630{
631    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
632    rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
633}
634
635static void
636nAllocationResize2D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX, jint dimY)
637{
638    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i), sizeY(%i)", con, (RsAllocation)alloc, dimX, dimY);
639    rsAllocationResize2D(con, (RsAllocation)alloc, dimX, dimY);
640}
641
642// -----------------------------------
643
644static int
645nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con, jint native_asset)
646{
647    LOGV("______nFileA3D %u", (uint32_t) native_asset);
648
649    Asset* asset = reinterpret_cast<Asset*>(native_asset);
650
651    jint id = (jint)rsaFileA3DCreateFromMemory(con, asset->getBuffer(false), asset->getLength());
652    return id;
653}
654
655static int
656nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path)
657{
658    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
659    if (mgr == NULL) {
660        return 0;
661    }
662
663    AutoJavaStringToUTF8 str(_env, _path);
664    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
665    if (asset == NULL) {
666        return 0;
667    }
668
669    jint id = (jint)rsaFileA3DCreateFromAsset(con, asset);
670    return id;
671}
672
673static int
674nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName)
675{
676    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
677    jint id = (jint)rsaFileA3DCreateFromFile(con, fileNameUTF.c_str());
678
679    return id;
680}
681
682static int
683nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D)
684{
685    int32_t numEntries = 0;
686    rsaFileA3DGetNumIndexEntries(con, &numEntries, (RsFile)fileA3D);
687    return numEntries;
688}
689
690static void
691nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
692{
693    LOGV("______nFileA3D %u", (uint32_t) fileA3D);
694    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
695
696    rsaFileA3DGetIndexEntries(con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
697
698    for(jint i = 0; i < numEntries; i ++) {
699        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
700        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
701    }
702
703    free(fileEntries);
704}
705
706static int
707nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint index)
708{
709    LOGV("______nFileA3D %u", (uint32_t) fileA3D);
710    jint id = (jint)rsaFileA3DGetEntryByIndex(con, (uint32_t)index, (RsFile)fileA3D);
711    return id;
712}
713
714// -----------------------------------
715
716static int
717nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con,
718                    jstring fileName, jfloat fontSize, jint dpi)
719{
720    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
721    jint id = (jint)rsFontCreateFromFile(con, fileNameUTF.c_str(), fontSize, dpi);
722
723    return id;
724}
725
726static int
727nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con,
728                           jstring name, jfloat fontSize, jint dpi, jint native_asset)
729{
730    Asset* asset = reinterpret_cast<Asset*>(native_asset);
731    AutoJavaStringToUTF8 nameUTF(_env, name);
732
733    jint id = (jint)rsFontCreateFromMemory(con, nameUTF.c_str(), fontSize, dpi,
734                                           asset->getBuffer(false), asset->getLength());
735    return id;
736}
737
738static int
739nFontCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path,
740                     jfloat fontSize, jint dpi)
741{
742    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
743    if (mgr == NULL) {
744        return 0;
745    }
746
747    AutoJavaStringToUTF8 str(_env, _path);
748    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
749    if (asset == NULL) {
750        return 0;
751    }
752
753    jint id = (jint)rsFontCreateFromMemory(con, str.c_str(), fontSize, dpi,
754                                           asset->getBuffer(false), asset->getLength());
755    delete asset;
756    return id;
757}
758
759// -----------------------------------
760
761static void
762nScriptBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint script, jint alloc, jint slot)
763{
764    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
765    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
766}
767
768static void
769nScriptSetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
770{
771    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
772    rsScriptSetVarI(con, (RsScript)script, slot, val);
773}
774
775static void
776nScriptSetVarObj(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
777{
778    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
779    rsScriptSetVarObj(con, (RsScript)script, slot, (RsObjectBase)val);
780}
781
782static void
783nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
784{
785    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
786    rsScriptSetVarJ(con, (RsScript)script, slot, val);
787}
788
789static void
790nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
791{
792    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
793    rsScriptSetVarF(con, (RsScript)script, slot, val);
794}
795
796static void
797nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
798{
799    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
800    rsScriptSetVarD(con, (RsScript)script, slot, val);
801}
802
803static void
804nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
805{
806    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
807    jint len = _env->GetArrayLength(data);
808    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
809    rsScriptSetVarV(con, (RsScript)script, slot, ptr, len);
810    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
811}
812
813
814static void
815nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
816{
817    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
818
819    jint length = _env->GetArrayLength(timeZone);
820    jbyte* timeZone_ptr;
821    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
822
823    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
824
825    if (timeZone_ptr) {
826        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
827    }
828}
829
830static void
831nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
832{
833    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
834    rsScriptInvoke(con, (RsScript)obj, slot);
835}
836
837static void
838nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
839{
840    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
841    jint len = _env->GetArrayLength(data);
842    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
843    rsScriptInvokeV(con, (RsScript)script, slot, ptr, len);
844    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
845}
846
847
848// -----------------------------------
849
850static void
851nScriptCBegin(JNIEnv *_env, jobject _this, RsContext con)
852{
853    LOG_API("nScriptCBegin, con(%p)", con);
854    rsScriptCBegin(con);
855}
856
857static void
858nScriptCSetScript(JNIEnv *_env, jobject _this, RsContext con, jbyteArray scriptRef,
859                  jint offset, jint length)
860{
861    LOG_API("!!! nScriptCSetScript, con(%p)", con);
862    jint _exception = 0;
863    jint remaining;
864    jbyte* script_base = 0;
865    jbyte* script_ptr;
866    if (!scriptRef) {
867        _exception = 1;
868        //_env->ThrowNew(IAEClass, "script == null");
869        goto exit;
870    }
871    if (offset < 0) {
872        _exception = 1;
873        //_env->ThrowNew(IAEClass, "offset < 0");
874        goto exit;
875    }
876    if (length < 0) {
877        _exception = 1;
878        //_env->ThrowNew(IAEClass, "length < 0");
879        goto exit;
880    }
881    remaining = _env->GetArrayLength(scriptRef) - offset;
882    if (remaining < length) {
883        _exception = 1;
884        //_env->ThrowNew(IAEClass, "length > script.length - offset");
885        goto exit;
886    }
887    script_base = (jbyte *)
888        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
889    script_ptr = script_base + offset;
890
891    rsScriptCSetText(con, (const char *)script_ptr, length);
892
893exit:
894    if (script_base) {
895        _env->ReleasePrimitiveArrayCritical(scriptRef, script_base,
896                _exception ? JNI_ABORT: 0);
897    }
898}
899
900static jint
901nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con, jstring packageName, jstring resName, jstring cacheDir)
902{
903    LOG_API("nScriptCCreate, con(%p)", con);
904    AutoJavaStringToUTF8 packageNameUTF(_env, packageName);
905    AutoJavaStringToUTF8 resNameUTF(_env, resName);
906    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
907    jint i = (jint)rsScriptCCreate(con, packageNameUTF.c_str(), resNameUTF.c_str(), cacheDirUTF.c_str());
908    return i;
909}
910
911// ---------------------------------------------------------------------------
912
913static void
914nProgramStoreBegin(JNIEnv *_env, jobject _this, RsContext con, jint in, jint out)
915{
916    LOG_API("nProgramStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
917    rsProgramStoreBegin(con, (RsElement)in, (RsElement)out);
918}
919
920static void
921nProgramStoreDepthFunc(JNIEnv *_env, jobject _this, RsContext con, jint func)
922{
923    LOG_API("nProgramStoreDepthFunc, con(%p), func(%i)", con, func);
924    rsProgramStoreDepthFunc(con, (RsDepthFunc)func);
925}
926
927static void
928nProgramStoreDepthMask(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
929{
930    LOG_API("nProgramStoreDepthMask, con(%p), enable(%i)", con, enable);
931    rsProgramStoreDepthMask(con, enable);
932}
933
934static void
935nProgramStoreColorMask(JNIEnv *_env, jobject _this, RsContext con, jboolean r, jboolean g, jboolean b, jboolean a)
936{
937    LOG_API("nProgramStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
938    rsProgramStoreColorMask(con, r, g, b, a);
939}
940
941static void
942nProgramStoreBlendFunc(JNIEnv *_env, jobject _this, RsContext con, int src, int dst)
943{
944    LOG_API("nProgramStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
945    rsProgramStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
946}
947
948static void
949nProgramStoreDither(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
950{
951    LOG_API("nProgramStoreDither, con(%p), enable(%i)", con, enable);
952    rsProgramStoreDither(con, enable);
953}
954
955static jint
956nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con)
957{
958    LOG_API("nProgramStoreCreate, con(%p)", con);
959    return (jint)rsProgramStoreCreate(con);
960}
961
962// ---------------------------------------------------------------------------
963
964static void
965nProgramBindConstants(JNIEnv *_env, jobject _this, RsContext con, jint vpv, jint slot, jint a)
966{
967    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
968    rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a);
969}
970
971static void
972nProgramBindTexture(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
973{
974    LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
975    rsProgramBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
976}
977
978static void
979nProgramBindSampler(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
980{
981    LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
982    rsProgramBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
983}
984
985// ---------------------------------------------------------------------------
986
987static jint
988nProgramFragmentCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
989{
990    AutoJavaStringToUTF8 shaderUTF(_env, shader);
991    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
992    jint paramLen = _env->GetArrayLength(params);
993
994    LOG_API("nProgramFragmentCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
995
996    jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
997    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
998    return ret;
999}
1000
1001
1002// ---------------------------------------------------------------------------
1003
1004static jint
1005nProgramVertexCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
1006{
1007    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1008    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1009    jint paramLen = _env->GetArrayLength(params);
1010
1011    LOG_API("nProgramVertexCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
1012
1013    jint ret = (jint)rsProgramVertexCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
1014    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1015    return ret;
1016}
1017
1018// ---------------------------------------------------------------------------
1019
1020static jint
1021nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite)
1022{
1023    LOG_API("nProgramRasterCreate, con(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)",
1024            con, pointSmooth, lineSmooth, pointSprite);
1025    return (jint)rsProgramRasterCreate(con, pointSmooth, lineSmooth, pointSprite);
1026}
1027
1028static void
1029nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jfloat v)
1030{
1031    LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
1032    rsProgramRasterSetLineWidth(con, (RsProgramRaster)vpr, v);
1033}
1034
1035static void
1036nProgramRasterSetCullMode(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jint v)
1037{
1038    LOG_API("nProgramRasterSetCullMode, con(%p), vpf(%p), value(%i)", con, (RsProgramRaster)vpr, v);
1039    rsProgramRasterSetCullMode(con, (RsProgramRaster)vpr, (RsCullMode)v);
1040}
1041
1042
1043// ---------------------------------------------------------------------------
1044
1045static void
1046nContextBindRootScript(JNIEnv *_env, jobject _this, RsContext con, jint script)
1047{
1048    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
1049    rsContextBindRootScript(con, (RsScript)script);
1050}
1051
1052static void
1053nContextBindProgramStore(JNIEnv *_env, jobject _this, RsContext con, jint pfs)
1054{
1055    LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs);
1056    rsContextBindProgramStore(con, (RsProgramStore)pfs);
1057}
1058
1059static void
1060nContextBindProgramFragment(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1061{
1062    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
1063    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
1064}
1065
1066static void
1067nContextBindProgramVertex(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1068{
1069    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
1070    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
1071}
1072
1073static void
1074nContextBindProgramRaster(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1075{
1076    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
1077    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
1078}
1079
1080
1081// ---------------------------------------------------------------------------
1082
1083static void
1084nSamplerBegin(JNIEnv *_env, jobject _this, RsContext con)
1085{
1086    LOG_API("nSamplerBegin, con(%p)", con);
1087    rsSamplerBegin(con);
1088}
1089
1090static void
1091nSamplerSet(JNIEnv *_env, jobject _this, RsContext con, jint p, jint v)
1092{
1093    LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v);
1094    rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v);
1095}
1096
1097static void
1098nSamplerSet2(JNIEnv *_env, jobject _this, RsContext con, jint p, jfloat v)
1099{
1100    LOG_API("nSamplerSet2, con(%p), param(%i), value(%f)", con, p, v);
1101    rsSamplerSet2(con, (RsSamplerParam)p, v);
1102}
1103
1104static jint
1105nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con)
1106{
1107    LOG_API("nSamplerCreate, con(%p)", con);
1108    return (jint)rsSamplerCreate(con);
1109}
1110
1111// ---------------------------------------------------------------------------
1112
1113static jint
1114nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jint vtxCount, jint idxCount)
1115{
1116    LOG_API("nMeshCreate, con(%p), vtxCount(%i), idxCount(%i)", con, vtxCount, idxCount);
1117    int id = (int)rsMeshCreate(con, vtxCount, idxCount);
1118    return id;
1119}
1120
1121static void
1122nMeshBindVertex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint slot)
1123{
1124    LOG_API("nMeshBindVertex, con(%p), Mesh(%p), Alloc(%p), slot(%i)", con, (RsMesh)mesh, (RsAllocation)alloc, slot);
1125    rsMeshBindVertex(con, (RsMesh)mesh, (RsAllocation)alloc, slot);
1126}
1127
1128static void
1129nMeshBindIndex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint primID, jint slot)
1130{
1131    LOG_API("nMeshBindIndex, con(%p), Mesh(%p), Alloc(%p)", con, (RsMesh)mesh, (RsAllocation)alloc);
1132    rsMeshBindIndex(con, (RsMesh)mesh, (RsAllocation)alloc, primID, slot);
1133}
1134
1135static void
1136nMeshInitVertexAttribs(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1137{
1138    LOG_API("nMeshInitVertexAttribs, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1139    rsMeshInitVertexAttribs(con, (RsMesh)mesh);
1140}
1141
1142
1143static jint
1144nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1145{
1146    LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1147    jint vtxCount = 0;
1148    rsaMeshGetVertexBufferCount(con, (RsMesh)mesh, &vtxCount);
1149    return vtxCount;
1150}
1151
1152static jint
1153nMeshGetIndexCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1154{
1155    LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1156    jint idxCount = 0;
1157    rsaMeshGetIndexCount(con, (RsMesh)mesh, &idxCount);
1158    return idxCount;
1159}
1160
1161static void
1162nMeshGetVertices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _ids, int numVtxIDs)
1163{
1164    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1165
1166    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
1167    rsaMeshGetVertices(con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
1168
1169    for(jint i = 0; i < numVtxIDs; i ++) {
1170        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]);
1171    }
1172
1173    free(allocs);
1174}
1175
1176static void
1177nMeshGetIndices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
1178{
1179    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1180
1181    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
1182    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
1183
1184    rsaMeshGetIndices(con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
1185
1186    for(jint i = 0; i < numIndices; i ++) {
1187        _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]);
1188        _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]);
1189    }
1190
1191    free(allocs);
1192    free(prims);
1193}
1194
1195// ---------------------------------------------------------------------------
1196
1197
1198static const char *classPathName = "android/renderscript/RenderScript";
1199
1200static JNINativeMethod methods[] = {
1201{"_nInit",                         "()V",                                     (void*)_nInit },
1202
1203{"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
1204{"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
1205{"nDeviceSetConfig",               "(III)V",                                  (void*)nDeviceSetConfig },
1206{"nContextGetUserMessage",         "(I[I)V",                                  (void*)nContextGetUserMessage },
1207{"nContextGetErrorMessage",        "(I)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1208{"nContextPeekMessage",            "(I[IZ)I",                                 (void*)nContextPeekMessage },
1209
1210{"nContextInitToClient",           "(I)V",                                    (void*)nContextInitToClient },
1211{"nContextDeinitToClient",         "(I)V",                                    (void*)nContextDeinitToClient },
1212
1213
1214// All methods below are thread protected in java.
1215{"rsnContextCreate",                 "(II)I",                                 (void*)nContextCreate },
1216{"rsnContextCreateGL",               "(IIIIIIIIIIIIF)I",                      (void*)nContextCreateGL },
1217{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
1218{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
1219{"rsnContextSetSurface",             "(IIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
1220{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
1221{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
1222{"rsnContextPause",                  "(I)V",                                  (void*)nContextPause },
1223{"rsnContextResume",                 "(I)V",                                  (void*)nContextResume },
1224{"rsnAssignName",                    "(II[B)V",                               (void*)nAssignName },
1225{"rsnGetName",                       "(II)Ljava/lang/String;",                (void*)nGetName },
1226{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
1227
1228{"rsnFileA3DCreateFromFile",         "(ILjava/lang/String;)I",                (void*)nFileA3DCreateFromFile },
1229{"rsnFileA3DCreateFromAssetStream",  "(II)I",                                 (void*)nFileA3DCreateFromAssetStream },
1230{"rsnFileA3DCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;)I",            (void*)nFileA3DCreateFromAsset },
1231{"rsnFileA3DGetNumIndexEntries",     "(II)I",                                 (void*)nFileA3DGetNumIndexEntries },
1232{"rsnFileA3DGetIndexEntries",        "(III[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
1233{"rsnFileA3DGetEntryByIndex",        "(III)I",                                (void*)nFileA3DGetEntryByIndex },
1234
1235{"rsnFontCreateFromFile",            "(ILjava/lang/String;FI)I",              (void*)nFontCreateFromFile },
1236{"rsnFontCreateFromAssetStream",     "(ILjava/lang/String;FII)I",             (void*)nFontCreateFromAssetStream },
1237{"rsnFontCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;FI)I",            (void*)nFontCreateFromAsset },
1238
1239{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
1240{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
1241{"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
1242{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;)V",            (void*)nElementGetSubElements },
1243
1244{"rsnTypeCreate",                    "(IIIIIZZ)I",                            (void*)nTypeCreate },
1245{"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
1246
1247{"rsnAllocationCreateTyped",         "(IIII)I",                               (void*)nAllocationCreateTyped },
1248{"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
1249{"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
1250
1251{"rsnAllocationCopyFromBitmap",      "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1252{"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1253
1254{"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
1255{"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
1256{"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
1257{"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
1258{"rsnAllocationData1D",              "(IIIII[FI)V",                           (void*)nAllocationData1D_f },
1259{"rsnAllocationElementData1D",       "(IIIII[BI)V",                           (void*)nAllocationElementData1D },
1260{"rsnAllocationData2D",              "(IIIIIIII[II)V",                        (void*)nAllocationData2D_i },
1261{"rsnAllocationData2D",              "(IIIIIIII[SI)V",                        (void*)nAllocationData2D_s },
1262{"rsnAllocationData2D",              "(IIIIIIII[BI)V",                        (void*)nAllocationData2D_b },
1263{"rsnAllocationData2D",              "(IIIIIIII[FI)V",                        (void*)nAllocationData2D_f },
1264{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
1265{"rsnAllocationRead",                "(II[S)V",                               (void*)nAllocationRead_s },
1266{"rsnAllocationRead",                "(II[B)V",                               (void*)nAllocationRead_b },
1267{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
1268{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
1269{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
1270{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
1271{"rsnAllocationGenerateMipmaps",     "(II)V",                                 (void*)nAllocationGenerateMipmaps },
1272
1273{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
1274{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
1275{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
1276{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
1277{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
1278{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
1279{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
1280{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
1281{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
1282{"rsnScriptSetVarObj",               "(IIII)V",                               (void*)nScriptSetVarObj },
1283
1284{"rsnScriptCBegin",                  "(I)V",                                  (void*)nScriptCBegin },
1285{"rsnScriptCSetScript",              "(I[BII)V",                              (void*)nScriptCSetScript },
1286{"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",  (void*)nScriptCCreate },
1287
1288{"rsnProgramStoreBegin",             "(III)V",                                (void*)nProgramStoreBegin },
1289{"rsnProgramStoreDepthFunc",         "(II)V",                                 (void*)nProgramStoreDepthFunc },
1290{"rsnProgramStoreDepthMask",         "(IZ)V",                                 (void*)nProgramStoreDepthMask },
1291{"rsnProgramStoreColorMask",         "(IZZZZ)V",                              (void*)nProgramStoreColorMask },
1292{"rsnProgramStoreBlendFunc",         "(III)V",                                (void*)nProgramStoreBlendFunc },
1293{"rsnProgramStoreDither",            "(IZ)V",                                 (void*)nProgramStoreDither },
1294{"rsnProgramStoreCreate",            "(I)I",                                  (void*)nProgramStoreCreate },
1295
1296{"rsnProgramBindConstants",          "(IIII)V",                               (void*)nProgramBindConstants },
1297{"rsnProgramBindTexture",            "(IIII)V",                               (void*)nProgramBindTexture },
1298{"rsnProgramBindSampler",            "(IIII)V",                               (void*)nProgramBindSampler },
1299
1300{"rsnProgramFragmentCreate",         "(ILjava/lang/String;[I)I",              (void*)nProgramFragmentCreate },
1301
1302{"rsnProgramRasterCreate",           "(IZZZ)I",                               (void*)nProgramRasterCreate },
1303{"rsnProgramRasterSetLineWidth",     "(IIF)V",                                (void*)nProgramRasterSetLineWidth },
1304{"rsnProgramRasterSetCullMode",      "(III)V",                                (void*)nProgramRasterSetCullMode },
1305
1306{"rsnProgramVertexCreate",           "(ILjava/lang/String;[I)I",              (void*)nProgramVertexCreate },
1307
1308{"rsnContextBindRootScript",         "(II)V",                                 (void*)nContextBindRootScript },
1309{"rsnContextBindProgramStore",       "(II)V",                                 (void*)nContextBindProgramStore },
1310{"rsnContextBindProgramFragment",    "(II)V",                                 (void*)nContextBindProgramFragment },
1311{"rsnContextBindProgramVertex",      "(II)V",                                 (void*)nContextBindProgramVertex },
1312{"rsnContextBindProgramRaster",      "(II)V",                                 (void*)nContextBindProgramRaster },
1313
1314{"rsnSamplerBegin",                  "(I)V",                                  (void*)nSamplerBegin },
1315{"rsnSamplerSet",                    "(III)V",                                (void*)nSamplerSet },
1316{"rsnSamplerSet2",                   "(IIF)V",                                (void*)nSamplerSet2 },
1317{"rsnSamplerCreate",                 "(I)I",                                  (void*)nSamplerCreate },
1318
1319{"rsnMeshCreate",                    "(III)I",                                (void*)nMeshCreate },
1320{"rsnMeshBindVertex",                "(IIII)V",                               (void*)nMeshBindVertex },
1321{"rsnMeshBindIndex",                 "(IIIII)V",                              (void*)nMeshBindIndex },
1322{"rsnMeshInitVertexAttribs",         "(II)V",                                 (void*)nMeshInitVertexAttribs },
1323
1324{"rsnMeshGetVertexBufferCount",      "(II)I",                                 (void*)nMeshGetVertexBufferCount },
1325{"rsnMeshGetIndexCount",             "(II)I",                                 (void*)nMeshGetIndexCount },
1326{"rsnMeshGetVertices",               "(II[II)V",                              (void*)nMeshGetVertices },
1327{"rsnMeshGetIndices",                "(II[I[II)V",                            (void*)nMeshGetIndices },
1328
1329};
1330
1331static int registerFuncs(JNIEnv *_env)
1332{
1333    return android::AndroidRuntime::registerNativeMethods(
1334            _env, classPathName, methods, NELEM(methods));
1335}
1336
1337// ---------------------------------------------------------------------------
1338
1339jint JNI_OnLoad(JavaVM* vm, void* reserved)
1340{
1341    JNIEnv* env = NULL;
1342    jint result = -1;
1343
1344    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1345        LOGE("ERROR: GetEnv failed\n");
1346        goto bail;
1347    }
1348    assert(env != NULL);
1349
1350    if (registerFuncs(env) < 0) {
1351        LOGE("ERROR: MediaPlayer native registration failed\n");
1352        goto bail;
1353    }
1354
1355    /* success -- return valid version number */
1356    result = JNI_VERSION_1_4;
1357
1358bail:
1359    return result;
1360}
1361