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