android_renderscript_RenderScript.cpp revision efd9b6fb2e0f31b50db089352118e5daeb268879
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 <ui/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
41#include <RenderScript.h>
42#include <RenderScriptEnv.h>
43
44//#define LOG_API LOGE
45#define LOG_API(...)
46
47using namespace android;
48
49// ---------------------------------------------------------------------------
50
51static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
52{
53    jclass npeClazz = env->FindClass(exc);
54    env->ThrowNew(npeClazz, msg);
55}
56
57static jfieldID gContextId = 0;
58static jfieldID gNativeBitmapID = 0;
59static jfieldID gTypeNativeCache = 0;
60
61static RsElement g_A_8 = NULL;
62static RsElement g_RGBA_4444 = NULL;
63static RsElement g_RGBA_8888 = NULL;
64static RsElement g_RGB_565 = NULL;
65
66static void _nInit(JNIEnv *_env, jclass _this)
67{
68    gContextId             = _env->GetFieldID(_this, "mContext", "I");
69
70    jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
71    gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
72
73    jclass typeClass = _env->FindClass("android/renderscript/Type");
74    gTypeNativeCache = _env->GetFieldID(typeClass, "mNativeCache", "I");
75}
76
77static void nInitElements(JNIEnv *_env, jobject _this, jint a8, jint rgba4444, jint rgba8888, jint rgb565)
78{
79    g_A_8 = reinterpret_cast<RsElement>(a8);
80    g_RGBA_4444 = reinterpret_cast<RsElement>(rgba4444);
81    g_RGBA_8888 = reinterpret_cast<RsElement>(rgba8888);
82    g_RGB_565 = reinterpret_cast<RsElement>(rgb565);
83}
84
85// ---------------------------------------------------------------------------
86
87static void
88nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str)
89{
90    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
91    LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj);
92
93    jint len = _env->GetArrayLength(str);
94    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
95    rsAssignName(con, (void *)obj, (const char *)cptr, len);
96    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
97}
98
99static void
100nObjDestroy(JNIEnv *_env, jobject _this, jint obj)
101{
102    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
103    LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
104    rsObjDestroy(con, (void *)obj);
105}
106
107static void
108nObjDestroyOOB(JNIEnv *_env, jobject _this, jint obj)
109{
110    // This function only differs from nObjDestroy in that it calls the
111    // special Out Of Band version of ObjDestroy which is thread safe.
112    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
113    LOG_API("nObjDestroyOOB, con(%p) obj(%p)", con, (void *)obj);
114    rsObjDestroyOOB(con, (void *)obj);
115}
116
117static jint
118nFileOpen(JNIEnv *_env, jobject _this, jbyteArray str)
119{
120    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
121    LOG_API("nFileOpen, con(%p)", con);
122
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, jobject wnd, jint ver, jboolean useDepth)
155{
156    LOG_API("nContextCreate");
157
158    if (wnd == NULL) {
159        not_valid_surface:
160        doThrow(_env, "java/lang/IllegalArgumentException",
161                "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface");
162        return 0;
163    }
164    jclass surface_class = _env->FindClass("android/view/Surface");
165    jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I");
166    Surface * window = (Surface*)_env->GetIntField(wnd, surfaceFieldID);
167    if (window == NULL)
168        goto not_valid_surface;
169
170    return (jint)rsContextCreate((RsDevice)dev, window, ver, useDepth);
171}
172
173static void
174nContextSetSurface(JNIEnv *_env, jobject _this, jobject wnd)
175{
176    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
177    LOG_API("nContextSetSurface, con(%p), surface(%p)", con, (Surface *)wnd);
178
179    Surface * window = NULL;
180    if (wnd == NULL) {
181
182    } else {
183        jclass surface_class = _env->FindClass("android/view/Surface");
184        jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I");
185        window = (Surface*)_env->GetIntField(wnd, surfaceFieldID);
186    }
187
188    rsContextSetSurface(con, window);
189}
190
191static void
192nContextDestroy(JNIEnv *_env, jobject _this, jint con)
193{
194    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
195    return rsContextDestroy((RsContext)con);
196}
197
198
199static void
200nContextPause(JNIEnv *_env, jobject _this)
201{
202    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
203    LOG_API("nContextPause, con(%p)", con);
204    rsContextPause(con);
205}
206
207static void
208nContextResume(JNIEnv *_env, jobject _this)
209{
210    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
211    LOG_API("nContextResume, con(%p)", con);
212    rsContextResume(con);
213}
214
215static jint
216nContextGetMessage(JNIEnv *_env, jobject _this, jintArray data, jboolean wait)
217{
218    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
219    jint len = _env->GetArrayLength(data);
220    LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
221    jint *ptr = _env->GetIntArrayElements(data, NULL);
222    size_t receiveLen;
223    int id = rsContextGetMessage(con, ptr, &receiveLen, len * 4, wait);
224    if (!id && receiveLen) {
225        LOGE("message receive buffer too small.  %i", receiveLen);
226    }
227    _env->ReleaseIntArrayElements(data, ptr, 0);
228    return id;
229}
230
231static void nContextInitToClient(JNIEnv *_env, jobject _this)
232{
233    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
234    LOG_API("nContextInitToClient, con(%p)", con);
235    rsContextInitToClient(con);
236}
237
238static void nContextDeinitToClient(JNIEnv *_env, jobject _this)
239{
240    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
241    LOG_API("nContextDeinitToClient, con(%p)", con);
242    rsContextDeinitToClient(con);
243}
244
245
246static void
247nElementBegin(JNIEnv *_env, jobject _this)
248{
249    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
250    LOG_API("nElementBegin, con(%p)", con);
251    rsElementBegin(con);
252}
253
254
255static void
256nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jboolean norm, jint bits, jstring name)
257{
258    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
259    const char* n = NULL;
260    if (name) {
261        n = _env->GetStringUTFChars(name, NULL);
262    }
263    LOG_API("nElementAdd, con(%p), kind(%i), type(%i), norm(%i), bits(%i)", con, kind, type, norm, bits);
264    rsElementAdd(con, (RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits, n);
265    if (n) {
266        _env->ReleaseStringUTFChars(name, n);
267    }
268}
269
270static jint
271nElementCreate(JNIEnv *_env, jobject _this)
272{
273    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
274    LOG_API("nElementCreate, con(%p)", con);
275    return (jint)rsElementCreate(con);
276}
277
278// -----------------------------------
279
280static void
281nTypeBegin(JNIEnv *_env, jobject _this, jint eID)
282{
283    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
284    LOG_API("nTypeBegin, con(%p) e(%p)", con, (RsElement)eID);
285    rsTypeBegin(con, (RsElement)eID);
286}
287
288static void
289nTypeAdd(JNIEnv *_env, jobject _this, jint dim, jint val)
290{
291    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
292    LOG_API("nTypeAdd, con(%p) dim(%i), val(%i)", con, dim, val);
293    rsTypeAdd(con, (RsDimension)dim, val);
294}
295
296static jint
297nTypeCreate(JNIEnv *_env, jobject _this)
298{
299    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
300    LOG_API("nTypeCreate, con(%p)", con);
301    return (jint)rsTypeCreate(con);
302}
303
304static void * SF_LoadInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
305{
306    ((int32_t *)buffer)[0] = _env->GetIntField(_obj, _field);
307    return ((uint8_t *)buffer) + 4;
308}
309
310static void * SF_LoadShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
311{
312    ((int16_t *)buffer)[0] = _env->GetShortField(_obj, _field);
313    return ((uint8_t *)buffer) + 2;
314}
315
316static void * SF_LoadByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
317{
318    ((int8_t *)buffer)[0] = _env->GetByteField(_obj, _field);
319    return ((uint8_t *)buffer) + 1;
320}
321
322static void * SF_LoadFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
323{
324    ((float *)buffer)[0] = _env->GetFloatField(_obj, _field);
325    return ((uint8_t *)buffer) + 4;
326}
327
328static void * SF_SaveInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
329{
330    _env->SetIntField(_obj, _field, ((int32_t *)buffer)[0]);
331    return ((uint8_t *)buffer) + 4;
332}
333
334static void * SF_SaveShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
335{
336    _env->SetShortField(_obj, _field, ((int16_t *)buffer)[0]);
337    return ((uint8_t *)buffer) + 2;
338}
339
340static void * SF_SaveByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
341{
342    _env->SetByteField(_obj, _field, ((int8_t *)buffer)[0]);
343    return ((uint8_t *)buffer) + 1;
344}
345
346static void * SF_SaveFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
347{
348    _env->SetFloatField(_obj, _field, ((float *)buffer)[0]);
349    return ((uint8_t *)buffer) + 4;
350}
351
352struct TypeFieldCache {
353    jfieldID field;
354    int bits;
355    void * (*ptr)(JNIEnv *, jobject, jfieldID, void *buffer);
356    void * (*readPtr)(JNIEnv *, jobject, jfieldID, void *buffer);
357};
358
359struct TypeCache {
360    int fieldCount;
361    int size;
362    TypeFieldCache fields[1];
363};
364
365//{"nTypeFinalDestroy",              "(Landroid/renderscript/Type;)V",       (void*)nTypeFinalDestroy },
366static void
367nTypeFinalDestroy(JNIEnv *_env, jobject _this, jobject _type)
368{
369    TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
370    free(tc);
371}
372
373// native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs);
374static void
375nTypeSetupFields(JNIEnv *_env, jobject _this, jobject _type, jintArray _types, jintArray _bits, jobjectArray _IDs)
376{
377    int fieldCount = _env->GetArrayLength(_types);
378    size_t structSize = sizeof(TypeCache) + (sizeof(TypeFieldCache) * (fieldCount-1));
379    TypeCache *tc = (TypeCache *)malloc(structSize);
380    memset(tc, 0, structSize);
381
382    TypeFieldCache *tfc = &tc->fields[0];
383    tc->fieldCount = fieldCount;
384    _env->SetIntField(_type, gTypeNativeCache, (jint)tc);
385
386    jint *fType = _env->GetIntArrayElements(_types, NULL);
387    jint *fBits = _env->GetIntArrayElements(_bits, NULL);
388    for (int ct=0; ct < fieldCount; ct++) {
389        jobject field = _env->GetObjectArrayElement(_IDs, ct);
390        tfc[ct].field = _env->FromReflectedField(field);
391        tfc[ct].bits = fBits[ct];
392
393        switch(fType[ct]) {
394        case RS_TYPE_FLOAT:
395            tfc[ct].ptr = SF_LoadFloat;
396            tfc[ct].readPtr = SF_SaveFloat;
397            break;
398        case RS_TYPE_UNSIGNED:
399        case RS_TYPE_SIGNED:
400            switch(tfc[ct].bits) {
401            case 32:
402                tfc[ct].ptr = SF_LoadInt;
403                tfc[ct].readPtr = SF_SaveInt;
404                break;
405            case 16:
406                tfc[ct].ptr = SF_LoadShort;
407                tfc[ct].readPtr = SF_SaveShort;
408                break;
409            case 8:
410                tfc[ct].ptr = SF_LoadByte;
411                tfc[ct].readPtr = SF_SaveByte;
412                break;
413            }
414            break;
415        }
416        tc->size += 4;
417    }
418
419    _env->ReleaseIntArrayElements(_types, fType, JNI_ABORT);
420    _env->ReleaseIntArrayElements(_bits, fBits, JNI_ABORT);
421}
422
423
424// -----------------------------------
425
426static jint
427nAllocationCreateTyped(JNIEnv *_env, jobject _this, jint e)
428{
429    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
430    LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e);
431    return (jint) rsAllocationCreateTyped(con, (RsElement)e);
432}
433
434static void
435nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip)
436{
437    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
438    LOG_API("nAllocationUploadToTexture, con(%p), a(%p), mip(%i)", con, (RsAllocation)a, mip);
439    rsAllocationUploadToTexture(con, (RsAllocation)a, mip);
440}
441
442static void
443nAllocationUploadToBufferObject(JNIEnv *_env, jobject _this, jint a)
444{
445    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
446    LOG_API("nAllocationUploadToBufferObject, con(%p), a(%p)", con, (RsAllocation)a);
447    rsAllocationUploadToBufferObject(con, (RsAllocation)a);
448}
449
450static RsElement SkBitmapToPredefined(SkBitmap::Config cfg)
451{
452    switch (cfg) {
453    case SkBitmap::kA8_Config:
454        return g_A_8;
455    case SkBitmap::kARGB_4444_Config:
456        return g_RGBA_4444;
457    case SkBitmap::kARGB_8888_Config:
458        return g_RGBA_8888;
459    case SkBitmap::kRGB_565_Config:
460        return g_RGB_565;
461
462    default:
463        break;
464    }
465    // If we don't have a conversion mark it as a user type.
466    LOGE("Unsupported bitmap type");
467    return NULL;
468}
469
470static int
471nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap)
472{
473    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
474    SkBitmap const * nativeBitmap =
475            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
476    const SkBitmap& bitmap(*nativeBitmap);
477    SkBitmap::Config config = bitmap.getConfig();
478
479    RsElement e = SkBitmapToPredefined(config);
480    if (e) {
481        bitmap.lockPixels();
482        const int w = bitmap.width();
483        const int h = bitmap.height();
484        const void* ptr = bitmap.getPixels();
485        jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
486        bitmap.unlockPixels();
487        return id;
488    }
489    return 0;
490}
491
492static int
493nAllocationCreateFromAssetStream(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jint native_asset)
494{
495    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
496
497    Asset* asset = reinterpret_cast<Asset*>(native_asset);
498    SkBitmap bitmap;
499    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
500            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
501
502    SkBitmap::Config config = bitmap.getConfig();
503
504    RsElement e = SkBitmapToPredefined(config);
505
506    if (e) {
507        bitmap.lockPixels();
508        const int w = bitmap.width();
509        const int h = bitmap.height();
510        const void* ptr = bitmap.getPixels();
511        jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
512        bitmap.unlockPixels();
513        return id;
514    }
515    return 0;
516}
517
518static int
519nAllocationCreateFromBitmapBoxed(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap)
520{
521    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
522    SkBitmap const * nativeBitmap =
523            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
524    const SkBitmap& bitmap(*nativeBitmap);
525    SkBitmap::Config config = bitmap.getConfig();
526
527    RsElement e = SkBitmapToPredefined(config);
528
529    if (e) {
530        bitmap.lockPixels();
531        const int w = bitmap.width();
532        const int h = bitmap.height();
533        const void* ptr = bitmap.getPixels();
534        jint id = (jint)rsAllocationCreateFromBitmapBoxed(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
535        bitmap.unlockPixels();
536        return id;
537    }
538    return 0;
539}
540
541
542static void
543nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data, int sizeBytes)
544{
545    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
546    jint len = _env->GetArrayLength(data);
547    LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
548    jint *ptr = _env->GetIntArrayElements(data, NULL);
549    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
550    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
551}
552
553static void
554nAllocationSubData1D_s(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jshortArray data, int sizeBytes)
555{
556    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
557    jint len = _env->GetArrayLength(data);
558    LOG_API("nAllocation1DSubData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
559    jshort *ptr = _env->GetShortArrayElements(data, NULL);
560    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
561    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
562}
563
564static void
565nAllocationSubData1D_b(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jbyteArray data, int sizeBytes)
566{
567    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
568    jint len = _env->GetArrayLength(data);
569    LOG_API("nAllocation1DSubData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
570    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
571    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
572    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
573}
574
575static void
576nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data, int sizeBytes)
577{
578    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
579    jint len = _env->GetArrayLength(data);
580    LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
581    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
582    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
583    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
584}
585
586static void
587nAllocationSubData2D_i(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data, int sizeBytes)
588{
589    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
590    jint len = _env->GetArrayLength(data);
591    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);
592    jint *ptr = _env->GetIntArrayElements(data, NULL);
593    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes);
594    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
595}
596
597static void
598nAllocationSubData2D_f(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jfloatArray data, int sizeBytes)
599{
600    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
601    jint len = _env->GetArrayLength(data);
602    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);
603    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
604    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes);
605    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
606}
607
608static void
609nAllocationRead_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data)
610{
611    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
612    jint len = _env->GetArrayLength(data);
613    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
614    jint *ptr = _env->GetIntArrayElements(data, NULL);
615    rsAllocationRead(con, (RsAllocation)alloc, ptr);
616    _env->ReleaseIntArrayElements(data, ptr, 0);
617}
618
619static void
620nAllocationRead_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data)
621{
622    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
623    jint len = _env->GetArrayLength(data);
624    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
625    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
626    rsAllocationRead(con, (RsAllocation)alloc, ptr);
627    _env->ReleaseFloatArrayElements(data, ptr, 0);
628}
629
630
631//{"nAllocationDataFromObject",      "(ILandroid/renderscript/Type;Ljava/lang/Object;)V",   (void*)nAllocationDataFromObject },
632static void
633nAllocationSubDataFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _type, jint offset, jobject _o)
634{
635    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
636    LOG_API("nAllocationDataFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc);
637
638    const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
639
640    void * bufAlloc = malloc(tc->size);
641    void * buf = bufAlloc;
642    for (int ct=0; ct < tc->fieldCount; ct++) {
643        const TypeFieldCache *tfc = &tc->fields[ct];
644        buf = tfc->ptr(_env, _o, tfc->field, buf);
645    }
646    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, 1, bufAlloc, tc->size);
647    free(bufAlloc);
648}
649
650static void
651nAllocationSubReadFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _type, jint offset, jobject _o)
652{
653    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
654    LOG_API("nAllocationReadFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc);
655
656    assert(offset == 0);
657
658    const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
659
660    void * bufAlloc = malloc(tc->size);
661    void * buf = bufAlloc;
662    rsAllocationRead(con, (RsAllocation)alloc, bufAlloc);
663
664    for (int ct=0; ct < tc->fieldCount; ct++) {
665        const TypeFieldCache *tfc = &tc->fields[ct];
666        buf = tfc->readPtr(_env, _o, tfc->field, buf);
667    }
668    free(bufAlloc);
669}
670
671
672// -----------------------------------
673
674static void
675nAdapter1DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc)
676{
677    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
678    LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc);
679    rsAdapter1DBindAllocation(con, (RsAdapter1D)adapter, (RsAllocation)alloc);
680}
681
682static void
683nAdapter1DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value)
684{
685    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
686    LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value);
687    rsAdapter1DSetConstraint(con, (RsAdapter1D)adapter, (RsDimension)dim, value);
688}
689
690static void
691nAdapter1DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data)
692{
693    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
694    jint len = _env->GetArrayLength(data);
695    LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
696    jint *ptr = _env->GetIntArrayElements(data, NULL);
697    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
698    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
699}
700
701static void
702nAdapter1DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jintArray data)
703{
704    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
705    jint len = _env->GetArrayLength(data);
706    LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
707    jint *ptr = _env->GetIntArrayElements(data, NULL);
708    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
709    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
710}
711
712static void
713nAdapter1DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data)
714{
715    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
716    jint len = _env->GetArrayLength(data);
717    LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
718    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
719    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
720    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
721}
722
723static void
724nAdapter1DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jfloatArray data)
725{
726    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
727    jint len = _env->GetArrayLength(data);
728    LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
729    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
730    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
731    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
732}
733
734static jint
735nAdapter1DCreate(JNIEnv *_env, jobject _this)
736{
737    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
738    LOG_API("nAdapter1DCreate, con(%p)", con);
739    return (jint)rsAdapter1DCreate(con);
740}
741
742// -----------------------------------
743
744static void
745nAdapter2DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc)
746{
747    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
748    LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc);
749    rsAdapter2DBindAllocation(con, (RsAdapter2D)adapter, (RsAllocation)alloc);
750}
751
752static void
753nAdapter2DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value)
754{
755    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
756    LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value);
757    rsAdapter2DSetConstraint(con, (RsAdapter2D)adapter, (RsDimension)dim, value);
758}
759
760static void
761nAdapter2DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data)
762{
763    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
764    jint len = _env->GetArrayLength(data);
765    LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
766    jint *ptr = _env->GetIntArrayElements(data, NULL);
767    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
768    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
769}
770
771static void
772nAdapter2DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data)
773{
774    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
775    jint len = _env->GetArrayLength(data);
776    LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
777    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
778    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
779    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
780}
781
782static void
783nAdapter2DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jintArray data)
784{
785    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
786    jint len = _env->GetArrayLength(data);
787    LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
788            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
789    jint *ptr = _env->GetIntArrayElements(data, NULL);
790    rsAdapter2DSubData(con, (RsAdapter2D)adapter, xoff, yoff, w, h, ptr);
791    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
792}
793
794static void
795nAdapter2DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jfloatArray data)
796{
797    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
798    jint len = _env->GetArrayLength(data);
799    LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
800            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
801    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
802    rsAdapter2DSubData(con, (RsAdapter1D)adapter, xoff, yoff, w, h, ptr);
803    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
804}
805
806static jint
807nAdapter2DCreate(JNIEnv *_env, jobject _this)
808{
809    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
810    LOG_API("nAdapter2DCreate, con(%p)", con);
811    return (jint)rsAdapter2DCreate(con);
812}
813
814// -----------------------------------
815
816static void
817nScriptBindAllocation(JNIEnv *_env, jobject _this, jint script, jint alloc, jint slot)
818{
819    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
820    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
821    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
822}
823
824static void
825nScriptSetClearColor(JNIEnv *_env, jobject _this, jint script, jfloat r, jfloat g, jfloat b, jfloat a)
826{
827    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
828    LOG_API("nScriptSetClearColor, con(%p), s(%p), r(%f), g(%f), b(%f), a(%f)", con, (void *)script, r, g, b, a);
829    rsScriptSetClearColor(con, (RsScript)script, r, g, b, a);
830}
831
832static void
833nScriptSetClearDepth(JNIEnv *_env, jobject _this, jint script, jfloat d)
834{
835    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
836    LOG_API("nScriptCSetClearDepth, con(%p), s(%p), depth(%f)", con, (void *)script, d);
837    rsScriptSetClearDepth(con, (RsScript)script, d);
838}
839
840static void
841nScriptSetClearStencil(JNIEnv *_env, jobject _this, jint script, jint stencil)
842{
843    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
844    LOG_API("nScriptCSetClearStencil, con(%p), s(%p), stencil(%i)", con, (void *)script, stencil);
845    rsScriptSetClearStencil(con, (RsScript)script, stencil);
846}
847
848static void
849nScriptSetTimeZone(JNIEnv *_env, jobject _this, jint script, jbyteArray timeZone)
850{
851    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
852    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
853
854    jint length = _env->GetArrayLength(timeZone);
855    jbyte* timeZone_ptr;
856    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
857
858    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
859
860    if (timeZone_ptr) {
861        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
862    }
863}
864
865static void
866nScriptSetType(JNIEnv *_env, jobject _this, jint type, jboolean writable, jstring _str, jint slot)
867{
868    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
869    LOG_API("nScriptCAddType, con(%p), type(%p), writable(%i), slot(%i)", con, (RsType)type, writable, slot);
870    const char* n = NULL;
871    if (_str) {
872        n = _env->GetStringUTFChars(_str, NULL);
873    }
874    rsScriptSetType(con, (RsType)type, slot, writable, n);
875    if (n) {
876        _env->ReleaseStringUTFChars(_str, n);
877    }
878}
879
880static void
881nScriptSetInvoke(JNIEnv *_env, jobject _this, jstring _str, jint slot)
882{
883    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
884    LOG_API("nScriptSetInvoke, con(%p)", con);
885    const char* n = NULL;
886    if (_str) {
887        n = _env->GetStringUTFChars(_str, NULL);
888    }
889    rsScriptSetInvoke(con, n, slot);
890    if (n) {
891        _env->ReleaseStringUTFChars(_str, n);
892    }
893}
894
895static void
896nScriptInvoke(JNIEnv *_env, jobject _this, jint obj, jint slot)
897{
898    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
899    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
900    rsScriptInvoke(con, (RsScript)obj, slot);
901}
902
903static void
904nScriptSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot)
905{
906    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
907    LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot);
908    rsScriptSetRoot(con, isRoot);
909}
910
911// -----------------------------------
912
913static void
914nScriptCBegin(JNIEnv *_env, jobject _this)
915{
916    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
917    LOG_API("nScriptCBegin, con(%p)", con);
918    rsScriptCBegin(con);
919}
920
921static void
922nScriptCSetScript(JNIEnv *_env, jobject _this, jbyteArray scriptRef,
923                  jint offset, jint length)
924{
925    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
926    LOG_API("!!! nScriptCSetScript, con(%p)", con);
927    jint _exception = 0;
928    jint remaining;
929    jbyte* script_base = 0;
930    jbyte* script_ptr;
931    if (!scriptRef) {
932        _exception = 1;
933        //_env->ThrowNew(IAEClass, "script == null");
934        goto exit;
935    }
936    if (offset < 0) {
937        _exception = 1;
938        //_env->ThrowNew(IAEClass, "offset < 0");
939        goto exit;
940    }
941    if (length < 0) {
942        _exception = 1;
943        //_env->ThrowNew(IAEClass, "length < 0");
944        goto exit;
945    }
946    remaining = _env->GetArrayLength(scriptRef) - offset;
947    if (remaining < length) {
948        _exception = 1;
949        //_env->ThrowNew(IAEClass, "length > script.length - offset");
950        goto exit;
951    }
952    script_base = (jbyte *)
953        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
954    script_ptr = script_base + offset;
955
956    rsScriptCSetText(con, (const char *)script_ptr, length);
957
958exit:
959    if (script_base) {
960        _env->ReleasePrimitiveArrayCritical(scriptRef, script_base,
961                _exception ? JNI_ABORT: 0);
962    }
963}
964
965static jint
966nScriptCCreate(JNIEnv *_env, jobject _this)
967{
968    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
969    LOG_API("nScriptCCreate, con(%p)", con);
970    return (jint)rsScriptCCreate(con);
971}
972
973static void
974nScriptCAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value)
975{
976    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
977    const char* n = _env->GetStringUTFChars(name, NULL);
978    LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value);
979    rsScriptCSetDefineI32(con, n, value);
980    _env->ReleaseStringUTFChars(name, n);
981}
982
983static void
984nScriptCAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value)
985{
986    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
987    const char* n = _env->GetStringUTFChars(name, NULL);
988    LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value);
989    rsScriptCSetDefineF(con, n, value);
990    _env->ReleaseStringUTFChars(name, n);
991}
992
993// ---------------------------------------------------------------------------
994
995static void
996nProgramFragmentStoreBegin(JNIEnv *_env, jobject _this, jint in, jint out)
997{
998    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
999    LOG_API("nProgramFragmentStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
1000    rsProgramFragmentStoreBegin(con, (RsElement)in, (RsElement)out);
1001}
1002
1003static void
1004nProgramFragmentStoreDepthFunc(JNIEnv *_env, jobject _this, jint func)
1005{
1006    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1007    LOG_API("nProgramFragmentStoreDepthFunc, con(%p), func(%i)", con, func);
1008    rsProgramFragmentStoreDepthFunc(con, (RsDepthFunc)func);
1009}
1010
1011static void
1012nProgramFragmentStoreDepthMask(JNIEnv *_env, jobject _this, jboolean enable)
1013{
1014    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1015    LOG_API("nProgramFragmentStoreDepthMask, con(%p), enable(%i)", con, enable);
1016    rsProgramFragmentStoreDepthMask(con, enable);
1017}
1018
1019static void
1020nProgramFragmentStoreColorMask(JNIEnv *_env, jobject _this, jboolean r, jboolean g, jboolean b, jboolean a)
1021{
1022    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1023    LOG_API("nProgramFragmentStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
1024    rsProgramFragmentStoreColorMask(con, r, g, b, a);
1025}
1026
1027static void
1028nProgramFragmentStoreBlendFunc(JNIEnv *_env, jobject _this, int src, int dst)
1029{
1030    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1031    LOG_API("nProgramFragmentStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
1032    rsProgramFragmentStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
1033}
1034
1035static void
1036nProgramFragmentStoreDither(JNIEnv *_env, jobject _this, jboolean enable)
1037{
1038    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1039    LOG_API("nProgramFragmentStoreDither, con(%p), enable(%i)", con, enable);
1040    rsProgramFragmentStoreDither(con, enable);
1041}
1042
1043static jint
1044nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this)
1045{
1046    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1047    LOG_API("nProgramFragmentStoreCreate, con(%p)", con);
1048
1049    return (jint)rsProgramFragmentStoreCreate(con);
1050}
1051
1052// ---------------------------------------------------------------------------
1053
1054static void
1055nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out, jboolean pointSpriteEnable)
1056{
1057    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1058    LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p) PointSprite(%i)", con, (RsElement)in, (RsElement)out, pointSpriteEnable);
1059    rsProgramFragmentBegin(con, (RsElement)in, (RsElement)out, pointSpriteEnable);
1060}
1061
1062static void
1063nProgramFragmentBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a)
1064{
1065    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1066    LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1067    rsProgramFragmentBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1068}
1069
1070static void
1071nProgramFragmentBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a)
1072{
1073    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1074    LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1075    rsProgramFragmentBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1076}
1077
1078static void
1079nProgramFragmentSetSlot(JNIEnv *_env, jobject _this, jint slot, jboolean enable, jint env, jint vt)
1080{
1081    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1082    LOG_API("nProgramFragmentSetType, con(%p), slot(%i), enable(%i), env(%i), vt(%p)", con, slot, enable, env, (RsType)vt);
1083    rsProgramFragmentSetSlot(con, slot, enable, (RsTexEnvMode)env, (RsType)vt);
1084}
1085
1086static jint
1087nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable)
1088{
1089    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1090    LOG_API("nProgramFragmentCreate, con(%p)", con);
1091    return (jint)rsProgramFragmentCreate(con);
1092}
1093
1094// ---------------------------------------------------------------------------
1095
1096static void
1097nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out)
1098{
1099    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1100    LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
1101    rsProgramVertexBegin(con, (RsElement)in, (RsElement)out);
1102}
1103
1104static void
1105nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint a)
1106{
1107    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1108    LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), a(%p)", con, (RsProgramVertex)vpv, (RsAllocation)a);
1109    rsProgramVertexBindAllocation(con, (RsProgramFragment)vpv, (RsAllocation)a);
1110}
1111
1112static void
1113nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable)
1114{
1115    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1116    LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable);
1117    rsProgramVertexSetTextureMatrixEnable(con, enable);
1118}
1119
1120static void
1121nProgramVertexAddLight(JNIEnv *_env, jobject _this, jint light)
1122{
1123    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1124    LOG_API("nProgramVertexAddLight, con(%p), light(%p)", con, (RsLight)light);
1125    rsProgramVertexAddLight(con, (RsLight)light);
1126}
1127
1128static jint
1129nProgramVertexCreate(JNIEnv *_env, jobject _this)
1130{
1131    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1132    LOG_API("nProgramVertexCreate, con(%p)", con);
1133    return (jint)rsProgramVertexCreate(con);
1134}
1135
1136
1137// ---------------------------------------------------------------------------
1138
1139static jint
1140nProgramRasterCreate(JNIEnv *_env, jobject _this, jint in, jint out,
1141                     jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite)
1142{
1143    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1144    LOG_API("nProgramRasterCreate, con(%p), in(%p), out(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)",
1145            con, (RsElement)in, (RsElement)out, pointSmooth, lineSmooth, pointSprite);
1146    return (jint)rsProgramRasterCreate(con, (RsElement)in, (RsElement)out, pointSmooth, lineSmooth, pointSprite);
1147}
1148
1149static void
1150nProgramRasterSetPointSize(JNIEnv *_env, jobject _this, jint vpr, jfloat v)
1151{
1152    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1153    LOG_API("nProgramRasterSetPointSize, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
1154    rsProgramRasterSetPointSize(con, (RsProgramFragment)vpr, v);
1155}
1156
1157static void
1158nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, jint vpr, jfloat v)
1159{
1160    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1161    LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
1162    rsProgramRasterSetLineWidth(con, (RsProgramFragment)vpr, v);
1163}
1164
1165
1166// ---------------------------------------------------------------------------
1167
1168static void
1169nContextBindRootScript(JNIEnv *_env, jobject _this, jint script)
1170{
1171    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1172    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
1173    rsContextBindRootScript(con, (RsScript)script);
1174}
1175
1176static void
1177nContextBindProgramFragmentStore(JNIEnv *_env, jobject _this, jint pfs)
1178{
1179    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1180    LOG_API("nContextBindProgramFragmentStore, con(%p), pfs(%p)", con, (RsProgramFragmentStore)pfs);
1181    rsContextBindProgramFragmentStore(con, (RsProgramFragmentStore)pfs);
1182}
1183
1184static void
1185nContextBindProgramFragment(JNIEnv *_env, jobject _this, jint pf)
1186{
1187    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1188    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
1189    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
1190}
1191
1192static void
1193nContextBindProgramVertex(JNIEnv *_env, jobject _this, jint pf)
1194{
1195    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1196    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
1197    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
1198}
1199
1200static void
1201nContextBindProgramRaster(JNIEnv *_env, jobject _this, jint pf)
1202{
1203    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1204    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
1205    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
1206}
1207
1208static void
1209nContextAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value)
1210{
1211    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1212    const char* n = _env->GetStringUTFChars(name, NULL);
1213    LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value);
1214    rsContextSetDefineI32(con, n, value);
1215    _env->ReleaseStringUTFChars(name, n);
1216}
1217
1218static void
1219nContextAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value)
1220{
1221    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1222    const char* n = _env->GetStringUTFChars(name, NULL);
1223    LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value);
1224    rsContextSetDefineF(con, n, value);
1225    _env->ReleaseStringUTFChars(name, n);
1226}
1227
1228
1229// ---------------------------------------------------------------------------
1230
1231static void
1232nSamplerBegin(JNIEnv *_env, jobject _this)
1233{
1234    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1235    LOG_API("nSamplerBegin, con(%p)", con);
1236    rsSamplerBegin(con);
1237}
1238
1239static void
1240nSamplerSet(JNIEnv *_env, jobject _this, jint p, jint v)
1241{
1242    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1243    LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v);
1244    rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v);
1245}
1246
1247static jint
1248nSamplerCreate(JNIEnv *_env, jobject _this)
1249{
1250    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1251    LOG_API("nSamplerCreate, con(%p)", con);
1252    return (jint)rsSamplerCreate(con);
1253}
1254
1255// ---------------------------------------------------------------------------
1256
1257static void
1258nLightBegin(JNIEnv *_env, jobject _this)
1259{
1260    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1261    LOG_API("nLightBegin, con(%p)", con);
1262    rsLightBegin(con);
1263}
1264
1265static void
1266nLightSetIsMono(JNIEnv *_env, jobject _this, jboolean isMono)
1267{
1268    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1269    LOG_API("nLightSetIsMono, con(%p), isMono(%i)", con, isMono);
1270    rsLightSetMonochromatic(con, isMono);
1271}
1272
1273static void
1274nLightSetIsLocal(JNIEnv *_env, jobject _this, jboolean isLocal)
1275{
1276    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1277    LOG_API("nLightSetIsLocal, con(%p), isLocal(%i)", con, isLocal);
1278    rsLightSetLocal(con, isLocal);
1279}
1280
1281static jint
1282nLightCreate(JNIEnv *_env, jobject _this)
1283{
1284    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1285    LOG_API("nLightCreate, con(%p)", con);
1286    return (jint)rsLightCreate(con);
1287}
1288
1289static void
1290nLightSetColor(JNIEnv *_env, jobject _this, jint light, float r, float g, float b)
1291{
1292    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1293    LOG_API("nLightSetColor, con(%p), light(%p), r(%f), g(%f), b(%f)", con, (RsLight)light, r, g, b);
1294    rsLightSetColor(con, (RsLight)light, r, g, b);
1295}
1296
1297static void
1298nLightSetPosition(JNIEnv *_env, jobject _this, jint light, float x, float y, float z)
1299{
1300    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1301    LOG_API("nLightSetPosition, con(%p), light(%p), x(%f), y(%f), z(%f)", con, (RsLight)light, x, y, z);
1302    rsLightSetPosition(con, (RsLight)light, x, y, z);
1303}
1304
1305// ---------------------------------------------------------------------------
1306
1307static jint
1308nSimpleMeshCreate(JNIEnv *_env, jobject _this, jint batchID, jint indexID, jintArray vtxIDs, jint primID)
1309{
1310    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1311    jint len = _env->GetArrayLength(vtxIDs);
1312    LOG_API("nSimpleMeshCreate, con(%p), batchID(%i), indexID(%i), vtxIDs.len(%i), primID(%i)",
1313            con, batchID, indexID, len, primID);
1314    jint *ptr = _env->GetIntArrayElements(vtxIDs, NULL);
1315    int id = (int)rsSimpleMeshCreate(con, (void *)batchID, (void *)indexID, (void **)ptr, len, primID);
1316    _env->ReleaseIntArrayElements(vtxIDs, ptr, 0/*JNI_ABORT*/);
1317    return id;
1318}
1319
1320static void
1321nSimpleMeshBindVertex(JNIEnv *_env, jobject _this, jint s, jint alloc, jint slot)
1322{
1323    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1324    LOG_API("nSimpleMeshBindVertex, con(%p), SimpleMesh(%p), Alloc(%p), slot(%i)", con, (RsSimpleMesh)s, (RsAllocation)alloc, slot);
1325    rsSimpleMeshBindVertex(con, (RsSimpleMesh)s, (RsAllocation)alloc, slot);
1326}
1327
1328static void
1329nSimpleMeshBindIndex(JNIEnv *_env, jobject _this, jint s, jint alloc)
1330{
1331    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1332    LOG_API("nSimpleMeshBindIndex, con(%p), SimpleMesh(%p), Alloc(%p)", con, (RsSimpleMesh)s, (RsAllocation)alloc);
1333    rsSimpleMeshBindIndex(con, (RsSimpleMesh)s, (RsAllocation)alloc);
1334}
1335
1336// ---------------------------------------------------------------------------
1337
1338
1339static const char *classPathName = "android/renderscript/RenderScript";
1340
1341static JNINativeMethod methods[] = {
1342{"_nInit",                         "()V",                                  (void*)_nInit },
1343{"nInitElements",                  "(IIII)V",                              (void*)nInitElements },
1344
1345{"nDeviceCreate",                  "()I",                                  (void*)nDeviceCreate },
1346{"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
1347{"nDeviceSetConfig",               "(III)V",                               (void*)nDeviceSetConfig },
1348{"nContextCreate",                 "(ILandroid/view/Surface;IZ)I",         (void*)nContextCreate },
1349{"nContextSetSurface",             "(Landroid/view/Surface;)V",            (void*)nContextSetSurface },
1350{"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
1351{"nContextPause",                  "()V",                                  (void*)nContextPause },
1352{"nContextResume",                 "()V",                                  (void*)nContextResume },
1353{"nAssignName",                    "(I[B)V",                               (void*)nAssignName },
1354{"nObjDestroy",                    "(I)V",                                 (void*)nObjDestroy },
1355{"nObjDestroyOOB",                 "(I)V",                                 (void*)nObjDestroyOOB },
1356{"nContextGetMessage",             "([IZ)I",                               (void*)nContextGetMessage },
1357{"nContextInitToClient",           "()V",                                  (void*)nContextInitToClient },
1358{"nContextDeinitToClient",         "()V",                                  (void*)nContextDeinitToClient },
1359
1360{"nFileOpen",                      "([B)I",                                (void*)nFileOpen },
1361
1362{"nElementBegin",                  "()V",                                  (void*)nElementBegin },
1363{"nElementAdd",                    "(IIZILjava/lang/String;)V",            (void*)nElementAdd },
1364{"nElementCreate",                 "()I",                                  (void*)nElementCreate },
1365
1366{"nTypeBegin",                     "(I)V",                                 (void*)nTypeBegin },
1367{"nTypeAdd",                       "(II)V",                                (void*)nTypeAdd },
1368{"nTypeCreate",                    "()I",                                  (void*)nTypeCreate },
1369{"nTypeFinalDestroy",              "(Landroid/renderscript/Type;)V",       (void*)nTypeFinalDestroy },
1370{"nTypeSetupFields",               "(Landroid/renderscript/Type;[I[I[Ljava/lang/reflect/Field;)V", (void*)nTypeSetupFields },
1371
1372{"nAllocationCreateTyped",         "(I)I",                                 (void*)nAllocationCreateTyped },
1373{"nAllocationCreateFromBitmap",    "(IZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmap },
1374{"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I",      (void*)nAllocationCreateFromBitmapBoxed },
1375{"nAllocationCreateFromAssetStream","(IZI)I",                              (void*)nAllocationCreateFromAssetStream },
1376{"nAllocationUploadToTexture",     "(II)V",                                (void*)nAllocationUploadToTexture },
1377{"nAllocationUploadToBufferObject","(I)V",                                 (void*)nAllocationUploadToBufferObject },
1378{"nAllocationSubData1D",           "(III[II)V",                            (void*)nAllocationSubData1D_i },
1379{"nAllocationSubData1D",           "(III[SI)V",                            (void*)nAllocationSubData1D_s },
1380{"nAllocationSubData1D",           "(III[BI)V",                            (void*)nAllocationSubData1D_b },
1381{"nAllocationSubData1D",           "(III[FI)V",                            (void*)nAllocationSubData1D_f },
1382{"nAllocationSubData2D",           "(IIIII[II)V",                          (void*)nAllocationSubData2D_i },
1383{"nAllocationSubData2D",           "(IIIII[FI)V",                          (void*)nAllocationSubData2D_f },
1384{"nAllocationRead",                "(I[I)V",                               (void*)nAllocationRead_i },
1385{"nAllocationRead",                "(I[F)V",                               (void*)nAllocationRead_f },
1386{"nAllocationSubDataFromObject",   "(ILandroid/renderscript/Type;ILjava/lang/Object;)V",   (void*)nAllocationSubDataFromObject },
1387{"nAllocationSubReadFromObject",   "(ILandroid/renderscript/Type;ILjava/lang/Object;)V",   (void*)nAllocationSubReadFromObject },
1388
1389{"nAdapter1DBindAllocation",       "(II)V",                                (void*)nAdapter1DBindAllocation },
1390{"nAdapter1DSetConstraint",        "(III)V",                               (void*)nAdapter1DSetConstraint },
1391{"nAdapter1DData",                 "(I[I)V",                               (void*)nAdapter1DData_i },
1392{"nAdapter1DData",                 "(I[F)V",                               (void*)nAdapter1DData_f },
1393{"nAdapter1DSubData",              "(III[I)V",                             (void*)nAdapter1DSubData_i },
1394{"nAdapter1DSubData",              "(III[F)V",                             (void*)nAdapter1DSubData_f },
1395{"nAdapter1DCreate",               "()I",                                  (void*)nAdapter1DCreate },
1396
1397{"nAdapter2DBindAllocation",       "(II)V",                                (void*)nAdapter2DBindAllocation },
1398{"nAdapter2DSetConstraint",        "(III)V",                               (void*)nAdapter2DSetConstraint },
1399{"nAdapter2DData",                 "(I[I)V",                               (void*)nAdapter2DData_i },
1400{"nAdapter2DData",                 "(I[F)V",                               (void*)nAdapter2DData_f },
1401{"nAdapter2DSubData",              "(IIIII[I)V",                           (void*)nAdapter2DSubData_i },
1402{"nAdapter2DSubData",              "(IIIII[F)V",                           (void*)nAdapter2DSubData_f },
1403{"nAdapter2DCreate",               "()I",                                  (void*)nAdapter2DCreate },
1404
1405{"nScriptBindAllocation",          "(III)V",                               (void*)nScriptBindAllocation },
1406{"nScriptSetClearColor",           "(IFFFF)V",                             (void*)nScriptSetClearColor },
1407{"nScriptSetClearDepth",           "(IF)V",                                (void*)nScriptSetClearDepth },
1408{"nScriptSetClearStencil",         "(II)V",                                (void*)nScriptSetClearStencil },
1409{"nScriptSetTimeZone",             "(I[B)V",                               (void*)nScriptSetTimeZone },
1410{"nScriptSetType",                 "(IZLjava/lang/String;I)V",             (void*)nScriptSetType },
1411{"nScriptSetRoot",                 "(Z)V",                                 (void*)nScriptSetRoot },
1412{"nScriptSetInvokable",            "(Ljava/lang/String;I)V",               (void*)nScriptSetInvoke },
1413{"nScriptInvoke",                  "(II)V",                                (void*)nScriptInvoke },
1414
1415{"nScriptCBegin",                  "()V",                                  (void*)nScriptCBegin },
1416{"nScriptCSetScript",              "([BII)V",                              (void*)nScriptCSetScript },
1417{"nScriptCCreate",                 "()I",                                  (void*)nScriptCCreate },
1418{"nScriptCAddDefineI32",           "(Ljava/lang/String;I)V",               (void*)nScriptCAddDefineI32 },
1419{"nScriptCAddDefineF",             "(Ljava/lang/String;F)V",               (void*)nScriptCAddDefineF },
1420
1421{"nProgramFragmentStoreBegin",     "(II)V",                                (void*)nProgramFragmentStoreBegin },
1422{"nProgramFragmentStoreDepthFunc", "(I)V",                                 (void*)nProgramFragmentStoreDepthFunc },
1423{"nProgramFragmentStoreDepthMask", "(Z)V",                                 (void*)nProgramFragmentStoreDepthMask },
1424{"nProgramFragmentStoreColorMask", "(ZZZZ)V",                              (void*)nProgramFragmentStoreColorMask },
1425{"nProgramFragmentStoreBlendFunc", "(II)V",                                (void*)nProgramFragmentStoreBlendFunc },
1426{"nProgramFragmentStoreDither",    "(Z)V",                                 (void*)nProgramFragmentStoreDither },
1427{"nProgramFragmentStoreCreate",    "()I",                                  (void*)nProgramFragmentStoreCreate },
1428
1429{"nProgramFragmentBegin",          "(IIZ)V",                               (void*)nProgramFragmentBegin },
1430{"nProgramFragmentBindTexture",    "(III)V",                               (void*)nProgramFragmentBindTexture },
1431{"nProgramFragmentBindSampler",    "(III)V",                               (void*)nProgramFragmentBindSampler },
1432{"nProgramFragmentSetSlot",        "(IZII)V",                              (void*)nProgramFragmentSetSlot },
1433{"nProgramFragmentCreate",         "()I",                                  (void*)nProgramFragmentCreate },
1434
1435{"nProgramRasterCreate",           "(IIZZZ)I",                             (void*)nProgramRasterCreate },
1436{"nProgramRasterSetPointSize",     "(IF)V",                                (void*)nProgramRasterSetPointSize },
1437{"nProgramRasterSetLineWidth",     "(IF)V",                                (void*)nProgramRasterSetLineWidth },
1438
1439{"nProgramVertexBindAllocation",   "(II)V",                                (void*)nProgramVertexBindAllocation },
1440{"nProgramVertexBegin",            "(II)V",                                (void*)nProgramVertexBegin },
1441{"nProgramVertexSetTextureMatrixEnable",   "(Z)V",                         (void*)nProgramVertexSetTextureMatrixEnable },
1442{"nProgramVertexAddLight",         "(I)V",                                 (void*)nProgramVertexAddLight },
1443{"nProgramVertexCreate",           "()I",                                  (void*)nProgramVertexCreate },
1444
1445{"nLightBegin",                    "()V",                                  (void*)nLightBegin },
1446{"nLightSetIsMono",                "(Z)V",                                 (void*)nLightSetIsMono },
1447{"nLightSetIsLocal",               "(Z)V",                                 (void*)nLightSetIsLocal },
1448{"nLightCreate",                   "()I",                                  (void*)nLightCreate },
1449{"nLightSetColor",                 "(IFFF)V",                              (void*)nLightSetColor },
1450{"nLightSetPosition",              "(IFFF)V",                              (void*)nLightSetPosition },
1451
1452{"nContextBindRootScript",         "(I)V",                                 (void*)nContextBindRootScript },
1453{"nContextBindProgramFragmentStore","(I)V",                                (void*)nContextBindProgramFragmentStore },
1454{"nContextBindProgramFragment",    "(I)V",                                 (void*)nContextBindProgramFragment },
1455{"nContextBindProgramVertex",      "(I)V",                                 (void*)nContextBindProgramVertex },
1456{"nContextBindProgramRaster",      "(I)V",                                 (void*)nContextBindProgramRaster },
1457
1458{"nSamplerBegin",                  "()V",                                  (void*)nSamplerBegin },
1459{"nSamplerSet",                    "(II)V",                                (void*)nSamplerSet },
1460{"nSamplerCreate",                 "()I",                                  (void*)nSamplerCreate },
1461
1462{"nSimpleMeshCreate",              "(II[II)I",                             (void*)nSimpleMeshCreate },
1463{"nSimpleMeshBindVertex",          "(III)V",                               (void*)nSimpleMeshBindVertex },
1464{"nSimpleMeshBindIndex",           "(II)V",                                (void*)nSimpleMeshBindIndex },
1465
1466};
1467
1468static int registerFuncs(JNIEnv *_env)
1469{
1470    return android::AndroidRuntime::registerNativeMethods(
1471            _env, classPathName, methods, NELEM(methods));
1472}
1473
1474// ---------------------------------------------------------------------------
1475
1476jint JNI_OnLoad(JavaVM* vm, void* reserved)
1477{
1478    JNIEnv* env = NULL;
1479    jint result = -1;
1480
1481    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1482        LOGE("ERROR: GetEnv failed\n");
1483        goto bail;
1484    }
1485    assert(env != NULL);
1486
1487    if (registerFuncs(env) < 0) {
1488        LOGE("ERROR: MediaPlayer native registration failed\n");
1489        goto bail;
1490    }
1491
1492    /* success -- return valid version number */
1493    result = JNI_VERSION_1_4;
1494
1495bail:
1496    return result;
1497}
1498