android_renderscript_RenderScript.cpp revision faa32b33b50ad941f631716dd0915e936bdc3ac5
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)
153{
154    LOG_API("nContextCreate");
155    return (jint)rsContextCreate((RsDevice)dev, ver);
156}
157
158static jint
159nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver,
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, 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}
508
509static void ReleaseBitmapCallback(void *bmp)
510{
511    SkBitmap const * nativeBitmap = (SkBitmap const *)bmp;
512    nativeBitmap->unlockPixels();
513}
514
515
516static void
517nAllocationData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jintArray data, int sizeBytes)
518{
519    jint len = _env->GetArrayLength(data);
520    LOG_API("nAllocation1DData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
521    jint *ptr = _env->GetIntArrayElements(data, NULL);
522    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
523    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
524}
525
526static void
527nAllocationData1D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jshortArray data, int sizeBytes)
528{
529    jint len = _env->GetArrayLength(data);
530    LOG_API("nAllocation1DData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
531    jshort *ptr = _env->GetShortArrayElements(data, NULL);
532    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
533    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
534}
535
536static void
537nAllocationData1D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jbyteArray data, int sizeBytes)
538{
539    jint len = _env->GetArrayLength(data);
540    LOG_API("nAllocation1DData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
541    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
542    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
543    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
544}
545
546static void
547nAllocationData1D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jfloatArray data, int sizeBytes)
548{
549    jint len = _env->GetArrayLength(data);
550    LOG_API("nAllocation1DData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
551    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
552    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
553    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
554}
555
556static void
557//    native void rsnAllocationElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
558nAllocationElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes)
559{
560    jint len = _env->GetArrayLength(data);
561    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
562    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
563    rsAllocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, compIdx, sizeBytes);
564    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
565}
566
567static void
568nAllocationData2D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
569                    jint w, jint h, jshortArray data, int sizeBytes)
570{
571    jint len = _env->GetArrayLength(data);
572    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);
573    jshort *ptr = _env->GetShortArrayElements(data, NULL);
574    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
575    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
576}
577
578static void
579nAllocationData2D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
580                    jint w, jint h, jbyteArray data, int sizeBytes)
581{
582    jint len = _env->GetArrayLength(data);
583    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);
584    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
585    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
586    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
587}
588
589static void
590nAllocationData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
591                    jint w, jint h, jintArray data, int sizeBytes)
592{
593    jint len = _env->GetArrayLength(data);
594    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);
595    jint *ptr = _env->GetIntArrayElements(data, NULL);
596    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
597    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
598}
599
600static void
601nAllocationData2D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
602                    jint w, jint h, jfloatArray data, int sizeBytes)
603{
604    jint len = _env->GetArrayLength(data);
605    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);
606    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
607    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
608    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
609}
610
611static void
612nAllocationData2D_alloc(JNIEnv *_env, jobject _this, RsContext con,
613                        jint dstAlloc, jint dstXoff, jint dstYoff,
614                        jint dstMip, jint dstFace,
615                        jint width, jint height,
616                        jint srcAlloc, jint srcXoff, jint srcYoff,
617                        jint srcMip, jint srcFace)
618{
619    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff, dstYoff,"
620            " dstMip(%i), dstFace(%i), width(%i), height(%i),"
621            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
622            con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
623            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
624
625    rsAllocationCopy2DRange(con,
626                            (RsAllocation)dstAlloc,
627                            dstXoff, dstYoff,
628                            dstMip, dstFace,
629                            width, height,
630                            (RsAllocation)srcAlloc,
631                            srcXoff, srcYoff,
632                            srcMip, srcFace);
633}
634
635static void
636nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
637{
638    jint len = _env->GetArrayLength(data);
639    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
640    jint *ptr = _env->GetIntArrayElements(data, NULL);
641    jsize length = _env->GetArrayLength(data);
642    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
643    _env->ReleaseIntArrayElements(data, ptr, 0);
644}
645
646static void
647nAllocationRead_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jshortArray data)
648{
649    jint len = _env->GetArrayLength(data);
650    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
651    jshort *ptr = _env->GetShortArrayElements(data, NULL);
652    jsize length = _env->GetArrayLength(data);
653    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
654    _env->ReleaseShortArrayElements(data, ptr, 0);
655}
656
657static void
658nAllocationRead_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jbyteArray data)
659{
660    jint len = _env->GetArrayLength(data);
661    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
662    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
663    jsize length = _env->GetArrayLength(data);
664    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
665    _env->ReleaseByteArrayElements(data, ptr, 0);
666}
667
668static void
669nAllocationRead_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jfloatArray data)
670{
671    jint len = _env->GetArrayLength(data);
672    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
673    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
674    jsize length = _env->GetArrayLength(data);
675    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
676    _env->ReleaseFloatArrayElements(data, ptr, 0);
677}
678
679static jint
680nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
681{
682    LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a);
683    return (jint) rsaAllocationGetType(con, (RsAllocation)a);
684}
685
686static void
687nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
688{
689    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
690    rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
691}
692
693static void
694nAllocationResize2D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX, jint dimY)
695{
696    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i), sizeY(%i)", con, (RsAllocation)alloc, dimX, dimY);
697    rsAllocationResize2D(con, (RsAllocation)alloc, dimX, dimY);
698}
699
700// -----------------------------------
701
702static int
703nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con, jint native_asset)
704{
705    LOGV("______nFileA3D %u", (uint32_t) native_asset);
706
707    Asset* asset = reinterpret_cast<Asset*>(native_asset);
708
709    jint id = (jint)rsaFileA3DCreateFromMemory(con, asset->getBuffer(false), asset->getLength());
710    return id;
711}
712
713static int
714nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path)
715{
716    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
717    if (mgr == NULL) {
718        return 0;
719    }
720
721    AutoJavaStringToUTF8 str(_env, _path);
722    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
723    if (asset == NULL) {
724        return 0;
725    }
726
727    jint id = (jint)rsaFileA3DCreateFromAsset(con, asset);
728    return id;
729}
730
731static int
732nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName)
733{
734    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
735    jint id = (jint)rsaFileA3DCreateFromFile(con, fileNameUTF.c_str());
736
737    return id;
738}
739
740static int
741nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D)
742{
743    int32_t numEntries = 0;
744    rsaFileA3DGetNumIndexEntries(con, &numEntries, (RsFile)fileA3D);
745    return numEntries;
746}
747
748static void
749nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
750{
751    LOGV("______nFileA3D %u", (uint32_t) fileA3D);
752    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
753
754    rsaFileA3DGetIndexEntries(con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
755
756    for(jint i = 0; i < numEntries; i ++) {
757        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
758        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
759    }
760
761    free(fileEntries);
762}
763
764static int
765nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint index)
766{
767    LOGV("______nFileA3D %u", (uint32_t) fileA3D);
768    jint id = (jint)rsaFileA3DGetEntryByIndex(con, (uint32_t)index, (RsFile)fileA3D);
769    return id;
770}
771
772// -----------------------------------
773
774static int
775nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con,
776                    jstring fileName, jfloat fontSize, jint dpi)
777{
778    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
779    jint id = (jint)rsFontCreateFromFile(con,
780                                         fileNameUTF.c_str(), fileNameUTF.length(),
781                                         fontSize, dpi);
782
783    return id;
784}
785
786static int
787nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con,
788                           jstring name, jfloat fontSize, jint dpi, jint native_asset)
789{
790    Asset* asset = reinterpret_cast<Asset*>(native_asset);
791    AutoJavaStringToUTF8 nameUTF(_env, name);
792
793    jint id = (jint)rsFontCreateFromMemory(con,
794                                           nameUTF.c_str(), nameUTF.length(),
795                                           fontSize, dpi,
796                                           asset->getBuffer(false), asset->getLength());
797    return id;
798}
799
800static int
801nFontCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path,
802                     jfloat fontSize, jint dpi)
803{
804    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
805    if (mgr == NULL) {
806        return 0;
807    }
808
809    AutoJavaStringToUTF8 str(_env, _path);
810    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
811    if (asset == NULL) {
812        return 0;
813    }
814
815    jint id = (jint)rsFontCreateFromMemory(con,
816                                           str.c_str(), str.length(),
817                                           fontSize, dpi,
818                                           asset->getBuffer(false), asset->getLength());
819    delete asset;
820    return id;
821}
822
823// -----------------------------------
824
825static void
826nScriptBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint script, jint alloc, jint slot)
827{
828    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
829    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
830}
831
832static void
833nScriptSetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
834{
835    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
836    rsScriptSetVarI(con, (RsScript)script, slot, val);
837}
838
839static void
840nScriptSetVarObj(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
841{
842    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
843    rsScriptSetVarObj(con, (RsScript)script, slot, (RsObjectBase)val);
844}
845
846static void
847nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
848{
849    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
850    rsScriptSetVarJ(con, (RsScript)script, slot, val);
851}
852
853static void
854nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
855{
856    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
857    rsScriptSetVarF(con, (RsScript)script, slot, val);
858}
859
860static void
861nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
862{
863    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
864    rsScriptSetVarD(con, (RsScript)script, slot, val);
865}
866
867static void
868nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
869{
870    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
871    jint len = _env->GetArrayLength(data);
872    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
873    rsScriptSetVarV(con, (RsScript)script, slot, ptr, len);
874    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
875}
876
877
878static void
879nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
880{
881    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
882
883    jint length = _env->GetArrayLength(timeZone);
884    jbyte* timeZone_ptr;
885    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
886
887    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
888
889    if (timeZone_ptr) {
890        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
891    }
892}
893
894static void
895nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
896{
897    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
898    rsScriptInvoke(con, (RsScript)obj, slot);
899}
900
901static void
902nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
903{
904    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
905    jint len = _env->GetArrayLength(data);
906    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
907    rsScriptInvokeV(con, (RsScript)script, slot, ptr, len);
908    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
909}
910
911static void
912nScriptForEach(JNIEnv *_env, jobject _this, RsContext con,
913               jint script, jint slot, jint ain, jint aout)
914{
915    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
916    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0);
917}
918static void
919nScriptForEachV(JNIEnv *_env, jobject _this, RsContext con,
920                jint script, jint slot, jint ain, jint aout, jbyteArray params)
921{
922    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
923    jint len = _env->GetArrayLength(params);
924    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
925    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len);
926    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
927}
928
929
930// -----------------------------------
931
932static jint
933nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con,
934               jstring resName, jstring cacheDir,
935               jbyteArray scriptRef, jint length)
936{
937    LOG_API("nScriptCCreate, con(%p)", con);
938
939    AutoJavaStringToUTF8 resNameUTF(_env, resName);
940    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
941    jint ret = 0;
942    jbyte* script_ptr = NULL;
943    jint _exception = 0;
944    jint remaining;
945    if (!scriptRef) {
946        _exception = 1;
947        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
948        goto exit;
949    }
950    if (length < 0) {
951        _exception = 1;
952        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
953        goto exit;
954    }
955    remaining = _env->GetArrayLength(scriptRef);
956    if (remaining < length) {
957        _exception = 1;
958        //jniThrowException(_env, "java/lang/IllegalArgumentException",
959        //        "length > script.length - offset");
960        goto exit;
961    }
962    script_ptr = (jbyte *)
963        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
964
965    //rsScriptCSetText(con, (const char *)script_ptr, length);
966
967    ret = (jint)rsScriptCCreate(con,
968                                resNameUTF.c_str(), resNameUTF.length(),
969                                cacheDirUTF.c_str(), cacheDirUTF.length(),
970                                (const char *)script_ptr, length);
971
972exit:
973    if (script_ptr) {
974        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
975                _exception ? JNI_ABORT: 0);
976    }
977
978    return ret;
979}
980
981// ---------------------------------------------------------------------------
982
983static jint
984nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con,
985                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
986                    jboolean depthMask, jboolean ditherEnable,
987                    jint srcFunc, jint destFunc,
988                    jint depthFunc)
989{
990    LOG_API("nProgramStoreCreate, con(%p)", con);
991    return (jint)rsProgramStoreCreate(con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
992                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
993                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
994}
995
996// ---------------------------------------------------------------------------
997
998static void
999nProgramBindConstants(JNIEnv *_env, jobject _this, RsContext con, jint vpv, jint slot, jint a)
1000{
1001    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
1002    rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a);
1003}
1004
1005static void
1006nProgramBindTexture(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1007{
1008    LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1009    rsProgramBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1010}
1011
1012static void
1013nProgramBindSampler(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1014{
1015    LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1016    rsProgramBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1017}
1018
1019// ---------------------------------------------------------------------------
1020
1021static jint
1022nProgramFragmentCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
1023{
1024    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1025    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1026    jint paramLen = _env->GetArrayLength(params);
1027
1028    LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, paramLen);
1029
1030    jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
1031    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1032    return ret;
1033}
1034
1035
1036// ---------------------------------------------------------------------------
1037
1038static jint
1039nProgramVertexCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
1040{
1041    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1042    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1043    jint paramLen = _env->GetArrayLength(params);
1044
1045    LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", con, paramLen);
1046
1047    jint ret = (jint)rsProgramVertexCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
1048    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1049    return ret;
1050}
1051
1052// ---------------------------------------------------------------------------
1053
1054static jint
1055nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSmooth,
1056                     jboolean lineSmooth, jboolean pointSprite, jfloat lineWidth, jint cull)
1057{
1058    LOG_API("nProgramRasterCreate, con(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)",
1059            con, pointSmooth, lineSmooth, pointSprite);
1060    return (jint)rsProgramRasterCreate(con, pointSmooth, lineSmooth, pointSprite, lineWidth, (RsCullMode)cull);
1061}
1062
1063
1064// ---------------------------------------------------------------------------
1065
1066static void
1067nContextBindRootScript(JNIEnv *_env, jobject _this, RsContext con, jint script)
1068{
1069    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
1070    rsContextBindRootScript(con, (RsScript)script);
1071}
1072
1073static void
1074nContextBindProgramStore(JNIEnv *_env, jobject _this, RsContext con, jint pfs)
1075{
1076    LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs);
1077    rsContextBindProgramStore(con, (RsProgramStore)pfs);
1078}
1079
1080static void
1081nContextBindProgramFragment(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1082{
1083    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
1084    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
1085}
1086
1087static void
1088nContextBindProgramVertex(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1089{
1090    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
1091    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
1092}
1093
1094static void
1095nContextBindProgramRaster(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1096{
1097    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
1098    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
1099}
1100
1101
1102// ---------------------------------------------------------------------------
1103
1104static jint
1105nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con, jint magFilter, jint minFilter,
1106               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1107{
1108    LOG_API("nSamplerCreate, con(%p)", con);
1109    return (jint)rsSamplerCreate(con,
1110                                 (RsSamplerValue)magFilter,
1111                                 (RsSamplerValue)minFilter,
1112                                 (RsSamplerValue)wrapS,
1113                                 (RsSamplerValue)wrapT,
1114                                 (RsSamplerValue)wrapR,
1115                                 aniso);
1116}
1117
1118// ---------------------------------------------------------------------------
1119
1120static jint
1121nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jintArray _vtx, jintArray _idx, jintArray _prim)
1122{
1123    LOG_API("nMeshCreate, con(%p)", con);
1124
1125    jint vtxLen = _env->GetArrayLength(_vtx);
1126    jint *vtxPtr = _env->GetIntArrayElements(_vtx, NULL);
1127    jint idxLen = _env->GetArrayLength(_idx);
1128    jint *idxPtr = _env->GetIntArrayElements(_idx, NULL);
1129    jint primLen = _env->GetArrayLength(_prim);
1130    jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
1131
1132    int id = (int)rsMeshCreate(con,
1133                               (RsAllocation *)vtxPtr, vtxLen,
1134                               (RsAllocation *)idxPtr, idxLen,
1135                               (uint32_t *)primPtr, primLen);
1136
1137    _env->ReleaseIntArrayElements(_vtx, vtxPtr, 0);
1138    _env->ReleaseIntArrayElements(_idx, idxPtr, 0);
1139    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
1140    return id;
1141}
1142
1143static jint
1144nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1145{
1146    LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1147    jint vtxCount = 0;
1148    rsaMeshGetVertexBufferCount(con, (RsMesh)mesh, &vtxCount);
1149    return vtxCount;
1150}
1151
1152static jint
1153nMeshGetIndexCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1154{
1155    LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1156    jint idxCount = 0;
1157    rsaMeshGetIndexCount(con, (RsMesh)mesh, &idxCount);
1158    return idxCount;
1159}
1160
1161static void
1162nMeshGetVertices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _ids, int numVtxIDs)
1163{
1164    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1165
1166    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
1167    rsaMeshGetVertices(con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
1168
1169    for(jint i = 0; i < numVtxIDs; i ++) {
1170        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]);
1171    }
1172
1173    free(allocs);
1174}
1175
1176static void
1177nMeshGetIndices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
1178{
1179    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1180
1181    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
1182    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
1183
1184    rsaMeshGetIndices(con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
1185
1186    for(jint i = 0; i < numIndices; i ++) {
1187        _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]);
1188        _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]);
1189    }
1190
1191    free(allocs);
1192    free(prims);
1193}
1194
1195// ---------------------------------------------------------------------------
1196
1197
1198static const char *classPathName = "android/renderscript/RenderScript";
1199
1200static JNINativeMethod methods[] = {
1201{"_nInit",                         "()V",                                     (void*)_nInit },
1202
1203{"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
1204{"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
1205{"nDeviceSetConfig",               "(III)V",                                  (void*)nDeviceSetConfig },
1206{"nContextGetUserMessage",         "(I[I)I",                                  (void*)nContextGetUserMessage },
1207{"nContextGetErrorMessage",        "(I)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1208{"nContextPeekMessage",            "(I[I)I",                                  (void*)nContextPeekMessage },
1209
1210{"nContextInitToClient",           "(I)V",                                    (void*)nContextInitToClient },
1211{"nContextDeinitToClient",         "(I)V",                                    (void*)nContextDeinitToClient },
1212
1213
1214// All methods below are thread protected in java.
1215{"rsnContextCreate",                 "(II)I",                                 (void*)nContextCreate },
1216{"rsnContextCreateGL",               "(IIIIIIIIIIIIFI)I",                     (void*)nContextCreateGL },
1217{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
1218{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
1219{"rsnContextSetSurface",             "(IIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
1220{"rsnContextSetSurfaceTexture",      "(IIILandroid/graphics/SurfaceTexture;)V", (void*)nContextSetSurfaceTexture },
1221{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
1222{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
1223{"rsnContextPause",                  "(I)V",                                  (void*)nContextPause },
1224{"rsnContextResume",                 "(I)V",                                  (void*)nContextResume },
1225{"rsnAssignName",                    "(II[B)V",                               (void*)nAssignName },
1226{"rsnGetName",                       "(II)Ljava/lang/String;",                (void*)nGetName },
1227{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
1228
1229{"rsnFileA3DCreateFromFile",         "(ILjava/lang/String;)I",                (void*)nFileA3DCreateFromFile },
1230{"rsnFileA3DCreateFromAssetStream",  "(II)I",                                 (void*)nFileA3DCreateFromAssetStream },
1231{"rsnFileA3DCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;)I",            (void*)nFileA3DCreateFromAsset },
1232{"rsnFileA3DGetNumIndexEntries",     "(II)I",                                 (void*)nFileA3DGetNumIndexEntries },
1233{"rsnFileA3DGetIndexEntries",        "(III[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
1234{"rsnFileA3DGetEntryByIndex",        "(III)I",                                (void*)nFileA3DGetEntryByIndex },
1235
1236{"rsnFontCreateFromFile",            "(ILjava/lang/String;FI)I",              (void*)nFontCreateFromFile },
1237{"rsnFontCreateFromAssetStream",     "(ILjava/lang/String;FII)I",             (void*)nFontCreateFromAssetStream },
1238{"rsnFontCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;FI)I",            (void*)nFontCreateFromAsset },
1239
1240{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
1241{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
1242{"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
1243{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;)V",            (void*)nElementGetSubElements },
1244
1245{"rsnTypeCreate",                    "(IIIIIZZ)I",                            (void*)nTypeCreate },
1246{"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
1247
1248{"rsnAllocationCreateTyped",         "(IIII)I",                               (void*)nAllocationCreateTyped },
1249{"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
1250{"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
1251
1252{"rsnAllocationCopyFromBitmap",      "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1253{"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1254
1255{"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
1256{"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
1257{"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
1258{"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
1259{"rsnAllocationData1D",              "(IIIII[FI)V",                           (void*)nAllocationData1D_f },
1260{"rsnAllocationElementData1D",       "(IIIII[BI)V",                           (void*)nAllocationElementData1D },
1261{"rsnAllocationData2D",              "(IIIIIIII[II)V",                        (void*)nAllocationData2D_i },
1262{"rsnAllocationData2D",              "(IIIIIIII[SI)V",                        (void*)nAllocationData2D_s },
1263{"rsnAllocationData2D",              "(IIIIIIII[BI)V",                        (void*)nAllocationData2D_b },
1264{"rsnAllocationData2D",              "(IIIIIIII[FI)V",                        (void*)nAllocationData2D_f },
1265{"rsnAllocationData2D",              "(IIIIIIIIIIIII)V",                      (void*)nAllocationData2D_alloc },
1266{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
1267{"rsnAllocationRead",                "(II[S)V",                               (void*)nAllocationRead_s },
1268{"rsnAllocationRead",                "(II[B)V",                               (void*)nAllocationRead_b },
1269{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
1270{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
1271{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
1272{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
1273{"rsnAllocationGenerateMipmaps",     "(II)V",                                 (void*)nAllocationGenerateMipmaps },
1274
1275{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
1276{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
1277{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
1278{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
1279{"rsnScriptForEach",                 "(IIIII)V",                              (void*)nScriptForEach },
1280{"rsnScriptForEach",                 "(IIIII[B)V",                            (void*)nScriptForEachV },
1281{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
1282{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
1283{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
1284{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
1285{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
1286{"rsnScriptSetVarObj",               "(IIII)V",                               (void*)nScriptSetVarObj },
1287
1288{"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;[BI)I",  (void*)nScriptCCreate },
1289
1290{"rsnProgramStoreCreate",            "(IZZZZZZIII)I",                         (void*)nProgramStoreCreate },
1291
1292{"rsnProgramBindConstants",          "(IIII)V",                               (void*)nProgramBindConstants },
1293{"rsnProgramBindTexture",            "(IIII)V",                               (void*)nProgramBindTexture },
1294{"rsnProgramBindSampler",            "(IIII)V",                               (void*)nProgramBindSampler },
1295
1296{"rsnProgramFragmentCreate",         "(ILjava/lang/String;[I)I",              (void*)nProgramFragmentCreate },
1297{"rsnProgramRasterCreate",           "(IZZZFI)I",                             (void*)nProgramRasterCreate },
1298{"rsnProgramVertexCreate",           "(ILjava/lang/String;[I)I",              (void*)nProgramVertexCreate },
1299
1300{"rsnContextBindRootScript",         "(II)V",                                 (void*)nContextBindRootScript },
1301{"rsnContextBindProgramStore",       "(II)V",                                 (void*)nContextBindProgramStore },
1302{"rsnContextBindProgramFragment",    "(II)V",                                 (void*)nContextBindProgramFragment },
1303{"rsnContextBindProgramVertex",      "(II)V",                                 (void*)nContextBindProgramVertex },
1304{"rsnContextBindProgramRaster",      "(II)V",                                 (void*)nContextBindProgramRaster },
1305
1306{"rsnSamplerCreate",                 "(IIIIIIF)I",                            (void*)nSamplerCreate },
1307
1308{"rsnMeshCreate",                    "(I[I[I[I)I",                            (void*)nMeshCreate },
1309
1310{"rsnMeshGetVertexBufferCount",      "(II)I",                                 (void*)nMeshGetVertexBufferCount },
1311{"rsnMeshGetIndexCount",             "(II)I",                                 (void*)nMeshGetIndexCount },
1312{"rsnMeshGetVertices",               "(II[II)V",                              (void*)nMeshGetVertices },
1313{"rsnMeshGetIndices",                "(II[I[II)V",                            (void*)nMeshGetIndices },
1314
1315};
1316
1317static int registerFuncs(JNIEnv *_env)
1318{
1319    return android::AndroidRuntime::registerNativeMethods(
1320            _env, classPathName, methods, NELEM(methods));
1321}
1322
1323// ---------------------------------------------------------------------------
1324
1325jint JNI_OnLoad(JavaVM* vm, void* reserved)
1326{
1327    JNIEnv* env = NULL;
1328    jint result = -1;
1329
1330    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1331        LOGE("ERROR: GetEnv failed\n");
1332        goto bail;
1333    }
1334    assert(env != NULL);
1335
1336    if (registerFuncs(env) < 0) {
1337        LOGE("ERROR: MediaPlayer native registration failed\n");
1338        goto bail;
1339    }
1340
1341    /* success -- return valid version number */
1342    result = JNI_VERSION_1_4;
1343
1344bail:
1345    return result;
1346}
1347