android_renderscript_RenderScript.cpp revision 581cc64028e8b8f66cec8105bf530b16d5fb34eb
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 <surfaceflinger/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#include "android_runtime/android_view_Surface.h"
41
42#include <RenderScript.h>
43#include <RenderScriptEnv.h>
44
45//#define LOG_API LOGE
46#define LOG_API(...)
47
48using namespace android;
49
50// ---------------------------------------------------------------------------
51
52static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
53{
54    jclass npeClazz = env->FindClass(exc);
55    env->ThrowNew(npeClazz, msg);
56}
57
58static jfieldID gContextId = 0;
59static jfieldID gNativeBitmapID = 0;
60static jfieldID gTypeNativeCache = 0;
61
62static RsElement g_A_8 = NULL;
63static RsElement g_RGBA_4444 = NULL;
64static RsElement g_RGBA_8888 = NULL;
65static RsElement g_RGB_565 = NULL;
66
67static void _nInit(JNIEnv *_env, jclass _this)
68{
69    gContextId             = _env->GetFieldID(_this, "mContext", "I");
70
71    jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
72    gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
73}
74
75static void nInitElements(JNIEnv *_env, jobject _this, jint a8, jint rgba4444, jint rgba8888, jint rgb565)
76{
77    g_A_8 = reinterpret_cast<RsElement>(a8);
78    g_RGBA_4444 = reinterpret_cast<RsElement>(rgba4444);
79    g_RGBA_8888 = reinterpret_cast<RsElement>(rgba8888);
80    g_RGB_565 = reinterpret_cast<RsElement>(rgb565);
81}
82
83// ---------------------------------------------------------------------------
84
85static void
86nContextFinish(JNIEnv *_env, jobject _this, RsContext con)
87{
88    LOG_API("nContextFinish, con(%p)", con);
89    rsContextFinish(con);
90}
91
92static void
93nAssignName(JNIEnv *_env, jobject _this, RsContext con, jint obj, jbyteArray str)
94{
95    LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj);
96    jint len = _env->GetArrayLength(str);
97    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
98    rsAssignName(con, (void *)obj, (const char *)cptr, len);
99    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
100}
101
102static jstring
103nGetName(JNIEnv *_env, jobject _this, RsContext con, jint obj)
104{
105    LOG_API("nGetName, con(%p), obj(%p)", con, (void *)obj);
106    const char *name = NULL;
107    rsaGetName(con, (void *)obj, &name);
108    if(name == NULL || strlen(name) == 0) {
109        return NULL;
110    }
111    return _env->NewStringUTF(name);
112}
113
114static void
115nObjDestroy(JNIEnv *_env, jobject _this, RsContext con, jint obj)
116{
117    LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
118    rsObjDestroy(con, (void *)obj);
119}
120
121
122static jint
123nFileOpen(JNIEnv *_env, jobject _this, RsContext con, jbyteArray str)
124{
125    LOG_API("nFileOpen, con(%p)", con);
126    jint len = _env->GetArrayLength(str);
127    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
128    jint ret = (jint)rsFileOpen(con, (const char *)cptr, len);
129    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
130    return ret;
131}
132
133// ---------------------------------------------------------------------------
134
135static jint
136nDeviceCreate(JNIEnv *_env, jobject _this)
137{
138    LOG_API("nDeviceCreate");
139    return (jint)rsDeviceCreate();
140}
141
142static void
143nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev)
144{
145    LOG_API("nDeviceDestroy");
146    return rsDeviceDestroy((RsDevice)dev);
147}
148
149static void
150nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value)
151{
152    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
153    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
154}
155
156static jint
157nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver)
158{
159    LOG_API("nContextCreate");
160    return (jint)rsContextCreate((RsDevice)dev, ver);
161}
162
163static jint
164nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver,
165                 int colorMin, int colorPref,
166                 int alphaMin, int alphaPref,
167                 int depthMin, int depthPref,
168                 int stencilMin, int stencilPref,
169                 int samplesMin, int samplesPref, float samplesQ)
170{
171    RsSurfaceConfig sc;
172    sc.alphaMin = alphaMin;
173    sc.alphaPref = alphaPref;
174    sc.colorMin = colorMin;
175    sc.colorPref = colorPref;
176    sc.depthMin = depthMin;
177    sc.depthPref = depthPref;
178    sc.samplesMin = samplesMin;
179    sc.samplesPref = samplesPref;
180    sc.samplesQ = samplesQ;
181
182    LOG_API("nContextCreateGL");
183    return (jint)rsContextCreateGL((RsDevice)dev, ver, sc);
184}
185
186static void
187nContextSetPriority(JNIEnv *_env, jobject _this, RsContext con, jint p)
188{
189    LOG_API("ContextSetPriority, con(%p), priority(%i)", con, p);
190    rsContextSetPriority(con, p);
191}
192
193
194
195static void
196nContextSetSurface(JNIEnv *_env, jobject _this, RsContext con, jint width, jint height, jobject wnd)
197{
198    LOG_API("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", con, width, height, (Surface *)wnd);
199
200    Surface * window = NULL;
201    if (wnd == NULL) {
202
203    } else {
204        window = (Surface*) android_Surface_getNativeWindow(_env, wnd).get();
205    }
206
207    rsContextSetSurface(con, width, height, window);
208}
209
210static void
211nContextDestroy(JNIEnv *_env, jobject _this, RsContext con)
212{
213    LOG_API("nContextDestroy, con(%p)", con);
214    rsContextDestroy(con);
215}
216
217static void
218nContextDump(JNIEnv *_env, jobject _this, RsContext con, jint bits)
219{
220    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
221    rsContextDump((RsContext)con, bits);
222}
223
224static void
225nContextPause(JNIEnv *_env, jobject _this, RsContext con)
226{
227    LOG_API("nContextPause, con(%p)", con);
228    rsContextPause(con);
229}
230
231static void
232nContextResume(JNIEnv *_env, jobject _this, RsContext con)
233{
234    LOG_API("nContextResume, con(%p)", con);
235    rsContextResume(con);
236}
237
238static jint
239nContextGetMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data, jboolean wait)
240{
241    jint len = _env->GetArrayLength(data);
242    LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
243    jint *ptr = _env->GetIntArrayElements(data, NULL);
244    size_t receiveLen;
245    int id = rsContextGetMessage(con, ptr, &receiveLen, len * 4, wait);
246    if (!id && receiveLen) {
247        LOGV("message receive buffer too small.  %i", receiveLen);
248        *ptr = (jint)receiveLen;
249    }
250    _env->ReleaseIntArrayElements(data, ptr, 0);
251    return id;
252}
253
254static void nContextInitToClient(JNIEnv *_env, jobject _this, RsContext con)
255{
256    LOG_API("nContextInitToClient, con(%p)", con);
257    rsContextInitToClient(con);
258}
259
260static void nContextDeinitToClient(JNIEnv *_env, jobject _this, RsContext con)
261{
262    LOG_API("nContextDeinitToClient, con(%p)", con);
263    rsContextDeinitToClient(con);
264}
265
266
267static jint
268nElementCreate(JNIEnv *_env, jobject _this, RsContext con, jint type, jint kind, jboolean norm, jint size)
269{
270    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size);
271    return (jint)rsElementCreate(con, (RsDataType)type, (RsDataKind)kind, norm, size);
272}
273
274static jint
275nElementCreate2(JNIEnv *_env, jobject _this, RsContext con, jintArray _ids, jobjectArray _names, jintArray _arraySizes)
276{
277    int fieldCount = _env->GetArrayLength(_ids);
278    LOG_API("nElementCreate2, con(%p)", con);
279
280    jint *ids = _env->GetIntArrayElements(_ids, NULL);
281    jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
282    const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
283    size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t));
284
285    for (int ct=0; ct < fieldCount; ct++) {
286        jstring s = (jstring)_env->GetObjectArrayElement(_names, ct);
287        nameArray[ct] = _env->GetStringUTFChars(s, NULL);
288        sizeArray[ct] = _env->GetStringUTFLength(s);
289    }
290    jint id = (jint)rsElementCreate2(con, fieldCount, (RsElement *)ids, nameArray, sizeArray, (const uint32_t *)arraySizes);
291    for (int ct=0; ct < fieldCount; ct++) {
292        jstring s = (jstring)_env->GetObjectArrayElement(_names, ct);
293        _env->ReleaseStringUTFChars(s, nameArray[ct]);
294    }
295    _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT);
296    _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT);
297    free(nameArray);
298    free(sizeArray);
299    return (jint)id;
300}
301
302static void
303nElementGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _elementData)
304{
305    int dataSize = _env->GetArrayLength(_elementData);
306    LOG_API("nElementGetNativeData, con(%p)", con);
307
308    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
309    assert(dataSize == 5);
310
311    uint32_t elementData[5];
312    rsaElementGetNativeData(con, (RsElement)id, elementData, dataSize);
313
314    for(jint i = 0; i < dataSize; i ++) {
315        _env->SetIntArrayRegion(_elementData, i, 1, (const jint*)&elementData[i]);
316    }
317}
318
319
320static void
321nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _IDs, jobjectArray _names)
322{
323    int dataSize = _env->GetArrayLength(_IDs);
324    LOG_API("nElementGetSubElements, con(%p)", con);
325
326    uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
327    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
328
329    rsaElementGetSubElements(con, (RsElement)id, ids, names, (uint32_t)dataSize);
330
331    for(jint i = 0; i < dataSize; i++) {
332        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
333        _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
334    }
335
336    free(ids);
337    free(names);
338}
339
340// -----------------------------------
341
342static int
343nTypeCreate(JNIEnv *_env, jobject _this, RsContext con, RsElement eid, jintArray _dims, jintArray _dimValues)
344{
345    int count = _env->GetArrayLength(_dims);
346    LOG_API("nTypeCreate, con(%p)", con);
347
348    jint *dimPtr = _env->GetIntArrayElements(_dims, NULL);
349    jint *dimValPtr = _env->GetIntArrayElements(_dimValues, NULL);
350
351    jint id = (jint)rsaTypeCreate(con, (RsElement)eid, count,
352                                  (RsDimension *)dimPtr, (uint32_t *)dimValPtr);
353
354    _env->ReleaseIntArrayElements(_dims, dimPtr, JNI_ABORT);
355    _env->ReleaseIntArrayElements(_dimValues, dimValPtr, JNI_ABORT);
356    return (jint)id;
357}
358
359static void
360nTypeGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _typeData)
361{
362    // We are packing 6 items: mDimX; mDimY; mDimZ;
363    // mDimLOD; mDimFaces; mElement; into typeData
364    int elementCount = _env->GetArrayLength(_typeData);
365
366    assert(elementCount == 6);
367    LOG_API("nTypeCreate, con(%p)", con);
368
369    uint32_t typeData[6];
370    rsaTypeGetNativeData(con, (RsType)id, typeData, 6);
371
372    for(jint i = 0; i < elementCount; i ++) {
373        _env->SetIntArrayRegion(_typeData, i, 1, (const jint*)&typeData[i]);
374    }
375}
376
377// -----------------------------------
378
379static jint
380nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint e)
381{
382    LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e);
383    return (jint) rsaAllocationCreateTyped(con, (RsElement)e);
384}
385
386static void
387nAllocationUploadToTexture(JNIEnv *_env, jobject _this, RsContext con, jint a, jboolean genMip, jint mip)
388{
389    LOG_API("nAllocationUploadToTexture, con(%p), a(%p), genMip(%i), mip(%i)", con, (RsAllocation)a, genMip, mip);
390    rsAllocationUploadToTexture(con, (RsAllocation)a, genMip, mip);
391}
392
393static void
394nAllocationUploadToBufferObject(JNIEnv *_env, jobject _this, RsContext con, jint a)
395{
396    LOG_API("nAllocationUploadToBufferObject, con(%p), a(%p)", con, (RsAllocation)a);
397    rsAllocationUploadToBufferObject(con, (RsAllocation)a);
398}
399
400static RsElement SkBitmapToPredefined(SkBitmap::Config cfg)
401{
402    switch (cfg) {
403    case SkBitmap::kA8_Config:
404        return g_A_8;
405    case SkBitmap::kARGB_4444_Config:
406        return g_RGBA_4444;
407    case SkBitmap::kARGB_8888_Config:
408        return g_RGBA_8888;
409    case SkBitmap::kRGB_565_Config:
410        return g_RGB_565;
411
412    default:
413        break;
414    }
415    // If we don't have a conversion mark it as a user type.
416    LOGE("Unsupported bitmap type");
417    return NULL;
418}
419
420static int
421nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint dstFmt, jboolean genMips, jobject jbitmap)
422{
423    SkBitmap const * nativeBitmap =
424            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
425    const SkBitmap& bitmap(*nativeBitmap);
426    SkBitmap::Config config = bitmap.getConfig();
427
428    RsElement e = SkBitmapToPredefined(config);
429    if (e) {
430        bitmap.lockPixels();
431        const int w = bitmap.width();
432        const int h = bitmap.height();
433        const void* ptr = bitmap.getPixels();
434        jint id = (jint)rsaAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
435        bitmap.unlockPixels();
436        return id;
437    }
438    return 0;
439}
440
441static void
442nAllocationUpdateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
443{
444    SkBitmap const * nativeBitmap =
445            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
446    const SkBitmap& bitmap(*nativeBitmap);
447    SkBitmap::Config config = bitmap.getConfig();
448
449    RsElement e = SkBitmapToPredefined(config);
450    if (e) {
451        bitmap.lockPixels();
452        const void* ptr = bitmap.getPixels();
453        rsAllocationUpdateFromBitmap(con, (RsAllocation)alloc, e, ptr);
454        bitmap.unlockPixels();
455    }
456}
457
458static void ReleaseBitmapCallback(void *bmp)
459{
460    SkBitmap const * nativeBitmap = (SkBitmap const *)bmp;
461    nativeBitmap->unlockPixels();
462}
463
464static int
465nAllocationCreateBitmapRef(JNIEnv *_env, jobject _this, RsContext con, jint type, jobject jbitmap)
466{
467    SkBitmap * nativeBitmap =
468            (SkBitmap *)_env->GetIntField(jbitmap, gNativeBitmapID);
469
470
471    nativeBitmap->lockPixels();
472    void* ptr = nativeBitmap->getPixels();
473    jint id = (jint)rsAllocationCreateBitmapRef(con, (RsType)type, ptr, nativeBitmap, ReleaseBitmapCallback);
474    return id;
475}
476
477static int
478nAllocationCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con, jint dstFmt, jboolean genMips, jint native_asset)
479{
480    Asset* asset = reinterpret_cast<Asset*>(native_asset);
481    SkBitmap bitmap;
482    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
483            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
484
485    SkBitmap::Config config = bitmap.getConfig();
486
487    RsElement e = SkBitmapToPredefined(config);
488
489    if (e) {
490        bitmap.lockPixels();
491        const int w = bitmap.width();
492        const int h = bitmap.height();
493        const void* ptr = bitmap.getPixels();
494        jint id = (jint)rsaAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
495        bitmap.unlockPixels();
496        return id;
497    }
498    return 0;
499}
500
501static void
502nAllocationSubData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint count, jintArray data, int sizeBytes)
503{
504    jint len = _env->GetArrayLength(data);
505    LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
506    jint *ptr = _env->GetIntArrayElements(data, NULL);
507    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
508    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
509}
510
511static void
512nAllocationSubData1D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint count, jshortArray data, int sizeBytes)
513{
514    jint len = _env->GetArrayLength(data);
515    LOG_API("nAllocation1DSubData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
516    jshort *ptr = _env->GetShortArrayElements(data, NULL);
517    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
518    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
519}
520
521static void
522nAllocationSubData1D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint count, jbyteArray data, int sizeBytes)
523{
524    jint len = _env->GetArrayLength(data);
525    LOG_API("nAllocation1DSubData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
526    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
527    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
528    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
529}
530
531static void
532nAllocationSubData1D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint count, jfloatArray data, int sizeBytes)
533{
534    jint len = _env->GetArrayLength(data);
535    LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
536    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
537    rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes);
538    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
539}
540
541static void
542//    native void rsnAllocationSubElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
543nAllocationSubElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint compIdx, jbyteArray data, int sizeBytes)
544{
545    jint len = _env->GetArrayLength(data);
546    LOG_API("nAllocationSubElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
547    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
548    rsAllocation1DSubElementData(con, (RsAllocation)alloc, offset, ptr, compIdx, sizeBytes);
549    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
550}
551
552static void
553nAllocationSubData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data, int sizeBytes)
554{
555    jint len = _env->GetArrayLength(data);
556    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);
557    jint *ptr = _env->GetIntArrayElements(data, NULL);
558    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes);
559    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
560}
561
562static void
563nAllocationSubData2D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint w, jint h, jfloatArray data, int sizeBytes)
564{
565    jint len = _env->GetArrayLength(data);
566    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);
567    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
568    rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes);
569    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
570}
571
572static void
573nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
574{
575    jint len = _env->GetArrayLength(data);
576    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
577    jint *ptr = _env->GetIntArrayElements(data, NULL);
578    rsAllocationRead(con, (RsAllocation)alloc, ptr);
579    _env->ReleaseIntArrayElements(data, ptr, 0);
580}
581
582static void
583nAllocationRead_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jfloatArray data)
584{
585    jint len = _env->GetArrayLength(data);
586    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
587    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
588    rsAllocationRead(con, (RsAllocation)alloc, ptr);
589    _env->ReleaseFloatArrayElements(data, ptr, 0);
590}
591
592static jint
593nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
594{
595    LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a);
596    return (jint) rsaAllocationGetType(con, (RsAllocation)a);
597}
598
599static void
600nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
601{
602    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
603    rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
604}
605
606static void
607nAllocationResize2D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX, jint dimY)
608{
609    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i), sizeY(%i)", con, (RsAllocation)alloc, dimX, dimY);
610    rsAllocationResize2D(con, (RsAllocation)alloc, dimX, dimY);
611}
612
613// -----------------------------------
614
615static int
616nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con, jint native_asset)
617{
618    LOGV("______nFileA3D %u", (uint32_t) native_asset);
619
620    Asset* asset = reinterpret_cast<Asset*>(native_asset);
621
622    jint id = (jint)rsaFileA3DCreateFromAssetStream(con, asset->getBuffer(false), asset->getLength());
623    return id;
624}
625
626static int
627nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D)
628{
629    int32_t numEntries = 0;
630    rsaFileA3DGetNumIndexEntries(con, &numEntries, (RsFile)fileA3D);
631    return numEntries;
632}
633
634static void
635nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
636{
637    LOGV("______nFileA3D %u", (uint32_t) fileA3D);
638    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
639
640    rsaFileA3DGetIndexEntries(con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
641
642    for(jint i = 0; i < numEntries; i ++) {
643        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
644        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
645    }
646
647    free(fileEntries);
648}
649
650static int
651nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint index)
652{
653    LOGV("______nFileA3D %u", (uint32_t) fileA3D);
654    jint id = (jint)rsaFileA3DGetEntryByIndex(con, (uint32_t)index, (RsFile)fileA3D);
655    return id;
656}
657
658// -----------------------------------
659
660static int
661nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName, jint fontSize, jint dpi)
662{
663    const char* fileNameUTF = _env->GetStringUTFChars(fileName, NULL);
664
665    jint id = (jint)rsFontCreateFromFile(con, fileNameUTF, fontSize, dpi);
666    return id;
667}
668
669
670// -----------------------------------
671
672static void
673nAdapter1DBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint alloc)
674{
675    LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc);
676    rsAdapter1DBindAllocation(con, (RsAdapter1D)adapter, (RsAllocation)alloc);
677}
678
679static void
680nAdapter1DSetConstraint(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint dim, jint value)
681{
682    LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value);
683    rsAdapter1DSetConstraint(con, (RsAdapter1D)adapter, (RsDimension)dim, value);
684}
685
686static void
687nAdapter1DData_i(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jintArray data)
688{
689    jint len = _env->GetArrayLength(data);
690    LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
691    jint *ptr = _env->GetIntArrayElements(data, NULL);
692    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
693    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
694}
695
696static void
697nAdapter1DSubData_i(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint offset, jint count, jintArray data)
698{
699    jint len = _env->GetArrayLength(data);
700    LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
701    jint *ptr = _env->GetIntArrayElements(data, NULL);
702    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
703    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
704}
705
706static void
707nAdapter1DData_f(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jfloatArray data)
708{
709    jint len = _env->GetArrayLength(data);
710    LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len);
711    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
712    rsAdapter1DData(con, (RsAdapter1D)adapter, ptr);
713    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
714}
715
716static void
717nAdapter1DSubData_f(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint offset, jint count, jfloatArray data)
718{
719    jint len = _env->GetArrayLength(data);
720    LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len);
721    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
722    rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr);
723    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
724}
725
726static jint
727nAdapter1DCreate(JNIEnv *_env, jobject _this, RsContext con)
728{
729    LOG_API("nAdapter1DCreate, con(%p)", con);
730    return (jint)rsAdapter1DCreate(con);
731}
732
733// -----------------------------------
734
735static void
736nAdapter2DBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint alloc)
737{
738    LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc);
739    rsAdapter2DBindAllocation(con, (RsAdapter2D)adapter, (RsAllocation)alloc);
740}
741
742static void
743nAdapter2DSetConstraint(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint dim, jint value)
744{
745    LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value);
746    rsAdapter2DSetConstraint(con, (RsAdapter2D)adapter, (RsDimension)dim, value);
747}
748
749static void
750nAdapter2DData_i(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jintArray data)
751{
752    jint len = _env->GetArrayLength(data);
753    LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
754    jint *ptr = _env->GetIntArrayElements(data, NULL);
755    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
756    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
757}
758
759static void
760nAdapter2DData_f(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jfloatArray data)
761{
762    jint len = _env->GetArrayLength(data);
763    LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
764    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
765    rsAdapter2DData(con, (RsAdapter2D)adapter, ptr);
766    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
767}
768
769static void
770nAdapter2DSubData_i(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint xoff, jint yoff, jint w, jint h, jintArray data)
771{
772    jint len = _env->GetArrayLength(data);
773    LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
774            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
775    jint *ptr = _env->GetIntArrayElements(data, NULL);
776    rsAdapter2DSubData(con, (RsAdapter2D)adapter, xoff, yoff, w, h, ptr);
777    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
778}
779
780static void
781nAdapter2DSubData_f(JNIEnv *_env, jobject _this, RsContext con, jint adapter, jint xoff, jint yoff, jint w, jint h, jfloatArray data)
782{
783    jint len = _env->GetArrayLength(data);
784    LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
785            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
786    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
787    rsAdapter2DSubData(con, (RsAdapter1D)adapter, xoff, yoff, w, h, ptr);
788    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
789}
790
791static jint
792nAdapter2DCreate(JNIEnv *_env, jobject _this, RsContext con)
793{
794    LOG_API("nAdapter2DCreate, con(%p)", con);
795    return (jint)rsAdapter2DCreate(con);
796}
797
798// -----------------------------------
799
800static void
801nScriptBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint script, jint alloc, jint slot)
802{
803    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
804    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
805}
806
807static void
808nScriptSetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
809{
810    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
811    rsScriptSetVarI(con, (RsScript)script, slot, val);
812}
813
814static void
815nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
816{
817    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
818    rsScriptSetVarJ(con, (RsScript)script, slot, val);
819}
820
821static void
822nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
823{
824    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
825    rsScriptSetVarF(con, (RsScript)script, slot, val);
826}
827
828static void
829nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
830{
831    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
832    rsScriptSetVarD(con, (RsScript)script, slot, val);
833}
834
835static void
836nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
837{
838    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
839    jint len = _env->GetArrayLength(data);
840    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
841    rsScriptSetVarV(con, (RsScript)script, slot, ptr, len);
842    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
843}
844
845
846static void
847nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
848{
849    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
850
851    jint length = _env->GetArrayLength(timeZone);
852    jbyte* timeZone_ptr;
853    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
854
855    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
856
857    if (timeZone_ptr) {
858        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
859    }
860}
861
862static void
863nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
864{
865    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
866    rsScriptInvoke(con, (RsScript)obj, slot);
867}
868
869static void
870nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
871{
872    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
873    jint len = _env->GetArrayLength(data);
874    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
875    rsScriptInvokeV(con, (RsScript)script, slot, ptr, len);
876    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
877}
878
879
880// -----------------------------------
881
882static void
883nScriptCBegin(JNIEnv *_env, jobject _this, RsContext con)
884{
885    LOG_API("nScriptCBegin, con(%p)", con);
886    rsScriptCBegin(con);
887}
888
889static void
890nScriptCSetScript(JNIEnv *_env, jobject _this, RsContext con, jbyteArray scriptRef,
891                  jint offset, jint length)
892{
893    LOG_API("!!! nScriptCSetScript, con(%p)", con);
894    jint _exception = 0;
895    jint remaining;
896    jbyte* script_base = 0;
897    jbyte* script_ptr;
898    if (!scriptRef) {
899        _exception = 1;
900        //_env->ThrowNew(IAEClass, "script == null");
901        goto exit;
902    }
903    if (offset < 0) {
904        _exception = 1;
905        //_env->ThrowNew(IAEClass, "offset < 0");
906        goto exit;
907    }
908    if (length < 0) {
909        _exception = 1;
910        //_env->ThrowNew(IAEClass, "length < 0");
911        goto exit;
912    }
913    remaining = _env->GetArrayLength(scriptRef) - offset;
914    if (remaining < length) {
915        _exception = 1;
916        //_env->ThrowNew(IAEClass, "length > script.length - offset");
917        goto exit;
918    }
919    script_base = (jbyte *)
920        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
921    script_ptr = script_base + offset;
922
923    rsScriptCSetText(con, (const char *)script_ptr, length);
924
925exit:
926    if (script_base) {
927        _env->ReleasePrimitiveArrayCritical(scriptRef, script_base,
928                _exception ? JNI_ABORT: 0);
929    }
930}
931
932static jint
933nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con)
934{
935    LOG_API("nScriptCCreate, con(%p)", con);
936    return (jint)rsScriptCCreate(con);
937}
938
939// ---------------------------------------------------------------------------
940
941static void
942nProgramStoreBegin(JNIEnv *_env, jobject _this, RsContext con, jint in, jint out)
943{
944    LOG_API("nProgramStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
945    rsProgramStoreBegin(con, (RsElement)in, (RsElement)out);
946}
947
948static void
949nProgramStoreDepthFunc(JNIEnv *_env, jobject _this, RsContext con, jint func)
950{
951    LOG_API("nProgramStoreDepthFunc, con(%p), func(%i)", con, func);
952    rsProgramStoreDepthFunc(con, (RsDepthFunc)func);
953}
954
955static void
956nProgramStoreDepthMask(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
957{
958    LOG_API("nProgramStoreDepthMask, con(%p), enable(%i)", con, enable);
959    rsProgramStoreDepthMask(con, enable);
960}
961
962static void
963nProgramStoreColorMask(JNIEnv *_env, jobject _this, RsContext con, jboolean r, jboolean g, jboolean b, jboolean a)
964{
965    LOG_API("nProgramStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
966    rsProgramStoreColorMask(con, r, g, b, a);
967}
968
969static void
970nProgramStoreBlendFunc(JNIEnv *_env, jobject _this, RsContext con, int src, int dst)
971{
972    LOG_API("nProgramStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
973    rsProgramStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
974}
975
976static void
977nProgramStoreDither(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
978{
979    LOG_API("nProgramStoreDither, con(%p), enable(%i)", con, enable);
980    rsProgramStoreDither(con, enable);
981}
982
983static jint
984nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con)
985{
986    LOG_API("nProgramStoreCreate, con(%p)", con);
987    return (jint)rsProgramStoreCreate(con);
988}
989
990// ---------------------------------------------------------------------------
991
992static void
993nProgramBindConstants(JNIEnv *_env, jobject _this, RsContext con, jint vpv, jint slot, jint a)
994{
995    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
996    rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a);
997}
998
999static void
1000nProgramBindTexture(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1001{
1002    LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1003    rsProgramBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1004}
1005
1006static void
1007nProgramBindSampler(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1008{
1009    LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1010    rsProgramBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1011}
1012
1013// ---------------------------------------------------------------------------
1014
1015static jint
1016nProgramFragmentCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
1017{
1018    const char* shaderUTF = _env->GetStringUTFChars(shader, NULL);
1019    jint shaderLen = _env->GetStringUTFLength(shader);
1020    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1021    jint paramLen = _env->GetArrayLength(params);
1022
1023    LOG_API("nProgramFragmentCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
1024
1025    jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen);
1026    _env->ReleaseStringUTFChars(shader, shaderUTF);
1027    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1028    return ret;
1029}
1030
1031
1032// ---------------------------------------------------------------------------
1033
1034static jint
1035nProgramVertexCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
1036{
1037    const char* shaderUTF = _env->GetStringUTFChars(shader, NULL);
1038    jint shaderLen = _env->GetStringUTFLength(shader);
1039    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1040    jint paramLen = _env->GetArrayLength(params);
1041
1042    LOG_API("nProgramVertexCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
1043
1044    jint ret = (jint)rsProgramVertexCreate(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen);
1045    _env->ReleaseStringUTFChars(shader, shaderUTF);
1046    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1047    return ret;
1048}
1049
1050// ---------------------------------------------------------------------------
1051
1052static jint
1053nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite)
1054{
1055    LOG_API("nProgramRasterCreate, con(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)",
1056            con, pointSmooth, lineSmooth, pointSprite);
1057    return (jint)rsProgramRasterCreate(con, pointSmooth, lineSmooth, pointSprite);
1058}
1059
1060static void
1061nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jfloat v)
1062{
1063    LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
1064    rsProgramRasterSetLineWidth(con, (RsProgramRaster)vpr, v);
1065}
1066
1067static void
1068nProgramRasterSetCullMode(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jint v)
1069{
1070    LOG_API("nProgramRasterSetCullMode, con(%p), vpf(%p), value(%i)", con, (RsProgramRaster)vpr, v);
1071    rsProgramRasterSetCullMode(con, (RsProgramRaster)vpr, (RsCullMode)v);
1072}
1073
1074
1075// ---------------------------------------------------------------------------
1076
1077static void
1078nContextBindRootScript(JNIEnv *_env, jobject _this, RsContext con, jint script)
1079{
1080    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
1081    rsContextBindRootScript(con, (RsScript)script);
1082}
1083
1084static void
1085nContextBindProgramStore(JNIEnv *_env, jobject _this, RsContext con, jint pfs)
1086{
1087    LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs);
1088    rsContextBindProgramStore(con, (RsProgramStore)pfs);
1089}
1090
1091static void
1092nContextBindProgramFragment(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1093{
1094    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
1095    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
1096}
1097
1098static void
1099nContextBindProgramVertex(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1100{
1101    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
1102    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
1103}
1104
1105static void
1106nContextBindProgramRaster(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1107{
1108    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
1109    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
1110}
1111
1112
1113// ---------------------------------------------------------------------------
1114
1115static void
1116nSamplerBegin(JNIEnv *_env, jobject _this, RsContext con)
1117{
1118    LOG_API("nSamplerBegin, con(%p)", con);
1119    rsSamplerBegin(con);
1120}
1121
1122static void
1123nSamplerSet(JNIEnv *_env, jobject _this, RsContext con, jint p, jint v)
1124{
1125    LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v);
1126    rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v);
1127}
1128
1129static void
1130nSamplerSet2(JNIEnv *_env, jobject _this, RsContext con, jint p, jfloat v)
1131{
1132    LOG_API("nSamplerSet2, con(%p), param(%i), value(%f)", con, p, v);
1133    rsSamplerSet2(con, (RsSamplerParam)p, v);
1134}
1135
1136static jint
1137nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con)
1138{
1139    LOG_API("nSamplerCreate, con(%p)", con);
1140    return (jint)rsSamplerCreate(con);
1141}
1142
1143// ---------------------------------------------------------------------------
1144
1145static jint
1146nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jint vtxCount, jint idxCount)
1147{
1148    LOG_API("nMeshCreate, con(%p), vtxCount(%i), idxCount(%i)", con, vtxCount, idxCount);
1149    int id = (int)rsMeshCreate(con, vtxCount, idxCount);
1150    return id;
1151}
1152
1153static void
1154nMeshBindVertex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint slot)
1155{
1156    LOG_API("nMeshBindVertex, con(%p), Mesh(%p), Alloc(%p), slot(%i)", con, (RsMesh)mesh, (RsAllocation)alloc, slot);
1157    rsMeshBindVertex(con, (RsMesh)mesh, (RsAllocation)alloc, slot);
1158}
1159
1160static void
1161nMeshBindIndex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint primID, jint slot)
1162{
1163    LOG_API("nMeshBindIndex, con(%p), Mesh(%p), Alloc(%p)", con, (RsMesh)mesh, (RsAllocation)alloc);
1164    rsMeshBindIndex(con, (RsMesh)mesh, (RsAllocation)alloc, primID, slot);
1165}
1166
1167static jint
1168nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1169{
1170    LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1171    jint vtxCount = 0;
1172    rsaMeshGetVertexBufferCount(con, (RsMesh)mesh, &vtxCount);
1173    return vtxCount;
1174}
1175
1176static jint
1177nMeshGetIndexCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1178{
1179    LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1180    jint idxCount = 0;
1181    rsaMeshGetIndexCount(con, (RsMesh)mesh, &idxCount);
1182    return idxCount;
1183}
1184
1185static void
1186nMeshGetVertices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _ids, int numVtxIDs)
1187{
1188    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1189
1190    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
1191    rsaMeshGetVertices(con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
1192
1193    for(jint i = 0; i < numVtxIDs; i ++) {
1194        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]);
1195    }
1196
1197    free(allocs);
1198}
1199
1200static void
1201nMeshGetIndices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
1202{
1203    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1204
1205    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
1206    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
1207
1208    rsaMeshGetIndices(con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
1209
1210    for(jint i = 0; i < numIndices; i ++) {
1211        _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]);
1212        _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]);
1213    }
1214
1215    free(allocs);
1216    free(prims);
1217}
1218
1219// ---------------------------------------------------------------------------
1220
1221
1222static const char *classPathName = "android/renderscript/RenderScript";
1223
1224static JNINativeMethod methods[] = {
1225{"_nInit",                         "()V",                                  (void*)_nInit },
1226{"nInitElements",                  "(IIII)V",                              (void*)nInitElements },
1227
1228{"nDeviceCreate",                  "()I",                                  (void*)nDeviceCreate },
1229{"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
1230{"nDeviceSetConfig",               "(III)V",                               (void*)nDeviceSetConfig },
1231{"nContextGetMessage",             "(I[IZ)I",                               (void*)nContextGetMessage },
1232{"nContextInitToClient",           "(I)V",                                  (void*)nContextInitToClient },
1233{"nContextDeinitToClient",         "(I)V",                                  (void*)nContextDeinitToClient },
1234
1235
1236// All methods below are thread protected in java.
1237{"rsnContextCreate",                 "(II)I",                                 (void*)nContextCreate },
1238{"rsnContextCreateGL",               "(IIIIIIIIIIIIF)I",                      (void*)nContextCreateGL },
1239{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
1240{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
1241{"rsnContextSetSurface",             "(IIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
1242{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
1243{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
1244{"rsnContextPause",                  "(I)V",                                  (void*)nContextPause },
1245{"rsnContextResume",                 "(I)V",                                  (void*)nContextResume },
1246{"rsnAssignName",                    "(II[B)V",                               (void*)nAssignName },
1247{"rsnGetName",                       "(II)Ljava/lang/String;",                (void*)nGetName },
1248{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
1249
1250{"rsnFileOpen",                      "(I[B)I",                                (void*)nFileOpen },
1251{"rsnFileA3DCreateFromAssetStream",  "(II)I",                                 (void*)nFileA3DCreateFromAssetStream },
1252{"rsnFileA3DGetNumIndexEntries",     "(II)I",                                 (void*)nFileA3DGetNumIndexEntries },
1253{"rsnFileA3DGetIndexEntries",        "(III[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
1254{"rsnFileA3DGetEntryByIndex",        "(III)I",                                (void*)nFileA3DGetEntryByIndex },
1255
1256{"rsnFontCreateFromFile",            "(ILjava/lang/String;II)I",              (void*)nFontCreateFromFile },
1257
1258{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
1259{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
1260{"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
1261{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;)V",            (void*)nElementGetSubElements },
1262
1263{"rsnTypeCreate",                    "(II[I[I)I",                             (void*)nTypeCreate },
1264{"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
1265
1266{"rsnAllocationCreateTyped",         "(II)I",                                 (void*)nAllocationCreateTyped },
1267{"rsnAllocationUpdateFromBitmap",    "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationUpdateFromBitmap },
1268{"rsnAllocationCreateFromBitmap",    "(IIZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmap },
1269{"rsnAllocationCreateBitmapRef",     "(IILandroid/graphics/Bitmap;)I",        (void*)nAllocationCreateBitmapRef },
1270{"rsnAllocationCreateFromAssetStream","(IIZI)I",                              (void*)nAllocationCreateFromAssetStream },
1271{"rsnAllocationUploadToTexture",     "(IIZI)V",                               (void*)nAllocationUploadToTexture },
1272{"rsnAllocationUploadToBufferObject","(II)V",                                 (void*)nAllocationUploadToBufferObject },
1273{"rsnAllocationSubData1D",           "(IIII[II)V",                            (void*)nAllocationSubData1D_i },
1274{"rsnAllocationSubData1D",           "(IIII[SI)V",                            (void*)nAllocationSubData1D_s },
1275{"rsnAllocationSubData1D",           "(IIII[BI)V",                            (void*)nAllocationSubData1D_b },
1276{"rsnAllocationSubData1D",           "(IIII[FI)V",                            (void*)nAllocationSubData1D_f },
1277{"rsnAllocationSubElementData1D",    "(IIII[BI)V",                            (void*)nAllocationSubElementData1D },
1278{"rsnAllocationSubData2D",           "(IIIIII[II)V",                          (void*)nAllocationSubData2D_i },
1279{"rsnAllocationSubData2D",           "(IIIIII[FI)V",                          (void*)nAllocationSubData2D_f },
1280{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
1281{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
1282{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
1283{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
1284{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
1285
1286{"rsnAdapter1DBindAllocation",       "(III)V",                                (void*)nAdapter1DBindAllocation },
1287{"rsnAdapter1DSetConstraint",        "(IIII)V",                               (void*)nAdapter1DSetConstraint },
1288{"rsnAdapter1DData",                 "(II[I)V",                               (void*)nAdapter1DData_i },
1289{"rsnAdapter1DData",                 "(II[F)V",                               (void*)nAdapter1DData_f },
1290{"rsnAdapter1DSubData",              "(IIII[I)V",                             (void*)nAdapter1DSubData_i },
1291{"rsnAdapter1DSubData",              "(IIII[F)V",                             (void*)nAdapter1DSubData_f },
1292{"rsnAdapter1DCreate",               "(I)I",                                  (void*)nAdapter1DCreate },
1293
1294{"rsnAdapter2DBindAllocation",       "(III)V",                                (void*)nAdapter2DBindAllocation },
1295{"rsnAdapter2DSetConstraint",        "(IIII)V",                               (void*)nAdapter2DSetConstraint },
1296{"rsnAdapter2DData",                 "(II[I)V",                               (void*)nAdapter2DData_i },
1297{"rsnAdapter2DData",                 "(II[F)V",                               (void*)nAdapter2DData_f },
1298{"rsnAdapter2DSubData",              "(IIIIII[I)V",                           (void*)nAdapter2DSubData_i },
1299{"rsnAdapter2DSubData",              "(IIIIII[F)V",                           (void*)nAdapter2DSubData_f },
1300{"rsnAdapter2DCreate",               "(I)I",                                  (void*)nAdapter2DCreate },
1301
1302{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
1303{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
1304{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
1305{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
1306{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
1307{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
1308{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
1309{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
1310{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
1311
1312{"rsnScriptCBegin",                  "(I)V",                                  (void*)nScriptCBegin },
1313{"rsnScriptCSetScript",              "(I[BII)V",                              (void*)nScriptCSetScript },
1314{"rsnScriptCCreate",                 "(I)I",                                  (void*)nScriptCCreate },
1315
1316{"rsnProgramStoreBegin",             "(III)V",                                (void*)nProgramStoreBegin },
1317{"rsnProgramStoreDepthFunc",         "(II)V",                                 (void*)nProgramStoreDepthFunc },
1318{"rsnProgramStoreDepthMask",         "(IZ)V",                                 (void*)nProgramStoreDepthMask },
1319{"rsnProgramStoreColorMask",         "(IZZZZ)V",                              (void*)nProgramStoreColorMask },
1320{"rsnProgramStoreBlendFunc",         "(III)V",                                (void*)nProgramStoreBlendFunc },
1321{"rsnProgramStoreDither",            "(IZ)V",                                 (void*)nProgramStoreDither },
1322{"rsnProgramStoreCreate",            "(I)I",                                  (void*)nProgramStoreCreate },
1323
1324{"rsnProgramBindConstants",          "(IIII)V",                               (void*)nProgramBindConstants },
1325{"rsnProgramBindTexture",            "(IIII)V",                               (void*)nProgramBindTexture },
1326{"rsnProgramBindSampler",            "(IIII)V",                               (void*)nProgramBindSampler },
1327
1328{"rsnProgramFragmentCreate",        "(ILjava/lang/String;[I)I",               (void*)nProgramFragmentCreate },
1329
1330{"rsnProgramRasterCreate",           "(IZZZ)I",                               (void*)nProgramRasterCreate },
1331{"rsnProgramRasterSetLineWidth",     "(IIF)V",                                (void*)nProgramRasterSetLineWidth },
1332{"rsnProgramRasterSetCullMode",      "(III)V",                                (void*)nProgramRasterSetCullMode },
1333
1334{"rsnProgramVertexCreate",          "(ILjava/lang/String;[I)I",               (void*)nProgramVertexCreate },
1335
1336{"rsnContextBindRootScript",         "(II)V",                                 (void*)nContextBindRootScript },
1337{"rsnContextBindProgramStore",       "(II)V",                                 (void*)nContextBindProgramStore },
1338{"rsnContextBindProgramFragment",    "(II)V",                                 (void*)nContextBindProgramFragment },
1339{"rsnContextBindProgramVertex",      "(II)V",                                 (void*)nContextBindProgramVertex },
1340{"rsnContextBindProgramRaster",      "(II)V",                                 (void*)nContextBindProgramRaster },
1341
1342{"rsnSamplerBegin",                  "(I)V",                                  (void*)nSamplerBegin },
1343{"rsnSamplerSet",                    "(III)V",                                (void*)nSamplerSet },
1344{"rsnSamplerSet2",                   "(IIF)V",                                (void*)nSamplerSet2 },
1345{"rsnSamplerCreate",                 "(I)I",                                  (void*)nSamplerCreate },
1346
1347{"rsnMeshCreate",                    "(III)I",                                (void*)nMeshCreate },
1348{"rsnMeshBindVertex",                "(IIII)V",                               (void*)nMeshBindVertex },
1349{"rsnMeshBindIndex",                 "(IIIII)V",                              (void*)nMeshBindIndex },
1350
1351{"rsnMeshGetVertexBufferCount",      "(II)I",                                 (void*)nMeshGetVertexBufferCount },
1352{"rsnMeshGetIndexCount",             "(II)I",                                 (void*)nMeshGetIndexCount },
1353{"rsnMeshGetVertices",               "(II[II)V",                              (void*)nMeshGetVertices },
1354{"rsnMeshGetIndices",                "(II[I[II)V",                            (void*)nMeshGetIndices },
1355
1356};
1357
1358static int registerFuncs(JNIEnv *_env)
1359{
1360    return android::AndroidRuntime::registerNativeMethods(
1361            _env, classPathName, methods, NELEM(methods));
1362}
1363
1364// ---------------------------------------------------------------------------
1365
1366jint JNI_OnLoad(JavaVM* vm, void* reserved)
1367{
1368    JNIEnv* env = NULL;
1369    jint result = -1;
1370
1371    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1372        LOGE("ERROR: GetEnv failed\n");
1373        goto bail;
1374    }
1375    assert(env != NULL);
1376
1377    if (registerFuncs(env) < 0) {
1378        LOGE("ERROR: MediaPlayer native registration failed\n");
1379        goto bail;
1380    }
1381
1382    /* success -- return valid version number */
1383    result = JNI_VERSION_1_4;
1384
1385bail:
1386    return result;
1387}
1388
1389