android_renderscript_RenderScript.cpp revision b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4
1/*
2 * Copyright (C) 2011-2012 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 <androidfw/Asset.h>
35#include <androidfw/AssetManager.h>
36#include <androidfw/ResourceTypes.h>
37
38#include "jni.h"
39#include "JNIHelp.h"
40#include "android_runtime/AndroidRuntime.h"
41#include "android_runtime/android_view_Surface.h"
42#include "android_runtime/android_util_AssetManager.h"
43
44#include <rs.h>
45#include <rsEnv.h>
46#include <gui/SurfaceTexture.h>
47#include <gui/SurfaceTextureClient.h>
48#include <android_runtime/android_graphics_SurfaceTexture.h>
49
50//#define LOG_API ALOGE
51#define LOG_API(...)
52
53using namespace android;
54
55class AutoJavaStringToUTF8 {
56public:
57    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
58        fCStr = env->GetStringUTFChars(str, NULL);
59        fLength = env->GetStringUTFLength(str);
60    }
61    ~AutoJavaStringToUTF8() {
62        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
63    }
64    const char* c_str() const { return fCStr; }
65    jsize length() const { return fLength; }
66
67private:
68    JNIEnv*     fEnv;
69    jstring     fJStr;
70    const char* fCStr;
71    jsize       fLength;
72};
73
74class AutoJavaStringArrayToUTF8 {
75public:
76    AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
77    : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
78        mCStrings = NULL;
79        mSizeArray = NULL;
80        if (stringsLength > 0) {
81            mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
82            mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
83            for (jsize ct = 0; ct < stringsLength; ct ++) {
84                jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
85                mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
86                mSizeArray[ct] = mEnv->GetStringUTFLength(s);
87            }
88        }
89    }
90    ~AutoJavaStringArrayToUTF8() {
91        for (jsize ct=0; ct < mStringsLength; ct++) {
92            jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
93            mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
94        }
95        free(mCStrings);
96        free(mSizeArray);
97    }
98    const char **c_str() const { return mCStrings; }
99    size_t *c_str_len() const { return mSizeArray; }
100    jsize length() const { return mStringsLength; }
101
102private:
103    JNIEnv      *mEnv;
104    jobjectArray mStrings;
105    const char **mCStrings;
106    size_t      *mSizeArray;
107    jsize        mStringsLength;
108};
109
110// ---------------------------------------------------------------------------
111
112static jfieldID gContextId = 0;
113static jfieldID gNativeBitmapID = 0;
114static jfieldID gTypeNativeCache = 0;
115
116static void _nInit(JNIEnv *_env, jclass _this)
117{
118    gContextId             = _env->GetFieldID(_this, "mContext", "I");
119
120    jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
121    gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
122}
123
124// ---------------------------------------------------------------------------
125
126static void
127nContextFinish(JNIEnv *_env, jobject _this, RsContext con)
128{
129    LOG_API("nContextFinish, con(%p)", con);
130    rsContextFinish(con);
131}
132
133static void
134nAssignName(JNIEnv *_env, jobject _this, RsContext con, jint obj, jbyteArray str)
135{
136    LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj);
137    jint len = _env->GetArrayLength(str);
138    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
139    rsAssignName(con, (void *)obj, (const char *)cptr, len);
140    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
141}
142
143static jstring
144nGetName(JNIEnv *_env, jobject _this, RsContext con, jint obj)
145{
146    LOG_API("nGetName, con(%p), obj(%p)", con, (void *)obj);
147    const char *name = NULL;
148    rsaGetName(con, (void *)obj, &name);
149    if(name == NULL || strlen(name) == 0) {
150        return NULL;
151    }
152    return _env->NewStringUTF(name);
153}
154
155static void
156nObjDestroy(JNIEnv *_env, jobject _this, RsContext con, jint obj)
157{
158    LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
159    rsObjDestroy(con, (void *)obj);
160}
161
162// ---------------------------------------------------------------------------
163
164static jint
165nDeviceCreate(JNIEnv *_env, jobject _this)
166{
167    LOG_API("nDeviceCreate");
168    return (jint)rsDeviceCreate();
169}
170
171static void
172nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev)
173{
174    LOG_API("nDeviceDestroy");
175    return rsDeviceDestroy((RsDevice)dev);
176}
177
178static void
179nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value)
180{
181    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
182    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
183}
184
185static jint
186nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer)
187{
188    LOG_API("nContextCreate");
189    return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer);
190}
191
192static jint
193nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer,
194                 int colorMin, int colorPref,
195                 int alphaMin, int alphaPref,
196                 int depthMin, int depthPref,
197                 int stencilMin, int stencilPref,
198                 int samplesMin, int samplesPref, float samplesQ,
199                 int dpi)
200{
201    RsSurfaceConfig sc;
202    sc.alphaMin = alphaMin;
203    sc.alphaPref = alphaPref;
204    sc.colorMin = colorMin;
205    sc.colorPref = colorPref;
206    sc.depthMin = depthMin;
207    sc.depthPref = depthPref;
208    sc.samplesMin = samplesMin;
209    sc.samplesPref = samplesPref;
210    sc.samplesQ = samplesQ;
211
212    LOG_API("nContextCreateGL");
213    return (jint)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
214}
215
216static void
217nContextSetPriority(JNIEnv *_env, jobject _this, RsContext con, jint p)
218{
219    LOG_API("ContextSetPriority, con(%p), priority(%i)", con, p);
220    rsContextSetPriority(con, p);
221}
222
223
224
225static void
226nContextSetSurface(JNIEnv *_env, jobject _this, RsContext con, jint width, jint height, jobject wnd)
227{
228    LOG_API("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", con, width, height, (Surface *)wnd);
229
230    ANativeWindow * window = NULL;
231    if (wnd == NULL) {
232
233    } else {
234        window = android_Surface_getNativeWindow(_env, wnd).get();
235    }
236
237    rsContextSetSurface(con, width, height, window);
238}
239
240static void
241nContextSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con, jint width, jint height, jobject sur)
242{
243    LOG_API("nContextSetSurfaceTexture, con(%p), width(%i), height(%i), surface(%p)", con, width, height, (Surface *)sur);
244
245    sp<ANativeWindow> window;
246    sp<SurfaceTexture> st;
247    if (sur == 0) {
248
249    } else {
250        st = SurfaceTexture_getSurfaceTexture(_env, sur);
251        window = new SurfaceTextureClient(st);
252    }
253
254    rsContextSetSurface(con, width, height, window.get());
255}
256
257static void
258nContextDestroy(JNIEnv *_env, jobject _this, RsContext con)
259{
260    LOG_API("nContextDestroy, con(%p)", con);
261    rsContextDestroy(con);
262}
263
264static void
265nContextDump(JNIEnv *_env, jobject _this, RsContext con, jint bits)
266{
267    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
268    rsContextDump((RsContext)con, bits);
269}
270
271static void
272nContextPause(JNIEnv *_env, jobject _this, RsContext con)
273{
274    LOG_API("nContextPause, con(%p)", con);
275    rsContextPause(con);
276}
277
278static void
279nContextResume(JNIEnv *_env, jobject _this, RsContext con)
280{
281    LOG_API("nContextResume, con(%p)", con);
282    rsContextResume(con);
283}
284
285
286static jstring
287nContextGetErrorMessage(JNIEnv *_env, jobject _this, RsContext con)
288{
289    LOG_API("nContextGetErrorMessage, con(%p)", con);
290    char buf[1024];
291
292    size_t receiveLen;
293    uint32_t subID;
294    int id = rsContextGetMessage(con,
295                                 buf, sizeof(buf),
296                                 &receiveLen, sizeof(receiveLen),
297                                 &subID, sizeof(subID));
298    if (!id && receiveLen) {
299        ALOGV("message receive buffer too small.  %i", receiveLen);
300    }
301    return _env->NewStringUTF(buf);
302}
303
304static jint
305nContextGetUserMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data)
306{
307    jint len = _env->GetArrayLength(data);
308    LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
309    jint *ptr = _env->GetIntArrayElements(data, NULL);
310    size_t receiveLen;
311    uint32_t subID;
312    int id = rsContextGetMessage(con,
313                                 ptr, len * 4,
314                                 &receiveLen, sizeof(receiveLen),
315                                 &subID, sizeof(subID));
316    if (!id && receiveLen) {
317        ALOGV("message receive buffer too small.  %i", receiveLen);
318    }
319    _env->ReleaseIntArrayElements(data, ptr, 0);
320    return id;
321}
322
323static jint
324nContextPeekMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray auxData)
325{
326    LOG_API("nContextPeekMessage, con(%p)", con);
327    jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
328    size_t receiveLen;
329    uint32_t subID;
330    int id = rsContextPeekMessage(con, &receiveLen, sizeof(receiveLen),
331                                  &subID, sizeof(subID));
332    auxDataPtr[0] = (jint)subID;
333    auxDataPtr[1] = (jint)receiveLen;
334    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
335    return id;
336}
337
338static void nContextInitToClient(JNIEnv *_env, jobject _this, RsContext con)
339{
340    LOG_API("nContextInitToClient, con(%p)", con);
341    rsContextInitToClient(con);
342}
343
344static void nContextDeinitToClient(JNIEnv *_env, jobject _this, RsContext con)
345{
346    LOG_API("nContextDeinitToClient, con(%p)", con);
347    rsContextDeinitToClient(con);
348}
349
350
351static jint
352nElementCreate(JNIEnv *_env, jobject _this, RsContext con, jint type, jint kind, jboolean norm, jint size)
353{
354    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size);
355    return (jint)rsElementCreate(con, (RsDataType)type, (RsDataKind)kind, norm, size);
356}
357
358static jint
359nElementCreate2(JNIEnv *_env, jobject _this, RsContext con,
360                jintArray _ids, jobjectArray _names, jintArray _arraySizes)
361{
362    int fieldCount = _env->GetArrayLength(_ids);
363    LOG_API("nElementCreate2, con(%p)", con);
364
365    jint *ids = _env->GetIntArrayElements(_ids, NULL);
366    jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
367
368    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
369
370    const char **nameArray = names.c_str();
371    size_t *sizeArray = names.c_str_len();
372
373    jint id = (jint)rsElementCreate2(con,
374                                     (RsElement *)ids, fieldCount,
375                                     nameArray, fieldCount * sizeof(size_t),  sizeArray,
376                                     (const uint32_t *)arraySizes, fieldCount);
377
378    _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT);
379    _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT);
380    return (jint)id;
381}
382
383static void
384nElementGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _elementData)
385{
386    int dataSize = _env->GetArrayLength(_elementData);
387    LOG_API("nElementGetNativeData, con(%p)", con);
388
389    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
390    assert(dataSize == 5);
391
392    uint32_t elementData[5];
393    rsaElementGetNativeData(con, (RsElement)id, elementData, dataSize);
394
395    for(jint i = 0; i < dataSize; i ++) {
396        _env->SetIntArrayRegion(_elementData, i, 1, (const jint*)&elementData[i]);
397    }
398}
399
400
401static void
402nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id,
403                       jintArray _IDs,
404                       jobjectArray _names,
405                       jintArray _arraySizes)
406{
407    int dataSize = _env->GetArrayLength(_IDs);
408    LOG_API("nElementGetSubElements, con(%p)", con);
409
410    uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
411    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
412    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
413
414    rsaElementGetSubElements(con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
415
416    for(jint i = 0; i < dataSize; i++) {
417        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
418        _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
419        _env->SetIntArrayRegion(_arraySizes, i, 1, (const jint*)&arraySizes[i]);
420    }
421
422    free(ids);
423    free(names);
424    free(arraySizes);
425}
426
427// -----------------------------------
428
429static int
430nTypeCreate(JNIEnv *_env, jobject _this, RsContext con, RsElement eid,
431            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces)
432{
433    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i)",
434            con, eid, dimx, dimy, dimz, mips, faces);
435
436    jint id = (jint)rsTypeCreate(con, (RsElement)eid, dimx, dimy, dimz, mips, faces);
437    return (jint)id;
438}
439
440static void
441nTypeGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _typeData)
442{
443    // We are packing 6 items: mDimX; mDimY; mDimZ;
444    // mDimLOD; mDimFaces; mElement; into typeData
445    int elementCount = _env->GetArrayLength(_typeData);
446
447    assert(elementCount == 6);
448    LOG_API("nTypeCreate, con(%p)", con);
449
450    uint32_t typeData[6];
451    rsaTypeGetNativeData(con, (RsType)id, typeData, 6);
452
453    for(jint i = 0; i < elementCount; i ++) {
454        _env->SetIntArrayRegion(_typeData, i, 1, (const jint*)&typeData[i]);
455    }
456}
457
458// -----------------------------------
459
460static jint
461nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage, jint pointer)
462{
463    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", con, (RsElement)type, mips, usage, (void *)pointer);
464    return (jint) rsAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uint32_t)pointer);
465}
466
467static void
468nAllocationSyncAll(JNIEnv *_env, jobject _this, RsContext con, jint a, jint bits)
469{
470    LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", con, (RsAllocation)a, bits);
471    rsAllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
472}
473
474static jint
475nAllocationGetSurfaceTextureID(JNIEnv *_env, jobject _this, RsContext con, jint a)
476{
477    LOG_API("nAllocationGetSurfaceTextureID, con(%p), a(%p)", con, (RsAllocation)a);
478    return rsAllocationGetSurfaceTextureID(con, (RsAllocation)a);
479}
480
481static void
482nAllocationSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con,
483                             RsAllocation alloc, jobject sur)
484{
485    LOG_API("nAllocationSetSurfaceTexture, con(%p), alloc(%p), surface(%p)",
486            con, alloc, (Surface *)sur);
487
488    sp<ANativeWindow> window;
489    if (sur != 0) {
490        sp<SurfaceTexture> st = SurfaceTexture_getSurfaceTexture(_env, sur);
491        window = new SurfaceTextureClient(st);
492    }
493
494    rsAllocationSetSurface(con, alloc, window.get());
495}
496
497static void
498nAllocationIoSend(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
499{
500    LOG_API("nAllocationIoSend, con(%p), alloc(%p)", con, alloc);
501    rsAllocationIoSend(con, alloc);
502}
503
504static void
505nAllocationIoReceive(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
506{
507    LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", con, alloc);
508    rsAllocationIoReceive(con, alloc);
509}
510
511
512static void
513nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
514{
515    LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", con, (RsAllocation)alloc);
516    rsAllocationGenerateMipmaps(con, (RsAllocation)alloc);
517}
518
519static int
520nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
521{
522    SkBitmap const * nativeBitmap =
523            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
524    const SkBitmap& bitmap(*nativeBitmap);
525
526    bitmap.lockPixels();
527    const void* ptr = bitmap.getPixels();
528    jint id = (jint)rsAllocationCreateFromBitmap(con,
529                                                  (RsType)type, (RsAllocationMipmapControl)mip,
530                                                  ptr, bitmap.getSize(), usage);
531    bitmap.unlockPixels();
532    return id;
533}
534
535static int
536nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
537{
538    SkBitmap const * nativeBitmap =
539            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
540    const SkBitmap& bitmap(*nativeBitmap);
541
542    bitmap.lockPixels();
543    const void* ptr = bitmap.getPixels();
544    jint id = (jint)rsAllocationCubeCreateFromBitmap(con,
545                                                      (RsType)type, (RsAllocationMipmapControl)mip,
546                                                      ptr, bitmap.getSize(), usage);
547    bitmap.unlockPixels();
548    return id;
549}
550
551static void
552nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
553{
554    SkBitmap const * nativeBitmap =
555            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
556    const SkBitmap& bitmap(*nativeBitmap);
557    int w = bitmap.width();
558    int h = bitmap.height();
559
560    bitmap.lockPixels();
561    const void* ptr = bitmap.getPixels();
562    rsAllocation2DData(con, (RsAllocation)alloc, 0, 0,
563                       0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
564                       w, h, ptr, bitmap.getSize());
565    bitmap.unlockPixels();
566}
567
568static void
569nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
570{
571    SkBitmap const * nativeBitmap =
572            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
573    const SkBitmap& bitmap(*nativeBitmap);
574
575    bitmap.lockPixels();
576    void* ptr = bitmap.getPixels();
577    rsAllocationCopyToBitmap(con, (RsAllocation)alloc, ptr, bitmap.getSize());
578    bitmap.unlockPixels();
579    bitmap.notifyPixelsChanged();
580}
581
582static void ReleaseBitmapCallback(void *bmp)
583{
584    SkBitmap const * nativeBitmap = (SkBitmap const *)bmp;
585    nativeBitmap->unlockPixels();
586}
587
588
589static void
590nAllocationData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jintArray data, int sizeBytes)
591{
592    jint len = _env->GetArrayLength(data);
593    LOG_API("nAllocation1DData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
594    jint *ptr = _env->GetIntArrayElements(data, NULL);
595    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
596    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
597}
598
599static void
600nAllocationData1D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jshortArray data, int sizeBytes)
601{
602    jint len = _env->GetArrayLength(data);
603    LOG_API("nAllocation1DData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
604    jshort *ptr = _env->GetShortArrayElements(data, NULL);
605    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
606    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
607}
608
609static void
610nAllocationData1D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jbyteArray data, int sizeBytes)
611{
612    jint len = _env->GetArrayLength(data);
613    LOG_API("nAllocation1DData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
614    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
615    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
616    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
617}
618
619static void
620nAllocationData1D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jfloatArray data, int sizeBytes)
621{
622    jint len = _env->GetArrayLength(data);
623    LOG_API("nAllocation1DData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
624    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
625    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
626    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
627}
628
629static void
630//    native void rsnAllocationElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
631nAllocationElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes)
632{
633    jint len = _env->GetArrayLength(data);
634    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
635    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
636    rsAllocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
637    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
638}
639
640static void
641nAllocationData2D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
642                    jint w, jint h, jshortArray data, int sizeBytes)
643{
644    jint len = _env->GetArrayLength(data);
645    LOG_API("nAllocation2DData_s, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
646    jshort *ptr = _env->GetShortArrayElements(data, NULL);
647    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
648    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
649}
650
651static void
652nAllocationData2D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
653                    jint w, jint h, jbyteArray data, int sizeBytes)
654{
655    jint len = _env->GetArrayLength(data);
656    LOG_API("nAllocation2DData_b, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
657    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
658    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
659    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
660}
661
662static void
663nAllocationData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
664                    jint w, jint h, jintArray data, int sizeBytes)
665{
666    jint len = _env->GetArrayLength(data);
667    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
668    jint *ptr = _env->GetIntArrayElements(data, NULL);
669    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
670    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
671}
672
673static void
674nAllocationData2D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
675                    jint w, jint h, jfloatArray data, int sizeBytes)
676{
677    jint len = _env->GetArrayLength(data);
678    LOG_API("nAllocation2DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len);
679    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
680    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
681    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
682}
683
684static void
685nAllocationData2D_alloc(JNIEnv *_env, jobject _this, RsContext con,
686                        jint dstAlloc, jint dstXoff, jint dstYoff,
687                        jint dstMip, jint dstFace,
688                        jint width, jint height,
689                        jint srcAlloc, jint srcXoff, jint srcYoff,
690                        jint srcMip, jint srcFace)
691{
692    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
693            " dstMip(%i), dstFace(%i), width(%i), height(%i),"
694            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
695            con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
696            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
697
698    rsAllocationCopy2DRange(con,
699                            (RsAllocation)dstAlloc,
700                            dstXoff, dstYoff,
701                            dstMip, dstFace,
702                            width, height,
703                            (RsAllocation)srcAlloc,
704                            srcXoff, srcYoff,
705                            srcMip, srcFace);
706}
707
708static void
709nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
710{
711    jint len = _env->GetArrayLength(data);
712    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
713    jint *ptr = _env->GetIntArrayElements(data, NULL);
714    jsize length = _env->GetArrayLength(data);
715    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
716    _env->ReleaseIntArrayElements(data, ptr, 0);
717}
718
719static void
720nAllocationRead_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jshortArray data)
721{
722    jint len = _env->GetArrayLength(data);
723    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
724    jshort *ptr = _env->GetShortArrayElements(data, NULL);
725    jsize length = _env->GetArrayLength(data);
726    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
727    _env->ReleaseShortArrayElements(data, ptr, 0);
728}
729
730static void
731nAllocationRead_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jbyteArray data)
732{
733    jint len = _env->GetArrayLength(data);
734    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
735    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
736    jsize length = _env->GetArrayLength(data);
737    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
738    _env->ReleaseByteArrayElements(data, ptr, 0);
739}
740
741static void
742nAllocationRead_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jfloatArray data)
743{
744    jint len = _env->GetArrayLength(data);
745    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
746    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
747    jsize length = _env->GetArrayLength(data);
748    rsAllocationRead(con, (RsAllocation)alloc, ptr, length);
749    _env->ReleaseFloatArrayElements(data, ptr, 0);
750}
751
752static jint
753nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
754{
755    LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a);
756    return (jint) rsaAllocationGetType(con, (RsAllocation)a);
757}
758
759static void
760nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
761{
762    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
763    rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
764}
765
766static void
767nAllocationResize2D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX, jint dimY)
768{
769    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i), sizeY(%i)", con, (RsAllocation)alloc, dimX, dimY);
770    rsAllocationResize2D(con, (RsAllocation)alloc, dimX, dimY);
771}
772
773// -----------------------------------
774
775static int
776nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con, jint native_asset)
777{
778    ALOGV("______nFileA3D %u", (uint32_t) native_asset);
779
780    Asset* asset = reinterpret_cast<Asset*>(native_asset);
781
782    jint id = (jint)rsaFileA3DCreateFromMemory(con, asset->getBuffer(false), asset->getLength());
783    return id;
784}
785
786static int
787nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path)
788{
789    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
790    if (mgr == NULL) {
791        return 0;
792    }
793
794    AutoJavaStringToUTF8 str(_env, _path);
795    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
796    if (asset == NULL) {
797        return 0;
798    }
799
800    jint id = (jint)rsaFileA3DCreateFromAsset(con, asset);
801    return id;
802}
803
804static int
805nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, RsContext con, jstring fileName)
806{
807    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
808    jint id = (jint)rsaFileA3DCreateFromFile(con, fileNameUTF.c_str());
809
810    return id;
811}
812
813static int
814nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D)
815{
816    int32_t numEntries = 0;
817    rsaFileA3DGetNumIndexEntries(con, &numEntries, (RsFile)fileA3D);
818    return numEntries;
819}
820
821static void
822nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
823{
824    ALOGV("______nFileA3D %u", (uint32_t) fileA3D);
825    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
826
827    rsaFileA3DGetIndexEntries(con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
828
829    for(jint i = 0; i < numEntries; i ++) {
830        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
831        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
832    }
833
834    free(fileEntries);
835}
836
837static int
838nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, RsContext con, jint fileA3D, jint index)
839{
840    ALOGV("______nFileA3D %u", (uint32_t) fileA3D);
841    jint id = (jint)rsaFileA3DGetEntryByIndex(con, (uint32_t)index, (RsFile)fileA3D);
842    return id;
843}
844
845// -----------------------------------
846
847static int
848nFontCreateFromFile(JNIEnv *_env, jobject _this, RsContext con,
849                    jstring fileName, jfloat fontSize, jint dpi)
850{
851    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
852    jint id = (jint)rsFontCreateFromFile(con,
853                                         fileNameUTF.c_str(), fileNameUTF.length(),
854                                         fontSize, dpi);
855
856    return id;
857}
858
859static int
860nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, RsContext con,
861                           jstring name, jfloat fontSize, jint dpi, jint native_asset)
862{
863    Asset* asset = reinterpret_cast<Asset*>(native_asset);
864    AutoJavaStringToUTF8 nameUTF(_env, name);
865
866    jint id = (jint)rsFontCreateFromMemory(con,
867                                           nameUTF.c_str(), nameUTF.length(),
868                                           fontSize, dpi,
869                                           asset->getBuffer(false), asset->getLength());
870    return id;
871}
872
873static int
874nFontCreateFromAsset(JNIEnv *_env, jobject _this, RsContext con, jobject _assetMgr, jstring _path,
875                     jfloat fontSize, jint dpi)
876{
877    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
878    if (mgr == NULL) {
879        return 0;
880    }
881
882    AutoJavaStringToUTF8 str(_env, _path);
883    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
884    if (asset == NULL) {
885        return 0;
886    }
887
888    jint id = (jint)rsFontCreateFromMemory(con,
889                                           str.c_str(), str.length(),
890                                           fontSize, dpi,
891                                           asset->getBuffer(false), asset->getLength());
892    delete asset;
893    return id;
894}
895
896// -----------------------------------
897
898static void
899nScriptBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint script, jint alloc, jint slot)
900{
901    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
902    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
903}
904
905static void
906nScriptSetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
907{
908    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
909    rsScriptSetVarI(con, (RsScript)script, slot, val);
910}
911
912static void
913nScriptSetVarObj(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
914{
915    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
916    rsScriptSetVarObj(con, (RsScript)script, slot, (RsObjectBase)val);
917}
918
919static void
920nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
921{
922    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
923    rsScriptSetVarJ(con, (RsScript)script, slot, val);
924}
925
926static void
927nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
928{
929    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
930    rsScriptSetVarF(con, (RsScript)script, slot, val);
931}
932
933static void
934nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
935{
936    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
937    rsScriptSetVarD(con, (RsScript)script, slot, val);
938}
939
940static void
941nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
942{
943    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
944    jint len = _env->GetArrayLength(data);
945    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
946    rsScriptSetVarV(con, (RsScript)script, slot, ptr, len);
947    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
948}
949
950
951static void
952nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
953{
954    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
955
956    jint length = _env->GetArrayLength(timeZone);
957    jbyte* timeZone_ptr;
958    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
959
960    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
961
962    if (timeZone_ptr) {
963        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
964    }
965}
966
967static void
968nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
969{
970    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
971    rsScriptInvoke(con, (RsScript)obj, slot);
972}
973
974static void
975nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
976{
977    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
978    jint len = _env->GetArrayLength(data);
979    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
980    rsScriptInvokeV(con, (RsScript)script, slot, ptr, len);
981    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
982}
983
984static void
985nScriptForEach(JNIEnv *_env, jobject _this, RsContext con,
986               jint script, jint slot, jint ain, jint aout)
987{
988    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
989    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0);
990}
991static void
992nScriptForEachV(JNIEnv *_env, jobject _this, RsContext con,
993                jint script, jint slot, jint ain, jint aout, jbyteArray params)
994{
995    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
996    jint len = _env->GetArrayLength(params);
997    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
998    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len);
999    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1000}
1001
1002
1003// -----------------------------------
1004
1005static jint
1006nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con,
1007               jstring resName, jstring cacheDir,
1008               jbyteArray scriptRef, jint length)
1009{
1010    LOG_API("nScriptCCreate, con(%p)", con);
1011
1012    AutoJavaStringToUTF8 resNameUTF(_env, resName);
1013    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1014    jint ret = 0;
1015    jbyte* script_ptr = NULL;
1016    jint _exception = 0;
1017    jint remaining;
1018    if (!scriptRef) {
1019        _exception = 1;
1020        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1021        goto exit;
1022    }
1023    if (length < 0) {
1024        _exception = 1;
1025        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1026        goto exit;
1027    }
1028    remaining = _env->GetArrayLength(scriptRef);
1029    if (remaining < length) {
1030        _exception = 1;
1031        //jniThrowException(_env, "java/lang/IllegalArgumentException",
1032        //        "length > script.length - offset");
1033        goto exit;
1034    }
1035    script_ptr = (jbyte *)
1036        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1037
1038    //rsScriptCSetText(con, (const char *)script_ptr, length);
1039
1040    ret = (jint)rsScriptCCreate(con,
1041                                resNameUTF.c_str(), resNameUTF.length(),
1042                                cacheDirUTF.c_str(), cacheDirUTF.length(),
1043                                (const char *)script_ptr, length);
1044
1045exit:
1046    if (script_ptr) {
1047        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1048                _exception ? JNI_ABORT: 0);
1049    }
1050
1051    return ret;
1052}
1053
1054// ---------------------------------------------------------------------------
1055
1056static jint
1057nProgramStoreCreate(JNIEnv *_env, jobject _this, RsContext con,
1058                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
1059                    jboolean depthMask, jboolean ditherEnable,
1060                    jint srcFunc, jint destFunc,
1061                    jint depthFunc)
1062{
1063    LOG_API("nProgramStoreCreate, con(%p)", con);
1064    return (jint)rsProgramStoreCreate(con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
1065                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
1066                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
1067}
1068
1069// ---------------------------------------------------------------------------
1070
1071static void
1072nProgramBindConstants(JNIEnv *_env, jobject _this, RsContext con, jint vpv, jint slot, jint a)
1073{
1074    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
1075    rsProgramBindConstants(con, (RsProgram)vpv, slot, (RsAllocation)a);
1076}
1077
1078static void
1079nProgramBindTexture(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1080{
1081    LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1082    rsProgramBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1083}
1084
1085static void
1086nProgramBindSampler(JNIEnv *_env, jobject _this, RsContext con, jint vpf, jint slot, jint a)
1087{
1088    LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1089    rsProgramBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1090}
1091
1092// ---------------------------------------------------------------------------
1093
1094static jint
1095nProgramFragmentCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader,
1096                       jobjectArray texNames, jintArray params)
1097{
1098    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1099    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1100    jint paramLen = _env->GetArrayLength(params);
1101
1102    int texCount = _env->GetArrayLength(texNames);
1103    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
1104    const char ** nameArray = names.c_str();
1105    size_t* sizeArray = names.c_str_len();
1106
1107    LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, paramLen);
1108
1109    jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF.c_str(), shaderUTF.length(),
1110                                             nameArray, texCount, sizeArray,
1111                                             (uint32_t *)paramPtr, paramLen);
1112
1113    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1114    return ret;
1115}
1116
1117
1118// ---------------------------------------------------------------------------
1119
1120static jint
1121nProgramVertexCreate(JNIEnv *_env, jobject _this, RsContext con, jstring shader,
1122                     jobjectArray texNames, jintArray params)
1123{
1124    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1125    jint *paramPtr = _env->GetIntArrayElements(params, NULL);
1126    jint paramLen = _env->GetArrayLength(params);
1127
1128    LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", con, paramLen);
1129
1130    int texCount = _env->GetArrayLength(texNames);
1131    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
1132    const char ** nameArray = names.c_str();
1133    size_t* sizeArray = names.c_str_len();
1134
1135    jint ret = (jint)rsProgramVertexCreate(con, shaderUTF.c_str(), shaderUTF.length(),
1136                                           nameArray, texCount, sizeArray,
1137                                           (uint32_t *)paramPtr, paramLen);
1138
1139    _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
1140    return ret;
1141}
1142
1143// ---------------------------------------------------------------------------
1144
1145static jint
1146nProgramRasterCreate(JNIEnv *_env, jobject _this, RsContext con, jboolean pointSprite, jint cull)
1147{
1148    LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", con, pointSprite, cull);
1149    return (jint)rsProgramRasterCreate(con, pointSprite, (RsCullMode)cull);
1150}
1151
1152
1153// ---------------------------------------------------------------------------
1154
1155static void
1156nContextBindRootScript(JNIEnv *_env, jobject _this, RsContext con, jint script)
1157{
1158    LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script);
1159    rsContextBindRootScript(con, (RsScript)script);
1160}
1161
1162static void
1163nContextBindProgramStore(JNIEnv *_env, jobject _this, RsContext con, jint pfs)
1164{
1165    LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs);
1166    rsContextBindProgramStore(con, (RsProgramStore)pfs);
1167}
1168
1169static void
1170nContextBindProgramFragment(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1171{
1172    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf);
1173    rsContextBindProgramFragment(con, (RsProgramFragment)pf);
1174}
1175
1176static void
1177nContextBindProgramVertex(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1178{
1179    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
1180    rsContextBindProgramVertex(con, (RsProgramVertex)pf);
1181}
1182
1183static void
1184nContextBindProgramRaster(JNIEnv *_env, jobject _this, RsContext con, jint pf)
1185{
1186    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
1187    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
1188}
1189
1190
1191// ---------------------------------------------------------------------------
1192
1193static jint
1194nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con, jint magFilter, jint minFilter,
1195               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1196{
1197    LOG_API("nSamplerCreate, con(%p)", con);
1198    return (jint)rsSamplerCreate(con,
1199                                 (RsSamplerValue)magFilter,
1200                                 (RsSamplerValue)minFilter,
1201                                 (RsSamplerValue)wrapS,
1202                                 (RsSamplerValue)wrapT,
1203                                 (RsSamplerValue)wrapR,
1204                                 aniso);
1205}
1206
1207// ---------------------------------------------------------------------------
1208
1209//native int  rsnPathCreate(int con, int prim, boolean isStatic, int vtx, int loop, float q);
1210static jint
1211nPathCreate(JNIEnv *_env, jobject _this, RsContext con, jint prim, jboolean isStatic, jint _vtx, jint _loop, jfloat q) {
1212    LOG_API("nPathCreate, con(%p)", con);
1213
1214    int id = (int)rsPathCreate(con, (RsPathPrimitive)prim, isStatic,
1215                               (RsAllocation)_vtx,
1216                               (RsAllocation)_loop, q);
1217    return id;
1218}
1219
1220static jint
1221nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jintArray _vtx, jintArray _idx, jintArray _prim)
1222{
1223    LOG_API("nMeshCreate, con(%p)", con);
1224
1225    jint vtxLen = _env->GetArrayLength(_vtx);
1226    jint *vtxPtr = _env->GetIntArrayElements(_vtx, NULL);
1227    jint idxLen = _env->GetArrayLength(_idx);
1228    jint *idxPtr = _env->GetIntArrayElements(_idx, NULL);
1229    jint primLen = _env->GetArrayLength(_prim);
1230    jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
1231
1232    int id = (int)rsMeshCreate(con,
1233                               (RsAllocation *)vtxPtr, vtxLen,
1234                               (RsAllocation *)idxPtr, idxLen,
1235                               (uint32_t *)primPtr, primLen);
1236
1237    _env->ReleaseIntArrayElements(_vtx, vtxPtr, 0);
1238    _env->ReleaseIntArrayElements(_idx, idxPtr, 0);
1239    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
1240    return id;
1241}
1242
1243static jint
1244nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1245{
1246    LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1247    jint vtxCount = 0;
1248    rsaMeshGetVertexBufferCount(con, (RsMesh)mesh, &vtxCount);
1249    return vtxCount;
1250}
1251
1252static jint
1253nMeshGetIndexCount(JNIEnv *_env, jobject _this, RsContext con, jint mesh)
1254{
1255    LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1256    jint idxCount = 0;
1257    rsaMeshGetIndexCount(con, (RsMesh)mesh, &idxCount);
1258    return idxCount;
1259}
1260
1261static void
1262nMeshGetVertices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _ids, int numVtxIDs)
1263{
1264    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1265
1266    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
1267    rsaMeshGetVertices(con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
1268
1269    for(jint i = 0; i < numVtxIDs; i ++) {
1270        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]);
1271    }
1272
1273    free(allocs);
1274}
1275
1276static void
1277nMeshGetIndices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray _idxIds, jintArray _primitives, int numIndices)
1278{
1279    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh);
1280
1281    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
1282    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
1283
1284    rsaMeshGetIndices(con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
1285
1286    for(jint i = 0; i < numIndices; i ++) {
1287        _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]);
1288        _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]);
1289    }
1290
1291    free(allocs);
1292    free(prims);
1293}
1294
1295// ---------------------------------------------------------------------------
1296
1297
1298static const char *classPathName = "android/renderscript/RenderScript";
1299
1300static JNINativeMethod methods[] = {
1301{"_nInit",                         "()V",                                     (void*)_nInit },
1302
1303{"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
1304{"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
1305{"nDeviceSetConfig",               "(III)V",                                  (void*)nDeviceSetConfig },
1306{"nContextGetUserMessage",         "(I[I)I",                                  (void*)nContextGetUserMessage },
1307{"nContextGetErrorMessage",        "(I)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1308{"nContextPeekMessage",            "(I[I)I",                                  (void*)nContextPeekMessage },
1309
1310{"nContextInitToClient",           "(I)V",                                    (void*)nContextInitToClient },
1311{"nContextDeinitToClient",         "(I)V",                                    (void*)nContextDeinitToClient },
1312
1313
1314// All methods below are thread protected in java.
1315{"rsnContextCreate",                 "(III)I",                                (void*)nContextCreate },
1316{"rsnContextCreateGL",               "(IIIIIIIIIIIIIFI)I",                    (void*)nContextCreateGL },
1317{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
1318{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
1319{"rsnContextSetSurface",             "(IIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
1320{"rsnContextSetSurfaceTexture",      "(IIILandroid/graphics/SurfaceTexture;)V", (void*)nContextSetSurfaceTexture },
1321{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
1322{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
1323{"rsnContextPause",                  "(I)V",                                  (void*)nContextPause },
1324{"rsnContextResume",                 "(I)V",                                  (void*)nContextResume },
1325{"rsnAssignName",                    "(II[B)V",                               (void*)nAssignName },
1326{"rsnGetName",                       "(II)Ljava/lang/String;",                (void*)nGetName },
1327{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
1328
1329{"rsnFileA3DCreateFromFile",         "(ILjava/lang/String;)I",                (void*)nFileA3DCreateFromFile },
1330{"rsnFileA3DCreateFromAssetStream",  "(II)I",                                 (void*)nFileA3DCreateFromAssetStream },
1331{"rsnFileA3DCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;)I",            (void*)nFileA3DCreateFromAsset },
1332{"rsnFileA3DGetNumIndexEntries",     "(II)I",                                 (void*)nFileA3DGetNumIndexEntries },
1333{"rsnFileA3DGetIndexEntries",        "(III[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
1334{"rsnFileA3DGetEntryByIndex",        "(III)I",                                (void*)nFileA3DGetEntryByIndex },
1335
1336{"rsnFontCreateFromFile",            "(ILjava/lang/String;FI)I",              (void*)nFontCreateFromFile },
1337{"rsnFontCreateFromAssetStream",     "(ILjava/lang/String;FII)I",             (void*)nFontCreateFromAssetStream },
1338{"rsnFontCreateFromAsset",        "(ILandroid/content/res/AssetManager;Ljava/lang/String;FI)I",            (void*)nFontCreateFromAsset },
1339
1340{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
1341{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
1342{"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
1343{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
1344
1345{"rsnTypeCreate",                    "(IIIIIZZ)I",                            (void*)nTypeCreate },
1346{"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
1347
1348{"rsnAllocationCreateTyped",         "(IIIII)I",                               (void*)nAllocationCreateTyped },
1349{"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
1350{"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
1351
1352{"rsnAllocationCopyFromBitmap",      "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1353{"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1354
1355{"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
1356{"rsnAllocationGetSurfaceTextureID", "(II)I",                                 (void*)nAllocationGetSurfaceTextureID },
1357{"rsnAllocationSetSurfaceTexture",   "(IILandroid/graphics/SurfaceTexture;)V", (void*)nAllocationSetSurfaceTexture },
1358{"rsnAllocationIoSend",              "(II)V",                                 (void*)nAllocationIoSend },
1359{"rsnAllocationIoReceive",           "(II)V",                                 (void*)nAllocationIoReceive },
1360{"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
1361{"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
1362{"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
1363{"rsnAllocationData1D",              "(IIIII[FI)V",                           (void*)nAllocationData1D_f },
1364{"rsnAllocationElementData1D",       "(IIIII[BI)V",                           (void*)nAllocationElementData1D },
1365{"rsnAllocationData2D",              "(IIIIIIII[II)V",                        (void*)nAllocationData2D_i },
1366{"rsnAllocationData2D",              "(IIIIIIII[SI)V",                        (void*)nAllocationData2D_s },
1367{"rsnAllocationData2D",              "(IIIIIIII[BI)V",                        (void*)nAllocationData2D_b },
1368{"rsnAllocationData2D",              "(IIIIIIII[FI)V",                        (void*)nAllocationData2D_f },
1369{"rsnAllocationData2D",              "(IIIIIIIIIIIII)V",                      (void*)nAllocationData2D_alloc },
1370{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
1371{"rsnAllocationRead",                "(II[S)V",                               (void*)nAllocationRead_s },
1372{"rsnAllocationRead",                "(II[B)V",                               (void*)nAllocationRead_b },
1373{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
1374{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
1375{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
1376{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
1377{"rsnAllocationGenerateMipmaps",     "(II)V",                                 (void*)nAllocationGenerateMipmaps },
1378
1379{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
1380{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
1381{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
1382{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
1383{"rsnScriptForEach",                 "(IIIII)V",                              (void*)nScriptForEach },
1384{"rsnScriptForEach",                 "(IIIII[B)V",                            (void*)nScriptForEachV },
1385{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
1386{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
1387{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
1388{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
1389{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
1390{"rsnScriptSetVarObj",               "(IIII)V",                               (void*)nScriptSetVarObj },
1391
1392{"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;[BI)I",  (void*)nScriptCCreate },
1393
1394{"rsnProgramStoreCreate",            "(IZZZZZZIII)I",                         (void*)nProgramStoreCreate },
1395
1396{"rsnProgramBindConstants",          "(IIII)V",                               (void*)nProgramBindConstants },
1397{"rsnProgramBindTexture",            "(IIII)V",                               (void*)nProgramBindTexture },
1398{"rsnProgramBindSampler",            "(IIII)V",                               (void*)nProgramBindSampler },
1399
1400{"rsnProgramFragmentCreate",         "(ILjava/lang/String;[Ljava/lang/String;[I)I",              (void*)nProgramFragmentCreate },
1401{"rsnProgramRasterCreate",           "(IZI)I",                                (void*)nProgramRasterCreate },
1402{"rsnProgramVertexCreate",           "(ILjava/lang/String;[Ljava/lang/String;[I)I",              (void*)nProgramVertexCreate },
1403
1404{"rsnContextBindRootScript",         "(II)V",                                 (void*)nContextBindRootScript },
1405{"rsnContextBindProgramStore",       "(II)V",                                 (void*)nContextBindProgramStore },
1406{"rsnContextBindProgramFragment",    "(II)V",                                 (void*)nContextBindProgramFragment },
1407{"rsnContextBindProgramVertex",      "(II)V",                                 (void*)nContextBindProgramVertex },
1408{"rsnContextBindProgramRaster",      "(II)V",                                 (void*)nContextBindProgramRaster },
1409
1410{"rsnSamplerCreate",                 "(IIIIIIF)I",                            (void*)nSamplerCreate },
1411
1412{"rsnPathCreate",                    "(IIZIIF)I",                             (void*)nPathCreate },
1413{"rsnMeshCreate",                    "(I[I[I[I)I",                            (void*)nMeshCreate },
1414
1415{"rsnMeshGetVertexBufferCount",      "(II)I",                                 (void*)nMeshGetVertexBufferCount },
1416{"rsnMeshGetIndexCount",             "(II)I",                                 (void*)nMeshGetIndexCount },
1417{"rsnMeshGetVertices",               "(II[II)V",                              (void*)nMeshGetVertices },
1418{"rsnMeshGetIndices",                "(II[I[II)V",                            (void*)nMeshGetIndices },
1419
1420};
1421
1422static int registerFuncs(JNIEnv *_env)
1423{
1424    return android::AndroidRuntime::registerNativeMethods(
1425            _env, classPathName, methods, NELEM(methods));
1426}
1427
1428// ---------------------------------------------------------------------------
1429
1430jint JNI_OnLoad(JavaVM* vm, void* reserved)
1431{
1432    JNIEnv* env = NULL;
1433    jint result = -1;
1434
1435    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1436        ALOGE("ERROR: GetEnv failed\n");
1437        goto bail;
1438    }
1439    assert(env != NULL);
1440
1441    if (registerFuncs(env) < 0) {
1442        ALOGE("ERROR: MediaPlayer native registration failed\n");
1443        goto bail;
1444    }
1445
1446    /* success -- return valid version number */
1447    result = JNI_VERSION_1_4;
1448
1449bail:
1450    return result;
1451}
1452