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