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