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