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