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