android_renderscript_RenderScript.cpp revision 1c41517124a90fcfdb95dc069fc492c6fcf1ff25
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
832nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
833{
834    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
835    rsScriptSetVarJ(con, (RsScript)script, slot, val);
836}
837
838static void
839nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
840{
841    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
842    rsScriptSetVarF(con, (RsScript)script, slot, val);
843}
844
845static void
846nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
847{
848    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
849    rsScriptSetVarD(con, (RsScript)script, slot, val);
850}
851
852static void
853nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
854{
855    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
856    jint len = _env->GetArrayLength(data);
857    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
858    rsScriptSetVarV(con, (RsScript)script, slot, ptr, len);
859    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
860}
861
862
863static void
864nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
865{
866    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
867
868    jint length = _env->GetArrayLength(timeZone);
869    jbyte* timeZone_ptr;
870    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
871
872    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
873
874    if (timeZone_ptr) {
875        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
876    }
877}
878
879static void
880nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
881{
882    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
883    rsScriptInvoke(con, (RsScript)obj, slot);
884}
885
886static void
887nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
888{
889    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
890    jint len = _env->GetArrayLength(data);
891    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
892    rsScriptInvokeV(con, (RsScript)script, slot, ptr, len);
893    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
894}
895
896
897// -----------------------------------
898
899static void
900nScriptCBegin(JNIEnv *_env, jobject _this, RsContext con)
901{
902    LOG_API("nScriptCBegin, con(%p)", con);
903    rsScriptCBegin(con);
904}
905
906static void
907nScriptCSetScript(JNIEnv *_env, jobject _this, RsContext con, jbyteArray scriptRef,
908                  jint offset, jint length)
909{
910    LOG_API("!!! nScriptCSetScript, con(%p)", con);
911    jint _exception = 0;
912    jint remaining;
913    jbyte* script_base = 0;
914    jbyte* script_ptr;
915    if (!scriptRef) {
916        _exception = 1;
917        //_env->ThrowNew(IAEClass, "script == null");
918        goto exit;
919    }
920    if (offset < 0) {
921        _exception = 1;
922        //_env->ThrowNew(IAEClass, "offset < 0");
923        goto exit;
924    }
925    if (length < 0) {
926        _exception = 1;
927        //_env->ThrowNew(IAEClass, "length < 0");
928        goto exit;
929    }
930    remaining = _env->GetArrayLength(scriptRef) - offset;
931    if (remaining < length) {
932        _exception = 1;
933        //_env->ThrowNew(IAEClass, "length > script.length - offset");
934        goto exit;
935    }
936    script_base = (jbyte *)
937        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
938    script_ptr = script_base + offset;
939
940    rsScriptCSetText(con, (const char *)script_ptr, length);
941
942exit:
943    if (script_base) {
944        _env->ReleasePrimitiveArrayCritical(scriptRef, script_base,
945                _exception ? JNI_ABORT: 0);
946    }
947}
948
949static jint
950nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con)
951{
952    LOG_API("nScriptCCreate, con(%p)", con);
953    return (jint)rsScriptCCreate(con);
954}
955
956// ---------------------------------------------------------------------------
957
958static void
959nProgramStoreBegin(JNIEnv *_env, jobject _this, RsContext con, jint in, jint out)
960{
961    LOG_API("nProgramStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
962    rsProgramStoreBegin(con, (RsElement)in, (RsElement)out);
963}
964
965static void
966nProgramStoreDepthFunc(JNIEnv *_env, jobject _this, RsContext con, jint func)
967{
968    LOG_API("nProgramStoreDepthFunc, con(%p), func(%i)", con, func);
969    rsProgramStoreDepthFunc(con, (RsDepthFunc)func);
970}
971
972static void
973nProgramStoreDepthMask(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
974{
975    LOG_API("nProgramStoreDepthMask, con(%p), enable(%i)", con, enable);
976    rsProgramStoreDepthMask(con, enable);
977}
978
979static void
980nProgramStoreColorMask(JNIEnv *_env, jobject _this, RsContext con, jboolean r, jboolean g, jboolean b, jboolean a)
981{
982    LOG_API("nProgramStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a);
983    rsProgramStoreColorMask(con, r, g, b, a);
984}
985
986static void
987nProgramStoreBlendFunc(JNIEnv *_env, jobject _this, RsContext con, int src, int dst)
988{
989    LOG_API("nProgramStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst);
990    rsProgramStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst);
991}
992
993static void
994nProgramStoreDither(JNIEnv *_env, jobject _this, RsContext con, jboolean enable)
995{
996    LOG_API("nProgramStoreDither, con(%p), enable(%i)", con, enable);
997    rsProgramStoreDither(con, enable);
998}
999
1000static jint
1001nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con)
1002{
1003    LOG_API("nProgramStoreCreate, con(%p)", con);
1004    return (jint)rsProgramStoreCreate(con);
1005}
1006
1007// ---------------------------------------------------------------------------
1008
1009static void
1010nProgramBindConstants(JNIEnv *_env, jobject _this, RsContext con, jint vpv, jint slot, jint a)
1011{
1012    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
1013    rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a);
1014}
1015
1016static void
1017nProgramBindTexture(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1018{
1019    LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1020    rsProgramBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1021}
1022
1023static void
1024nProgramBindSampler(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1025{
1026    LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1027    rsProgramBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1028}
1029
1030// ---------------------------------------------------------------------------
1031
1032static jint
1033nProgramFragmentCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
1034{
1035    const char* shaderUTF = _env->GetStringUTFChars(shader, NULL);
1036    jint shaderLen = _env->GetStringUTFLength(shader);
1037    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1038    jint paramLen = _env->GetArrayLength(params);
1039
1040    LOG_API("nProgramFragmentCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
1041
1042    jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen);
1043    _env->ReleaseStringUTFChars(shader, shaderUTF);
1044    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1045    return ret;
1046}
1047
1048
1049// ---------------------------------------------------------------------------
1050
1051static jint
1052nProgramVertexCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader, jintArray params)
1053{
1054    const char* shaderUTF = _env->GetStringUTFChars(shader, NULL);
1055    jint shaderLen = _env->GetStringUTFLength(shader);
1056    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1057    jint paramLen = _env->GetArrayLength(params);
1058
1059    LOG_API("nProgramVertexCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
1060
1061    jint ret = (jint)rsProgramVertexCreate(con, shaderUTF, shaderLen, (uint32_t *)paramPtr, paramLen);
1062    _env->ReleaseStringUTFChars(shader, shaderUTF);
1063    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1064    return ret;
1065}
1066
1067// ---------------------------------------------------------------------------
1068
1069static jint
1070nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite)
1071{
1072    LOG_API("nProgramRasterCreate, con(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)",
1073            con, pointSmooth, lineSmooth, pointSprite);
1074    return (jint)rsProgramRasterCreate(con, pointSmooth, lineSmooth, pointSprite);
1075}
1076
1077static void
1078nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jfloat v)
1079{
1080    LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
1081    rsProgramRasterSetLineWidth(con, (RsProgramRaster)vpr, v);
1082}
1083
1084static void
1085nProgramRasterSetCullMode(JNIEnv *_env, jobject _this, RsContext con, jint vpr, jint v)
1086{
1087    LOG_API("nProgramRasterSetCullMode, con(%p), vpf(%p), value(%i)", con, (RsProgramRaster)vpr, v);
1088    rsProgramRasterSetCullMode(con, (RsProgramRaster)vpr, (RsCullMode)v);
1089}
1090
1091
1092// ---------------------------------------------------------------------------
1093
1094static void
1095nContextBindRootScript(JNIEnv *_env, jobject _this, RsContext con, jint script)
1096{
1097    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
1098    rsContextBindRootScript(con, (RsScript)script);
1099}
1100
1101static void
1102nContextBindProgramStore(JNIEnv *_env, jobject _this, RsContext con, jint pfs)
1103{
1104    LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs);
1105    rsContextBindProgramStore(con, (RsProgramStore)pfs);
1106}
1107
1108static void
1109nContextBindProgramFragment(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1110{
1111    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
1112    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
1113}
1114
1115static void
1116nContextBindProgramVertex(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1117{
1118    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
1119    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
1120}
1121
1122static void
1123nContextBindProgramRaster(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1124{
1125    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
1126    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
1127}
1128
1129
1130// ---------------------------------------------------------------------------
1131
1132static void
1133nSamplerBegin(JNIEnv *_env, jobject _this, RsContext con)
1134{
1135    LOG_API("nSamplerBegin, con(%p)", con);
1136    rsSamplerBegin(con);
1137}
1138
1139static void
1140nSamplerSet(JNIEnv *_env, jobject _this, RsContext con, jint p, jint v)
1141{
1142    LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v);
1143    rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v);
1144}
1145
1146static void
1147nSamplerSet2(JNIEnv *_env, jobject _this, RsContext con, jint p, jfloat v)
1148{
1149    LOG_API("nSamplerSet2, con(%p), param(%i), value(%f)", con, p, v);
1150    rsSamplerSet2(con, (RsSamplerParam)p, v);
1151}
1152
1153static jint
1154nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con)
1155{
1156    LOG_API("nSamplerCreate, con(%p)", con);
1157    return (jint)rsSamplerCreate(con);
1158}
1159
1160// ---------------------------------------------------------------------------
1161
1162static jint
1163nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jint vtxCount, jint idxCount)
1164{
1165    LOG_API("nMeshCreate, con(%p), vtxCount(%i), idxCount(%i)", con, vtxCount, idxCount);
1166    int id = (int)rsMeshCreate(con, vtxCount, idxCount);
1167    return id;
1168}
1169
1170static void
1171nMeshBindVertex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint slot)
1172{
1173    LOG_API("nMeshBindVertex, con(%p), Mesh(%p), Alloc(%p), slot(%i)", con, (RsMesh)mesh, (RsAllocation)alloc, slot);
1174    rsMeshBindVertex(con, (RsMesh)mesh, (RsAllocation)alloc, slot);
1175}
1176
1177static void
1178nMeshBindIndex(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jint alloc, jint primID, jint slot)
1179{
1180    LOG_API("nMeshBindIndex, con(%p), Mesh(%p), Alloc(%p)", con, (RsMesh)mesh, (RsAllocation)alloc);
1181    rsMeshBindIndex(con, (RsMesh)mesh, (RsAllocation)alloc, primID, slot);
1182}
1183
1184static void
1185nMeshInitVertexAttribs(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1186{
1187    LOG_API("nMeshInitVertexAttribs, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1188    rsMeshInitVertexAttribs(con, (RsMesh)mesh);
1189}
1190
1191
1192static jint
1193nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1194{
1195    LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1196    jint vtxCount = 0;
1197    rsaMeshGetVertexBufferCount(con, (RsMesh)mesh, &vtxCount);
1198    return vtxCount;
1199}
1200
1201static jint
1202nMeshGetIndexCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1203{
1204    LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1205    jint idxCount = 0;
1206    rsaMeshGetIndexCount(con, (RsMesh)mesh, &idxCount);
1207    return idxCount;
1208}
1209
1210static void
1211nMeshGetVertices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _ids, int numVtxIDs)
1212{
1213    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1214
1215    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
1216    rsaMeshGetVertices(con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
1217
1218    for(jint i = 0; i < numVtxIDs; i ++) {
1219        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]);
1220    }
1221
1222    free(allocs);
1223}
1224
1225static void
1226nMeshGetIndices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
1227{
1228    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1229
1230    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
1231    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
1232
1233    rsaMeshGetIndices(con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
1234
1235    for(jint i = 0; i < numIndices; i ++) {
1236        _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]);
1237        _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]);
1238    }
1239
1240    free(allocs);
1241    free(prims);
1242}
1243
1244// ---------------------------------------------------------------------------
1245
1246
1247static const char *classPathName = "android/renderscript/RenderScript";
1248
1249static JNINativeMethod methods[] = {
1250{"_nInit",                         "()V",                                     (void*)_nInit },
1251{"nInitElements",                  "(IIII)V",                                 (void*)nInitElements },
1252
1253{"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
1254{"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
1255{"nDeviceSetConfig",               "(III)V",                                  (void*)nDeviceSetConfig },
1256{"nContextGetUserMessage",         "(I[I)V",                                  (void*)nContextGetUserMessage },
1257{"nContextGetErrorMessage",        "(I)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1258{"nContextPeekMessage",            "(I[IZ)I",                                 (void*)nContextPeekMessage },
1259
1260{"nContextInitToClient",           "(I)V",                                    (void*)nContextInitToClient },
1261{"nContextDeinitToClient",         "(I)V",                                    (void*)nContextDeinitToClient },
1262
1263
1264// All methods below are thread protected in java.
1265{"rsnContextCreate",                 "(II)I",                                 (void*)nContextCreate },
1266{"rsnContextCreateGL",               "(IIIIIIIIIIIIF)I",                      (void*)nContextCreateGL },
1267{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
1268{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
1269{"rsnContextSetSurface",             "(IIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
1270{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
1271{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
1272{"rsnContextPause",                  "(I)V",                                  (void*)nContextPause },
1273{"rsnContextResume",                 "(I)V",                                  (void*)nContextResume },
1274{"rsnAssignName",                    "(II[B)V",                               (void*)nAssignName },
1275{"rsnGetName",                       "(II)Ljava/lang/String;",                (void*)nGetName },
1276{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
1277
1278{"rsnFileA3DCreateFromAssetStream",  "(II)I",                                 (void*)nFileA3DCreateFromAssetStream },
1279{"rsnFileA3DGetNumIndexEntries",     "(II)I",                                 (void*)nFileA3DGetNumIndexEntries },
1280{"rsnFileA3DGetIndexEntries",        "(III[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
1281{"rsnFileA3DGetEntryByIndex",        "(III)I",                                (void*)nFileA3DGetEntryByIndex },
1282
1283{"rsnFontCreateFromFile",            "(ILjava/lang/String;II)I",              (void*)nFontCreateFromFile },
1284
1285{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
1286{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
1287{"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
1288{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;)V",            (void*)nElementGetSubElements },
1289
1290{"rsnTypeCreate",                    "(II[I[I)I",                             (void*)nTypeCreate },
1291{"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
1292
1293{"rsnAllocationCreateTyped",         "(II)I",                                 (void*)nAllocationCreateTyped },
1294{"rsnAllocationUpdateFromBitmap",    "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationUpdateFromBitmap },
1295{"rsnAllocationCreateFromBitmap",    "(IIZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmap },
1296{"rsnAllocationCreateBitmapRef",     "(IILandroid/graphics/Bitmap;)I",        (void*)nAllocationCreateBitmapRef },
1297{"rsnAllocationCreateFromAssetStream","(IIZI)I",                              (void*)nAllocationCreateFromAssetStream },
1298{"rsnAllocationUploadToTexture",     "(IIZI)V",                               (void*)nAllocationUploadToTexture },
1299{"rsnAllocationUploadToBufferObject","(II)V",                                 (void*)nAllocationUploadToBufferObject },
1300{"rsnAllocationSubData1D",           "(IIII[II)V",                            (void*)nAllocationSubData1D_i },
1301{"rsnAllocationSubData1D",           "(IIII[SI)V",                            (void*)nAllocationSubData1D_s },
1302{"rsnAllocationSubData1D",           "(IIII[BI)V",                            (void*)nAllocationSubData1D_b },
1303{"rsnAllocationSubData1D",           "(IIII[FI)V",                            (void*)nAllocationSubData1D_f },
1304{"rsnAllocationSubElementData1D",    "(IIII[BI)V",                            (void*)nAllocationSubElementData1D },
1305{"rsnAllocationSubData2D",           "(IIIIII[II)V",                          (void*)nAllocationSubData2D_i },
1306{"rsnAllocationSubData2D",           "(IIIIII[FI)V",                          (void*)nAllocationSubData2D_f },
1307{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
1308{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
1309{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
1310{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
1311{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
1312
1313{"rsnAdapter1DBindAllocation",       "(III)V",                                (void*)nAdapter1DBindAllocation },
1314{"rsnAdapter1DSetConstraint",        "(IIII)V",                               (void*)nAdapter1DSetConstraint },
1315{"rsnAdapter1DData",                 "(II[I)V",                               (void*)nAdapter1DData_i },
1316{"rsnAdapter1DData",                 "(II[F)V",                               (void*)nAdapter1DData_f },
1317{"rsnAdapter1DSubData",              "(IIII[I)V",                             (void*)nAdapter1DSubData_i },
1318{"rsnAdapter1DSubData",              "(IIII[F)V",                             (void*)nAdapter1DSubData_f },
1319{"rsnAdapter1DCreate",               "(I)I",                                  (void*)nAdapter1DCreate },
1320
1321{"rsnAdapter2DBindAllocation",       "(III)V",                                (void*)nAdapter2DBindAllocation },
1322{"rsnAdapter2DSetConstraint",        "(IIII)V",                               (void*)nAdapter2DSetConstraint },
1323{"rsnAdapter2DData",                 "(II[I)V",                               (void*)nAdapter2DData_i },
1324{"rsnAdapter2DData",                 "(II[F)V",                               (void*)nAdapter2DData_f },
1325{"rsnAdapter2DSubData",              "(IIIIII[I)V",                           (void*)nAdapter2DSubData_i },
1326{"rsnAdapter2DSubData",              "(IIIIII[F)V",                           (void*)nAdapter2DSubData_f },
1327{"rsnAdapter2DCreate",               "(I)I",                                  (void*)nAdapter2DCreate },
1328
1329{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
1330{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
1331{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
1332{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
1333{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
1334{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
1335{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
1336{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
1337{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
1338
1339{"rsnScriptCBegin",                  "(I)V",                                  (void*)nScriptCBegin },
1340{"rsnScriptCSetScript",              "(I[BII)V",                              (void*)nScriptCSetScript },
1341{"rsnScriptCCreate",                 "(I)I",                                  (void*)nScriptCCreate },
1342
1343{"rsnProgramStoreBegin",             "(III)V",                                (void*)nProgramStoreBegin },
1344{"rsnProgramStoreDepthFunc",         "(II)V",                                 (void*)nProgramStoreDepthFunc },
1345{"rsnProgramStoreDepthMask",         "(IZ)V",                                 (void*)nProgramStoreDepthMask },
1346{"rsnProgramStoreColorMask",         "(IZZZZ)V",                              (void*)nProgramStoreColorMask },
1347{"rsnProgramStoreBlendFunc",         "(III)V",                                (void*)nProgramStoreBlendFunc },
1348{"rsnProgramStoreDither",            "(IZ)V",                                 (void*)nProgramStoreDither },
1349{"rsnProgramStoreCreate",            "(I)I",                                  (void*)nProgramStoreCreate },
1350
1351{"rsnProgramBindConstants",          "(IIII)V",                               (void*)nProgramBindConstants },
1352{"rsnProgramBindTexture",            "(IIII)V",                               (void*)nProgramBindTexture },
1353{"rsnProgramBindSampler",            "(IIII)V",                               (void*)nProgramBindSampler },
1354
1355{"rsnProgramFragmentCreate",        "(ILjava/lang/String;[I)I",               (void*)nProgramFragmentCreate },
1356
1357{"rsnProgramRasterCreate",           "(IZZZ)I",                               (void*)nProgramRasterCreate },
1358{"rsnProgramRasterSetLineWidth",     "(IIF)V",                                (void*)nProgramRasterSetLineWidth },
1359{"rsnProgramRasterSetCullMode",      "(III)V",                                (void*)nProgramRasterSetCullMode },
1360
1361{"rsnProgramVertexCreate",          "(ILjava/lang/String;[I)I",               (void*)nProgramVertexCreate },
1362
1363{"rsnContextBindRootScript",         "(II)V",                                 (void*)nContextBindRootScript },
1364{"rsnContextBindProgramStore",       "(II)V",                                 (void*)nContextBindProgramStore },
1365{"rsnContextBindProgramFragment",    "(II)V",                                 (void*)nContextBindProgramFragment },
1366{"rsnContextBindProgramVertex",      "(II)V",                                 (void*)nContextBindProgramVertex },
1367{"rsnContextBindProgramRaster",      "(II)V",                                 (void*)nContextBindProgramRaster },
1368
1369{"rsnSamplerBegin",                  "(I)V",                                  (void*)nSamplerBegin },
1370{"rsnSamplerSet",                    "(III)V",                                (void*)nSamplerSet },
1371{"rsnSamplerSet2",                   "(IIF)V",                                (void*)nSamplerSet2 },
1372{"rsnSamplerCreate",                 "(I)I",                                  (void*)nSamplerCreate },
1373
1374{"rsnMeshCreate",                    "(III)I",                                (void*)nMeshCreate },
1375{"rsnMeshBindVertex",                "(IIII)V",                               (void*)nMeshBindVertex },
1376{"rsnMeshBindIndex",                 "(IIIII)V",                              (void*)nMeshBindIndex },
1377{"rsnMeshInitVertexAttribs",         "(II)V",                                 (void*)nMeshInitVertexAttribs },
1378
1379{"rsnMeshGetVertexBufferCount",      "(II)I",                                 (void*)nMeshGetVertexBufferCount },
1380{"rsnMeshGetIndexCount",             "(II)I",                                 (void*)nMeshGetIndexCount },
1381{"rsnMeshGetVertices",               "(II[II)V",                              (void*)nMeshGetVertices },
1382{"rsnMeshGetIndices",                "(II[I[II)V",                            (void*)nMeshGetIndices },
1383
1384};
1385
1386static int registerFuncs(JNIEnv *_env)
1387{
1388    return android::AndroidRuntime::registerNativeMethods(
1389            _env, classPathName, methods, NELEM(methods));
1390}
1391
1392// ---------------------------------------------------------------------------
1393
1394jint JNI_OnLoad(JavaVM* vm, void* reserved)
1395{
1396    JNIEnv* env = NULL;
1397    jint result = -1;
1398
1399    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1400        LOGE("ERROR: GetEnv failed\n");
1401        goto bail;
1402    }
1403    assert(env != NULL);
1404
1405    if (registerFuncs(env) < 0) {
1406        LOGE("ERROR: MediaPlayer native registration failed\n");
1407        goto bail;
1408    }
1409
1410    /* success -- return valid version number */
1411    result = JNI_VERSION_1_4;
1412
1413bail:
1414    return result;
1415}
1416
1417