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