android_renderscript_RenderScript.cpp revision 07ae40623737a6060b8a925fd2e6bba76780dcd4
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, (void *)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 void
349nAllocationUploadToBufferObject(JNIEnv *_env, jobject _this, jint a)
350{
351    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
352    LOG_API("nAllocationUploadToBufferObject, con(%p), a(%p)", con, (RsAllocation)a);
353    rsAllocationUploadToBufferObject(con, (RsAllocation)a);
354}
355
356static RsElementPredefined SkBitmapToPredefined(SkBitmap::Config cfg)
357{
358    switch (cfg) {
359    case SkBitmap::kA8_Config:
360        return RS_ELEMENT_A_8;
361    case SkBitmap::kARGB_4444_Config:
362        return RS_ELEMENT_RGBA_4444;
363    case SkBitmap::kARGB_8888_Config:
364        return RS_ELEMENT_RGBA_8888;
365    case SkBitmap::kRGB_565_Config:
366        return RS_ELEMENT_RGB_565;
367
368    default:
369        break;
370    }
371    // If we don't have a conversion mark it as a user type.
372    LOGE("Unsupported bitmap type");
373    return RS_ELEMENT_USER_U8;
374}
375
376static int
377nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap)
378{
379    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
380    SkBitmap const * nativeBitmap =
381            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
382    const SkBitmap& bitmap(*nativeBitmap);
383    SkBitmap::Config config = bitmap.getConfig();
384
385    RsElementPredefined e = SkBitmapToPredefined(config);
386
387    if (e != RS_ELEMENT_USER_U8) {
388        bitmap.lockPixels();
389        const int w = bitmap.width();
390        const int h = bitmap.height();
391        const void* ptr = bitmap.getPixels();
392        jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
393        bitmap.unlockPixels();
394        return id;
395    }
396    return 0;
397}
398
399static int
400nAllocationCreateFromBitmapBoxed(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap)
401{
402    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
403    SkBitmap const * nativeBitmap =
404            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
405    const SkBitmap& bitmap(*nativeBitmap);
406    SkBitmap::Config config = bitmap.getConfig();
407
408    RsElementPredefined e = SkBitmapToPredefined(config);
409
410    if (e != RS_ELEMENT_USER_U8) {
411        bitmap.lockPixels();
412        const int w = bitmap.width();
413        const int h = bitmap.height();
414        const void* ptr = bitmap.getPixels();
415        jint id = (jint)rsAllocationCreateFromBitmapBoxed(con, w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
416        bitmap.unlockPixels();
417        return id;
418    }
419    return 0;
420}
421
422
423static void
424nAllocationData_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data, int sizeBytes)
425{
426    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
427    jint len = _env->GetArrayLength(data);
428    LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
429    jint *ptr = _env->GetIntArrayElements(data, NULL);
430    rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes);
431    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
432}
433
434static void
435nAllocationData_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data, int sizeBytes)
436{
437    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
438    jint len = _env->GetArrayLength(data);
439    LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
440    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
441    rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes);
442    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
443}
444
445static void
446nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data, int sizeBytes)
447{
448    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
449    jint len = _env->GetArrayLength(data);
450    LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
451    jint *ptr = _env->GetIntArrayElements(data, NULL);
452    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
453    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
454}
455
456static void
457nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data, int sizeBytes)
458{
459    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
460    jint len = _env->GetArrayLength(data);
461    LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len);
462    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
463    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
464    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
465}
466
467static void
468nAllocationSubData2D_i(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data, int sizeBytes)
469{
470    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
471    jint len = _env->GetArrayLength(data);
472    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);
473    jint *ptr = _env->GetIntArrayElements(data, NULL);
474    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes);
475    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
476}
477
478static void
479nAllocationSubData2D_f(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jfloatArray data, int sizeBytes)
480{
481    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
482    jint len = _env->GetArrayLength(data);
483    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);
484    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
485    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes);
486    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
487}
488
489static void
490nAllocationRead_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data)
491{
492    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
493    jint len = _env->GetArrayLength(data);
494    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
495    jint *ptr = _env->GetIntArrayElements(data, NULL);
496    rsAllocationRead(con, (RsAllocation)alloc, ptr);
497    _env->ReleaseIntArrayElements(data, ptr, JNI_COMMIT);
498}
499
500static void
501nAllocationRead_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data)
502{
503    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
504    jint len = _env->GetArrayLength(data);
505    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
506    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
507    rsAllocationRead(con, (RsAllocation)alloc, ptr);
508    _env->ReleaseFloatArrayElements(data, ptr, JNI_COMMIT);
509}
510
511
512//{"nAllocationDataFromObject",      "(ILandroid/renderscript/Type;Ljava/lang/Object;)V",   (void*)nAllocationDataFromObject },
513static void
514nAllocationDataFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _type, jobject _o)
515{
516    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
517    LOG_API("nAllocationDataFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc);
518
519    const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache);
520
521    void * bufAlloc = malloc(tc->size);
522    void * buf = bufAlloc;
523    for (int ct=0; ct < tc->fieldCount; ct++) {
524        const TypeFieldCache *tfc = &tc->fields[ct];
525        buf = tfc->ptr(_env, _o, tfc->field, buf);
526    }
527    rsAllocationData(con, (RsAllocation)alloc, bufAlloc, tc->size);
528    const uint32_t * tmp = (const uint32_t *)bufAlloc;
529    free(bufAlloc);
530}
531
532// -----------------------------------
533
534static void
535nTriangleMeshBegin(JNIEnv *_env, jobject _this, jint v, jint i)
536{
537    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
538    LOG_API("nTriangleMeshBegin, con(%p), vertex(%p), index(%p)", con, (RsElement)v, (RsElement)i);
539    rsTriangleMeshBegin(con, (RsElement)v, (RsElement)i);
540}
541
542static void
543nTriangleMeshAddVertex_XY(JNIEnv *_env, jobject _this, jfloat x, jfloat y)
544{
545    float v[] = {x, y};
546    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
547    LOG_API("nTriangleMeshAddVertex_XY, con(%p), x(%f), y(%f)", con, x, y);
548    rsTriangleMeshAddVertex(con, v);
549}
550
551static void
552nTriangleMeshAddVertex_XYZ(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z)
553{
554    float v[] = {x, y, z};
555    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
556    LOG_API("nTriangleMeshAddVertex_XYZ, con(%p), x(%f), y(%f), z(%f)", con, x, y, z);
557    rsTriangleMeshAddVertex(con, v);
558}
559
560static void
561nTriangleMeshAddVertex_XY_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat s, jfloat t)
562{
563    float v[] = {s, t, x, y};
564    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
565    LOG_API("nTriangleMeshAddVertex_XY_ST, con(%p), x(%f), y(%f), s(%f), t(%f)", con, x, y, s, t);
566    rsTriangleMeshAddVertex(con, v);
567}
568
569static void
570nTriangleMeshAddVertex_XYZ_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t)
571{
572    float v[] = {s, t, x, y, z};
573    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
574    LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t);
575    rsTriangleMeshAddVertex(con, v);
576}
577
578static void
579nTriangleMeshAddVertex_XYZ_ST_NORM(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t, jfloat nx, jfloat ny, jfloat nz)
580{
581    float v[] = {nx, ny, nz, s, t, x, y, z};
582    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
583    LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t);
584    rsTriangleMeshAddVertex(con, v);
585}
586
587static void
588nTriangleMeshAddTriangle(JNIEnv *_env, jobject _this, jint i1, jint i2, jint i3)
589{
590    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
591    LOG_API("nTriangleMeshAddTriangle, con(%p), i1(%i), i2(%i), i3(%i)", con, i1, i2, i3);
592    rsTriangleMeshAddTriangle(con, i1, i2, i3);
593}
594
595static jint
596nTriangleMeshCreate(JNIEnv *_env, jobject _this)
597{
598    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
599    LOG_API("nTriangleMeshCreate, con(%p)", con);
600    return (jint) rsTriangleMeshCreate(con);
601}
602
603// -----------------------------------
604
605static void
606nAdapter1DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc)
607{
608    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
609    LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc);
610    rsAdapter1DBindAllocation(con, (RsAdapter1D)adapter, (RsAllocation)alloc);
611}
612
613static void
614nAdapter1DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value)
615{
616    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
617    LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value);
618    rsAdapter1DSetConstraint(con, (RsAdapter1D)adapter, (RsDimension)dim, value);
619}
620
621static void
622nAdapter1DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data)
623{
624    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
625    jint len = _env->GetArrayLength(data);
626    LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
627    jint *ptr = _env->GetIntArrayElements(data, NULL);
628    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
629    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
630}
631
632static void
633nAdapter1DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jintArray data)
634{
635    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
636    jint len = _env->GetArrayLength(data);
637    LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
638    jint *ptr = _env->GetIntArrayElements(data, NULL);
639    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
640    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
641}
642
643static void
644nAdapter1DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data)
645{
646    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
647    jint len = _env->GetArrayLength(data);
648    LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
649    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
650    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
651    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
652}
653
654static void
655nAdapter1DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jfloatArray data)
656{
657    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
658    jint len = _env->GetArrayLength(data);
659    LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
660    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
661    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
662    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
663}
664
665static jint
666nAdapter1DCreate(JNIEnv *_env, jobject _this)
667{
668    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
669    LOG_API("nAdapter1DCreate, con(%p)", con);
670    return (jint)rsAdapter1DCreate(con);
671}
672
673// -----------------------------------
674
675static void
676nAdapter2DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc)
677{
678    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
679    LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc);
680    rsAdapter2DBindAllocation(con, (RsAdapter2D)adapter, (RsAllocation)alloc);
681}
682
683static void
684nAdapter2DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value)
685{
686    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
687    LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value);
688    rsAdapter2DSetConstraint(con, (RsAdapter2D)adapter, (RsDimension)dim, value);
689}
690
691static void
692nAdapter2DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data)
693{
694    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
695    jint len = _env->GetArrayLength(data);
696    LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
697    jint *ptr = _env->GetIntArrayElements(data, NULL);
698    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
699    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
700}
701
702static void
703nAdapter2DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data)
704{
705    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
706    jint len = _env->GetArrayLength(data);
707    LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
708    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
709    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
710    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
711}
712
713static void
714nAdapter2DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jintArray data)
715{
716    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
717    jint len = _env->GetArrayLength(data);
718    LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
719            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
720    jint *ptr = _env->GetIntArrayElements(data, NULL);
721    rsAdapter2DSubData(con, (RsAdapter2D)adapter, xoff, yoff, w, h, ptr);
722    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
723}
724
725static void
726nAdapter2DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jfloatArray data)
727{
728    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
729    jint len = _env->GetArrayLength(data);
730    LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
731            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
732    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
733    rsAdapter2DSubData(con, (RsAdapter1D)adapter, xoff, yoff, w, h, ptr);
734    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
735}
736
737static jint
738nAdapter2DCreate(JNIEnv *_env, jobject _this)
739{
740    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
741    LOG_API("nAdapter2DCreate, con(%p)", con);
742    return (jint)rsAdapter2DCreate(con);
743}
744
745// -----------------------------------
746
747static void
748nScriptBindAllocation(JNIEnv *_env, jobject _this, jint script, jint alloc, jint slot)
749{
750    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
751    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
752    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
753}
754
755static void
756nScriptSetClearColor(JNIEnv *_env, jobject _this, jint script, jfloat r, jfloat g, jfloat b, jfloat a)
757{
758    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
759    LOG_API("nScriptSetClearColor, con(%p), s(%p), r(%f), g(%f), b(%f), a(%f)", con, (void *)script, r, g, b, a);
760    rsScriptSetClearColor(con, (RsScript)script, r, g, b, a);
761}
762
763static void
764nScriptSetClearDepth(JNIEnv *_env, jobject _this, jint script, jfloat d)
765{
766    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
767    LOG_API("nScriptCSetClearDepth, con(%p), s(%p), depth(%f)", con, (void *)script, d);
768    rsScriptSetClearDepth(con, (RsScript)script, d);
769}
770
771static void
772nScriptSetClearStencil(JNIEnv *_env, jobject _this, jint script, jint stencil)
773{
774    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
775    LOG_API("nScriptCSetClearStencil, con(%p), s(%p), stencil(%i)", con, (void *)script, stencil);
776    rsScriptSetClearStencil(con, (RsScript)script, stencil);
777}
778
779static void
780nScriptSetTimeZone(JNIEnv *_env, jobject _this, jint script, jbyteArray timeZone)
781{
782    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
783    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
784
785    jint length = _env->GetArrayLength(timeZone);
786    jbyte* timeZone_ptr;
787    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
788
789    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
790
791    if (timeZone_ptr) {
792        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
793    }
794}
795
796static void
797nScriptSetType(JNIEnv *_env, jobject _this, jint type, jboolean writable, jstring _str, jint slot)
798{
799    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
800    LOG_API("nScriptCAddType, con(%p), type(%p), writable(%i), slot(%i)", con, (RsType)type, writable, slot);
801    const char* n = NULL;
802    if (_str) {
803        n = _env->GetStringUTFChars(_str, NULL);
804    }
805    rsScriptSetType(con, (RsType)type, slot, writable, n);
806    if (n) {
807        _env->ReleaseStringUTFChars(_str, n);
808    }
809}
810
811static void
812nScriptSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot)
813{
814    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
815    LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot);
816    rsScriptSetRoot(con, isRoot);
817}
818
819// -----------------------------------
820
821static void
822nScriptCBegin(JNIEnv *_env, jobject _this)
823{
824    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
825    LOG_API("nScriptCBegin, con(%p)", con);
826    rsScriptCBegin(con);
827}
828
829static void
830nScriptCSetScript(JNIEnv *_env, jobject _this, jbyteArray scriptRef,
831                  jint offset, jint length)
832{
833    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
834    LOG_API("!!! nScriptCSetScript, con(%p)", con);
835    jint _exception = 0;
836    jint remaining;
837    jbyte* script_base = 0;
838    jbyte* script_ptr;
839    if (!scriptRef) {
840        _exception = 1;
841        //_env->ThrowNew(IAEClass, "script == null");
842        goto exit;
843    }
844    if (offset < 0) {
845        _exception = 1;
846        //_env->ThrowNew(IAEClass, "offset < 0");
847        goto exit;
848    }
849    if (length < 0) {
850        _exception = 1;
851        //_env->ThrowNew(IAEClass, "length < 0");
852        goto exit;
853    }
854    remaining = _env->GetArrayLength(scriptRef) - offset;
855    if (remaining < length) {
856        _exception = 1;
857        //_env->ThrowNew(IAEClass, "length > script.length - offset");
858        goto exit;
859    }
860    script_base = (jbyte *)
861        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
862    script_ptr = script_base + offset;
863
864    rsScriptCSetText(con, (const char *)script_ptr, length);
865
866exit:
867    if (script_base) {
868        _env->ReleasePrimitiveArrayCritical(scriptRef, script_base,
869                _exception ? JNI_ABORT: 0);
870    }
871}
872
873static jint
874nScriptCCreate(JNIEnv *_env, jobject _this)
875{
876    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
877    LOG_API("nScriptCCreate, con(%p)", con);
878    return (jint)rsScriptCCreate(con);
879}
880
881static void
882nScriptCAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value)
883{
884    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
885    const char* n = _env->GetStringUTFChars(name, NULL);
886    LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value);
887    rsScriptCSetDefineI32(con, n, value);
888    _env->ReleaseStringUTFChars(name, n);
889}
890
891static void
892nScriptCAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value)
893{
894    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
895    const char* n = _env->GetStringUTFChars(name, NULL);
896    LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value);
897    rsScriptCSetDefineF(con, n, value);
898    _env->ReleaseStringUTFChars(name, n);
899}
900
901// ---------------------------------------------------------------------------
902
903static void
904nProgramFragmentStoreBegin(JNIEnv *_env, jobject _this, jint in, jint out)
905{
906    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
907    LOG_API("nProgramFragmentStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
908    rsProgramFragmentStoreBegin(con, (RsElement)in, (RsElement)out);
909}
910
911static void
912nProgramFragmentStoreDepthFunc(JNIEnv *_env, jobject _this, jint func)
913{
914    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
915    LOG_API("nProgramFragmentStoreDepthFunc, con(%p), func(%i)", con, func);
916    rsProgramFragmentStoreDepthFunc(con, (RsDepthFunc)func);
917}
918
919static void
920nProgramFragmentStoreDepthMask(JNIEnv *_env, jobject _this, jboolean enable)
921{
922    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
923    LOG_API("nProgramFragmentStoreDepthMask, con(%p), enable(%i)", con, enable);
924    rsProgramFragmentStoreDepthMask(con, enable);
925}
926
927static void
928nProgramFragmentStoreColorMask(JNIEnv *_env, jobject _this, jboolean r, jboolean g, jboolean b, jboolean a)
929{
930    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
931    LOG_API("nProgramFragmentStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
932    rsProgramFragmentStoreColorMask(con, r, g, b, a);
933}
934
935static void
936nProgramFragmentStoreBlendFunc(JNIEnv *_env, jobject _this, int src, int dst)
937{
938    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
939    LOG_API("nProgramFragmentStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
940    rsProgramFragmentStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
941}
942
943static void
944nProgramFragmentStoreDither(JNIEnv *_env, jobject _this, jboolean enable)
945{
946    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
947    LOG_API("nProgramFragmentStoreDither, con(%p), enable(%i)", con, enable);
948    rsProgramFragmentStoreDither(con, enable);
949}
950
951static jint
952nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this)
953{
954    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
955    LOG_API("nProgramFragmentStoreCreate, con(%p)", con);
956
957    return (jint)rsProgramFragmentStoreCreate(con);
958}
959
960// ---------------------------------------------------------------------------
961
962static void
963nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out, jboolean pointSpriteEnable)
964{
965    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
966    LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p) PointSprite(%i)", con, (RsElement)in, (RsElement)out, pointSpriteEnable);
967    rsProgramFragmentBegin(con, (RsElement)in, (RsElement)out, pointSpriteEnable);
968}
969
970static void
971nProgramFragmentBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a)
972{
973    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
974    LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
975    rsProgramFragmentBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
976}
977
978static void
979nProgramFragmentBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a)
980{
981    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
982    LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
983    rsProgramFragmentBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
984}
985
986static void
987nProgramFragmentSetSlot(JNIEnv *_env, jobject _this, jint slot, jboolean enable, jint env, jint vt)
988{
989    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
990    LOG_API("nProgramFragmentSetType, con(%p), slot(%i), enable(%i), env(%i), vt(%p)", con, slot, enable, env, (RsType)vt);
991    rsProgramFragmentSetSlot(con, slot, enable, (RsTexEnvMode)env, (RsType)vt);
992}
993
994static jint
995nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable)
996{
997    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
998    LOG_API("nProgramFragmentCreate, con(%p)", con);
999    return (jint)rsProgramFragmentCreate(con);
1000}
1001
1002// ---------------------------------------------------------------------------
1003
1004static void
1005nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out)
1006{
1007    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1008    LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
1009    rsProgramVertexBegin(con, (RsElement)in, (RsElement)out);
1010}
1011
1012static void
1013nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint a)
1014{
1015    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1016    LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), a(%p)", con, (RsProgramVertex)vpv, (RsAllocation)a);
1017    rsProgramVertexBindAllocation(con, (RsProgramFragment)vpv, (RsAllocation)a);
1018}
1019
1020static void
1021nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable)
1022{
1023    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1024    LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable);
1025    rsProgramVertexSetTextureMatrixEnable(con, enable);
1026}
1027
1028static void
1029nProgramVertexAddLight(JNIEnv *_env, jobject _this, jint light)
1030{
1031    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1032    LOG_API("nProgramVertexAddLight, con(%p), light(%p)", con, (RsLight)light);
1033    rsProgramVertexAddLight(con, (RsLight)light);
1034}
1035
1036static jint
1037nProgramVertexCreate(JNIEnv *_env, jobject _this)
1038{
1039    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1040    LOG_API("nProgramVertexCreate, con(%p)", con);
1041    return (jint)rsProgramVertexCreate(con);
1042}
1043
1044
1045
1046// ---------------------------------------------------------------------------
1047
1048static void
1049nContextBindRootScript(JNIEnv *_env, jobject _this, jint script)
1050{
1051    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1052    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
1053    rsContextBindRootScript(con, (RsScript)script);
1054}
1055
1056static void
1057nContextBindProgramFragmentStore(JNIEnv *_env, jobject _this, jint pfs)
1058{
1059    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1060    LOG_API("nContextBindProgramFragmentStore, con(%p), pfs(%p)", con, (RsProgramFragmentStore)pfs);
1061    rsContextBindProgramFragmentStore(con, (RsProgramFragmentStore)pfs);
1062}
1063
1064static void
1065nContextBindProgramFragment(JNIEnv *_env, jobject _this, jint pf)
1066{
1067    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1068    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
1069    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
1070}
1071
1072static void
1073nContextBindProgramVertex(JNIEnv *_env, jobject _this, jint pf)
1074{
1075    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1076    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
1077    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
1078}
1079
1080static void
1081nContextAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value)
1082{
1083    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1084    const char* n = _env->GetStringUTFChars(name, NULL);
1085    LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value);
1086    rsContextSetDefineI32(con, n, value);
1087    _env->ReleaseStringUTFChars(name, n);
1088}
1089
1090static void
1091nContextAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value)
1092{
1093    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1094    const char* n = _env->GetStringUTFChars(name, NULL);
1095    LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value);
1096    rsContextSetDefineF(con, n, value);
1097    _env->ReleaseStringUTFChars(name, n);
1098}
1099
1100
1101// ---------------------------------------------------------------------------
1102
1103static void
1104nSamplerBegin(JNIEnv *_env, jobject _this)
1105{
1106    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1107    LOG_API("nSamplerBegin, con(%p)", con);
1108    rsSamplerBegin(con);
1109}
1110
1111static void
1112nSamplerSet(JNIEnv *_env, jobject _this, jint p, jint v)
1113{
1114    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1115    LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v);
1116    rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v);
1117}
1118
1119static jint
1120nSamplerCreate(JNIEnv *_env, jobject _this)
1121{
1122    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1123    LOG_API("nSamplerCreate, con(%p)", con);
1124    return (jint)rsSamplerCreate(con);
1125}
1126
1127// ---------------------------------------------------------------------------
1128
1129static void
1130nLightBegin(JNIEnv *_env, jobject _this)
1131{
1132    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1133    LOG_API("nLightBegin, con(%p)", con);
1134    rsLightBegin(con);
1135}
1136
1137static void
1138nLightSetIsMono(JNIEnv *_env, jobject _this, jboolean isMono)
1139{
1140    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1141    LOG_API("nLightSetIsMono, con(%p), isMono(%i)", con, isMono);
1142    rsLightSetMonochromatic(con, isMono);
1143}
1144
1145static void
1146nLightSetIsLocal(JNIEnv *_env, jobject _this, jboolean isLocal)
1147{
1148    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1149    LOG_API("nLightSetIsLocal, con(%p), isLocal(%i)", con, isLocal);
1150    rsLightSetLocal(con, isLocal);
1151}
1152
1153static jint
1154nLightCreate(JNIEnv *_env, jobject _this)
1155{
1156    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1157    LOG_API("nLightCreate, con(%p)", con);
1158    return (jint)rsLightCreate(con);
1159}
1160
1161static void
1162nLightSetColor(JNIEnv *_env, jobject _this, jint light, float r, float g, float b)
1163{
1164    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1165    LOG_API("nLightSetColor, con(%p), light(%p), r(%f), g(%f), b(%f)", con, (RsLight)light, r, g, b);
1166    rsLightSetColor(con, (RsLight)light, r, g, b);
1167}
1168
1169static void
1170nLightSetPosition(JNIEnv *_env, jobject _this, jint light, float x, float y, float z)
1171{
1172    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1173    LOG_API("nLightSetPosition, con(%p), light(%p), x(%f), y(%f), z(%f)", con, (RsLight)light, x, y, z);
1174    rsLightSetPosition(con, (RsLight)light, x, y, z);
1175}
1176
1177// ---------------------------------------------------------------------------
1178
1179static jint
1180nSimpleMeshCreate(JNIEnv *_env, jobject _this, jint batchID, jint indexID, jintArray vtxIDs, jint primID)
1181{
1182    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1183    jint len = _env->GetArrayLength(vtxIDs);
1184    LOG_API("nSimpleMeshCreate, con(%p), batchID(%i), indexID(%i), vtxIDs.len(%i), primID(%i)",
1185            con, batchID, indexID, len, primID);
1186    jint *ptr = _env->GetIntArrayElements(vtxIDs, NULL);
1187    int id = (int)rsSimpleMeshCreate(con, (void *)batchID, (void *)indexID, (void **)ptr, len, primID);
1188    _env->ReleaseIntArrayElements(vtxIDs, ptr, 0/*JNI_ABORT*/);
1189    return id;
1190}
1191
1192static void
1193nSimpleMeshBindVertex(JNIEnv *_env, jobject _this, jint s, jint alloc, jint slot)
1194{
1195    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1196    LOG_API("nSimpleMeshBindVertex, con(%p), SimpleMesh(%p), Alloc(%p), slot(%i)", con, (RsSimpleMesh)s, (RsAllocation)alloc, slot);
1197    rsSimpleMeshBindVertex(con, (RsSimpleMesh)s, (RsAllocation)alloc, slot);
1198}
1199
1200static void
1201nSimpleMeshBindIndex(JNIEnv *_env, jobject _this, jint s, jint alloc)
1202{
1203    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
1204    LOG_API("nSimpleMeshBindIndex, con(%p), SimpleMesh(%p), Alloc(%p)", con, (RsSimpleMesh)s, (RsAllocation)alloc);
1205    rsSimpleMeshBindIndex(con, (RsSimpleMesh)s, (RsAllocation)alloc);
1206}
1207
1208// ---------------------------------------------------------------------------
1209
1210
1211static const char *classPathName = "android/renderscript/RenderScript";
1212
1213static JNINativeMethod methods[] = {
1214{"_nInit",                         "()V",                                  (void*)_nInit },
1215{"nDeviceCreate",                  "()I",                                  (void*)nDeviceCreate },
1216{"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
1217{"nContextCreate",                 "(ILandroid/view/Surface;IZ)I",         (void*)nContextCreate },
1218{"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
1219{"nAssignName",                    "(I[B)V",                               (void*)nAssignName },
1220{"nObjDestroy",                    "(I)V",                                 (void*)nObjDestroy },
1221{"nObjDestroyOOB",                 "(I)V",                                 (void*)nObjDestroyOOB },
1222
1223{"nFileOpen",                      "([B)I",                                (void*)nFileOpen },
1224
1225{"nElementBegin",                  "()V",                                  (void*)nElementBegin },
1226{"nElementAddPredefined",          "(I)V",                                 (void*)nElementAddPredefined },
1227{"nElementAdd",                    "(IIIILjava/lang/String;)V",            (void*)nElementAdd },
1228{"nElementCreate",                 "()I",                                  (void*)nElementCreate },
1229{"nElementGetPredefined",          "(I)I",                                 (void*)nElementGetPredefined },
1230
1231{"nTypeBegin",                     "(I)V",                                 (void*)nTypeBegin },
1232{"nTypeAdd",                       "(II)V",                                (void*)nTypeAdd },
1233{"nTypeCreate",                    "()I",                                  (void*)nTypeCreate },
1234{"nTypeFinalDestroy",              "(Landroid/renderscript/Type;)V",       (void*)nTypeFinalDestroy },
1235{"nTypeSetupFields",               "(Landroid/renderscript/Type;[I[I[Ljava/lang/reflect/Field;)V", (void*)nTypeSetupFields },
1236
1237{"nAllocationCreateTyped",         "(I)I",                                 (void*)nAllocationCreateTyped },
1238{"nAllocationCreatePredefSized",   "(II)I",                                (void*)nAllocationCreatePredefSized },
1239{"nAllocationCreateSized",         "(II)I",                                (void*)nAllocationCreateSized },
1240{"nAllocationCreateFromBitmap",    "(IZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmap },
1241{"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I",      (void*)nAllocationCreateFromBitmapBoxed },
1242{"nAllocationUploadToTexture",     "(II)V",                                (void*)nAllocationUploadToTexture },
1243{"nAllocationUploadToBufferObject","(I)V",                                 (void*)nAllocationUploadToBufferObject },
1244{"nAllocationData",                "(I[II)V",                              (void*)nAllocationData_i },
1245{"nAllocationData",                "(I[FI)V",                              (void*)nAllocationData_f },
1246{"nAllocationSubData1D",           "(III[II)V",                            (void*)nAllocationSubData1D_i },
1247{"nAllocationSubData1D",           "(III[FI)V",                            (void*)nAllocationSubData1D_f },
1248{"nAllocationSubData2D",           "(IIIII[II)V",                          (void*)nAllocationSubData2D_i },
1249{"nAllocationSubData2D",           "(IIIII[FI)V",                          (void*)nAllocationSubData2D_f },
1250{"nAllocationRead",                "(I[I)V",                               (void*)nAllocationRead_i },
1251{"nAllocationRead",                "(I[F)V",                               (void*)nAllocationRead_f },
1252{"nAllocationDataFromObject",      "(ILandroid/renderscript/Type;Ljava/lang/Object;)V",   (void*)nAllocationDataFromObject },
1253
1254{"nTriangleMeshBegin",             "(II)V",                                (void*)nTriangleMeshBegin },
1255{"nTriangleMeshAddVertex_XY",      "(FF)V",                                (void*)nTriangleMeshAddVertex_XY },
1256{"nTriangleMeshAddVertex_XYZ",     "(FFF)V",                               (void*)nTriangleMeshAddVertex_XYZ },
1257{"nTriangleMeshAddVertex_XY_ST",   "(FFFF)V",                              (void*)nTriangleMeshAddVertex_XY_ST },
1258{"nTriangleMeshAddVertex_XYZ_ST",  "(FFFFF)V",                             (void*)nTriangleMeshAddVertex_XYZ_ST },
1259{"nTriangleMeshAddVertex_XYZ_ST_NORM",  "(FFFFFFFF)V",                     (void*)nTriangleMeshAddVertex_XYZ_ST_NORM },
1260{"nTriangleMeshAddTriangle",       "(III)V",                               (void*)nTriangleMeshAddTriangle },
1261{"nTriangleMeshCreate",            "()I",                                  (void*)nTriangleMeshCreate },
1262
1263{"nAdapter1DBindAllocation",       "(II)V",                                (void*)nAdapter1DBindAllocation },
1264{"nAdapter1DSetConstraint",        "(III)V",                               (void*)nAdapter1DSetConstraint },
1265{"nAdapter1DData",                 "(I[I)V",                               (void*)nAdapter1DData_i },
1266{"nAdapter1DData",                 "(I[F)V",                               (void*)nAdapter1DData_f },
1267{"nAdapter1DSubData",              "(III[I)V",                             (void*)nAdapter1DSubData_i },
1268{"nAdapter1DSubData",              "(III[F)V",                             (void*)nAdapter1DSubData_f },
1269{"nAdapter1DCreate",               "()I",                                  (void*)nAdapter1DCreate },
1270
1271{"nAdapter2DBindAllocation",       "(II)V",                                (void*)nAdapter2DBindAllocation },
1272{"nAdapter2DSetConstraint",        "(III)V",                               (void*)nAdapter2DSetConstraint },
1273{"nAdapter2DData",                 "(I[I)V",                               (void*)nAdapter2DData_i },
1274{"nAdapter2DData",                 "(I[F)V",                               (void*)nAdapter2DData_f },
1275{"nAdapter2DSubData",              "(IIIII[I)V",                           (void*)nAdapter2DSubData_i },
1276{"nAdapter2DSubData",              "(IIIII[F)V",                           (void*)nAdapter2DSubData_f },
1277{"nAdapter2DCreate",               "()I",                                  (void*)nAdapter2DCreate },
1278
1279{"nScriptBindAllocation",          "(III)V",                               (void*)nScriptBindAllocation },
1280{"nScriptSetClearColor",           "(IFFFF)V",                             (void*)nScriptSetClearColor },
1281{"nScriptSetClearDepth",           "(IF)V",                                (void*)nScriptSetClearDepth },
1282{"nScriptSetClearStencil",         "(II)V",                                (void*)nScriptSetClearStencil },
1283{"nScriptSetTimeZone",             "(I[B)V",                               (void*)nScriptSetTimeZone },
1284{"nScriptSetType",                 "(IZLjava/lang/String;I)V",             (void*)nScriptSetType },
1285{"nScriptSetRoot",                 "(Z)V",                                 (void*)nScriptSetRoot },
1286
1287{"nScriptCBegin",                  "()V",                                  (void*)nScriptCBegin },
1288{"nScriptCSetScript",              "([BII)V",                              (void*)nScriptCSetScript },
1289{"nScriptCCreate",                 "()I",                                  (void*)nScriptCCreate },
1290{"nScriptCAddDefineI32",           "(Ljava/lang/String;I)V",               (void*)nScriptCAddDefineI32 },
1291{"nScriptCAddDefineF",             "(Ljava/lang/String;F)V",               (void*)nScriptCAddDefineF },
1292
1293{"nProgramFragmentStoreBegin",     "(II)V",                                (void*)nProgramFragmentStoreBegin },
1294{"nProgramFragmentStoreDepthFunc", "(I)V",                                 (void*)nProgramFragmentStoreDepthFunc },
1295{"nProgramFragmentStoreDepthMask", "(Z)V",                                 (void*)nProgramFragmentStoreDepthMask },
1296{"nProgramFragmentStoreColorMask", "(ZZZZ)V",                              (void*)nProgramFragmentStoreColorMask },
1297{"nProgramFragmentStoreBlendFunc", "(II)V",                                (void*)nProgramFragmentStoreBlendFunc },
1298{"nProgramFragmentStoreDither",    "(Z)V",                                 (void*)nProgramFragmentStoreDither },
1299{"nProgramFragmentStoreCreate",    "()I",                                  (void*)nProgramFragmentStoreCreate },
1300
1301{"nProgramFragmentBegin",          "(IIZ)V",                               (void*)nProgramFragmentBegin },
1302{"nProgramFragmentBindTexture",    "(III)V",                               (void*)nProgramFragmentBindTexture },
1303{"nProgramFragmentBindSampler",    "(III)V",                               (void*)nProgramFragmentBindSampler },
1304{"nProgramFragmentSetSlot",        "(IZII)V",                              (void*)nProgramFragmentSetSlot },
1305{"nProgramFragmentCreate",         "()I",                                  (void*)nProgramFragmentCreate },
1306
1307{"nProgramVertexBindAllocation",   "(II)V",                                (void*)nProgramVertexBindAllocation },
1308{"nProgramVertexBegin",            "(II)V",                                (void*)nProgramVertexBegin },
1309{"nProgramVertexSetTextureMatrixEnable",   "(Z)V",                         (void*)nProgramVertexSetTextureMatrixEnable },
1310{"nProgramVertexAddLight",         "(I)V",                                 (void*)nProgramVertexAddLight },
1311{"nProgramVertexCreate",           "()I",                                  (void*)nProgramVertexCreate },
1312
1313{"nLightBegin",                    "()V",                                  (void*)nLightBegin },
1314{"nLightSetIsMono",                "(Z)V",                                 (void*)nLightSetIsMono },
1315{"nLightSetIsLocal",               "(Z)V",                                 (void*)nLightSetIsLocal },
1316{"nLightCreate",                   "()I",                                  (void*)nLightCreate },
1317{"nLightSetColor",                 "(IFFF)V",                              (void*)nLightSetColor },
1318{"nLightSetPosition",              "(IFFF)V",                              (void*)nLightSetPosition },
1319
1320{"nContextBindRootScript",         "(I)V",                                 (void*)nContextBindRootScript },
1321{"nContextBindProgramFragmentStore","(I)V",                                (void*)nContextBindProgramFragmentStore },
1322{"nContextBindProgramFragment",    "(I)V",                                 (void*)nContextBindProgramFragment },
1323{"nContextBindProgramVertex",      "(I)V",                                 (void*)nContextBindProgramVertex },
1324
1325{"nSamplerBegin",                  "()V",                                  (void*)nSamplerBegin },
1326{"nSamplerSet",                    "(II)V",                                (void*)nSamplerSet },
1327{"nSamplerCreate",                 "()I",                                  (void*)nSamplerCreate },
1328
1329{"nSimpleMeshCreate",              "(II[II)I",                             (void*)nSimpleMeshCreate },
1330{"nSimpleMeshBindVertex",          "(III)V",                               (void*)nSimpleMeshBindVertex },
1331{"nSimpleMeshBindIndex",           "(II)V",                                (void*)nSimpleMeshBindIndex },
1332
1333};
1334
1335static int registerFuncs(JNIEnv *_env)
1336{
1337    return android::AndroidRuntime::registerNativeMethods(
1338            _env, classPathName, methods, NELEM(methods));
1339}
1340
1341// ---------------------------------------------------------------------------
1342
1343jint JNI_OnLoad(JavaVM* vm, void* reserved)
1344{
1345    JNIEnv* env = NULL;
1346    jint result = -1;
1347
1348    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1349        LOGE("ERROR: GetEnv failed\n");
1350        goto bail;
1351    }
1352    assert(env != NULL);
1353
1354    if (registerFuncs(env) < 0) {
1355        LOGE("ERROR: MediaPlayer native registration failed\n");
1356        goto bail;
1357    }
1358
1359    /* success -- return valid version number */
1360    result = JNI_VERSION_1_4;
1361
1362bail:
1363    return result;
1364}
1365