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