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