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