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