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