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