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