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