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