android_renderscript_RenderScript.cpp revision 949610653fdf55dd2cb3c846047e6aa2c6d73f0d
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 <core/SkBitmap.h>
27#include <core/SkPixelRef.h>
28#include <core/SkStream.h>
29#include <core/SkTemplates.h>
30
31#include <androidfw/Asset.h>
32#include <androidfw/AssetManager.h>
33#include <androidfw/ResourceTypes.h>
34
35#include "jni.h"
36#include "JNIHelp.h"
37#include "android_runtime/AndroidRuntime.h"
38#include "android_runtime/android_view_Surface.h"
39#include "android_runtime/android_util_AssetManager.h"
40
41#include <rs.h>
42#include <rsEnv.h>
43#include <gui/Surface.h>
44#include <gui/GLConsumer.h>
45#include <gui/Surface.h>
46#include <android_runtime/android_graphics_SurfaceTexture.h>
47
48//#define LOG_API ALOGE
49#define LOG_API(...)
50
51using namespace android;
52
53#define PER_ARRAY_TYPE(flag, fnc, readonly, ...) {                                      \
54    jint len = 0;                                                                       \
55    void *ptr = NULL;                                                                   \
56    size_t typeBytes = 0;                                                               \
57    jint relFlag = 0;                                                                   \
58    if (readonly) {                                                                     \
59        /* The on-release mode should only be JNI_ABORT for read-only accesses. */      \
60        relFlag = JNI_ABORT;                                                            \
61    }                                                                                   \
62    switch(dataType) {                                                                  \
63    case RS_TYPE_FLOAT_32:                                                              \
64        len = _env->GetArrayLength((jfloatArray)data);                                  \
65        ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
66        typeBytes = 4;                                                                  \
67        fnc(__VA_ARGS__);                                                               \
68        _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag);     \
69        return;                                                                         \
70    case RS_TYPE_FLOAT_64:                                                              \
71        len = _env->GetArrayLength((jdoubleArray)data);                                 \
72        ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
73        typeBytes = 8;                                                                  \
74        fnc(__VA_ARGS__);                                                               \
75        _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag);  \
76        return;                                                                         \
77    case RS_TYPE_SIGNED_8:                                                              \
78    case RS_TYPE_UNSIGNED_8:                                                            \
79        len = _env->GetArrayLength((jbyteArray)data);                                   \
80        ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
81        typeBytes = 1;                                                                  \
82        fnc(__VA_ARGS__);                                                               \
83        _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag);         \
84        return;                                                                         \
85    case RS_TYPE_SIGNED_16:                                                             \
86    case RS_TYPE_UNSIGNED_16:                                                           \
87        len = _env->GetArrayLength((jshortArray)data);                                  \
88        ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
89        typeBytes = 2;                                                                  \
90        fnc(__VA_ARGS__);                                                               \
91        _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag);     \
92        return;                                                                         \
93    case RS_TYPE_SIGNED_32:                                                             \
94    case RS_TYPE_UNSIGNED_32:                                                           \
95        len = _env->GetArrayLength((jintArray)data);                                    \
96        ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
97        typeBytes = 4;                                                                  \
98        fnc(__VA_ARGS__);                                                               \
99        _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag);           \
100        return;                                                                         \
101    case RS_TYPE_SIGNED_64:                                                             \
102    case RS_TYPE_UNSIGNED_64:                                                           \
103        len = _env->GetArrayLength((jlongArray)data);                                   \
104        ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
105        typeBytes = 8;                                                                  \
106        fnc(__VA_ARGS__);                                                               \
107        _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag);        \
108        return;                                                                         \
109    default:                                                                            \
110        break;                                                                          \
111    }                                                                                   \
112}
113
114
115class AutoJavaStringToUTF8 {
116public:
117    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
118        fCStr = env->GetStringUTFChars(str, NULL);
119        fLength = env->GetStringUTFLength(str);
120    }
121    ~AutoJavaStringToUTF8() {
122        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
123    }
124    const char* c_str() const { return fCStr; }
125    jsize length() const { return fLength; }
126
127private:
128    JNIEnv*     fEnv;
129    jstring     fJStr;
130    const char* fCStr;
131    jsize       fLength;
132};
133
134class AutoJavaStringArrayToUTF8 {
135public:
136    AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
137    : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
138        mCStrings = NULL;
139        mSizeArray = NULL;
140        if (stringsLength > 0) {
141            mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
142            mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
143            for (jsize ct = 0; ct < stringsLength; ct ++) {
144                jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
145                mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
146                mSizeArray[ct] = mEnv->GetStringUTFLength(s);
147            }
148        }
149    }
150    ~AutoJavaStringArrayToUTF8() {
151        for (jsize ct=0; ct < mStringsLength; ct++) {
152            jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
153            mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
154        }
155        free(mCStrings);
156        free(mSizeArray);
157    }
158    const char **c_str() const { return mCStrings; }
159    size_t *c_str_len() const { return mSizeArray; }
160    jsize length() const { return mStringsLength; }
161
162private:
163    JNIEnv      *mEnv;
164    jobjectArray mStrings;
165    const char **mCStrings;
166    size_t      *mSizeArray;
167    jsize        mStringsLength;
168};
169
170// ---------------------------------------------------------------------------
171
172static jfieldID gContextId = 0;
173static jfieldID gNativeBitmapID = 0;
174static jfieldID gTypeNativeCache = 0;
175
176static void _nInit(JNIEnv *_env, jclass _this)
177{
178    gContextId             = _env->GetFieldID(_this, "mContext", "J");
179
180    jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
181    gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "J");
182}
183
184// ---------------------------------------------------------------------------
185
186static void
187nContextFinish(JNIEnv *_env, jobject _this, jlong con)
188{
189    LOG_API("nContextFinish, con(%p)", (RsContext)con);
190    rsContextFinish((RsContext)con);
191}
192
193static void
194nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str)
195{
196    LOG_API("nAssignName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
197    jint len = _env->GetArrayLength(str);
198    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
199    rsAssignName((RsContext)con, (void *)obj, (const char *)cptr, len);
200    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
201}
202
203static jstring
204nGetName(JNIEnv *_env, jobject _this, jlong con, jlong obj)
205{
206    LOG_API("nGetName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
207    const char *name = NULL;
208    rsaGetName((RsContext)con, (void *)obj, &name);
209    if(name == NULL || strlen(name) == 0) {
210        return NULL;
211    }
212    return _env->NewStringUTF(name);
213}
214
215static void
216nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
217{
218    LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
219    rsObjDestroy((RsContext)con, (void *)obj);
220}
221
222// ---------------------------------------------------------------------------
223
224static jlong
225nDeviceCreate(JNIEnv *_env, jobject _this)
226{
227    LOG_API("nDeviceCreate");
228    return (jlong)rsDeviceCreate();
229}
230
231static void
232nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
233{
234    LOG_API("nDeviceDestroy");
235    return rsDeviceDestroy((RsDevice)dev);
236}
237
238static void
239nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
240{
241    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
242    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
243}
244
245static jlong
246nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct)
247{
248    LOG_API("nContextCreate");
249    return (jlong)rsContextCreate((RsDevice)dev, ver, sdkVer, (RsContextType)ct, 0);
250}
251
252static jlong
253nContextCreateGL(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
254                 jint colorMin, jint colorPref,
255                 jint alphaMin, jint alphaPref,
256                 jint depthMin, jint depthPref,
257                 jint stencilMin, jint stencilPref,
258                 jint samplesMin, jint samplesPref, jfloat samplesQ,
259                 jint dpi)
260{
261    RsSurfaceConfig sc;
262    sc.alphaMin = alphaMin;
263    sc.alphaPref = alphaPref;
264    sc.colorMin = colorMin;
265    sc.colorPref = colorPref;
266    sc.depthMin = depthMin;
267    sc.depthPref = depthPref;
268    sc.samplesMin = samplesMin;
269    sc.samplesPref = samplesPref;
270    sc.samplesQ = samplesQ;
271
272    LOG_API("nContextCreateGL");
273    return (jlong)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
274}
275
276static void
277nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
278{
279    LOG_API("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
280    rsContextSetPriority((RsContext)con, p);
281}
282
283
284
285static void
286nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd)
287{
288    LOG_API("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", (RsContext)con, width, height, (Surface *)wnd);
289
290    ANativeWindow * window = NULL;
291    if (wnd == NULL) {
292
293    } else {
294        window = android_view_Surface_getNativeWindow(_env, wnd).get();
295    }
296
297    rsContextSetSurface((RsContext)con, width, height, window);
298}
299
300static void
301nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
302{
303    LOG_API("nContextDestroy, con(%p)", (RsContext)con);
304    rsContextDestroy((RsContext)con);
305}
306
307static void
308nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
309{
310    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
311    rsContextDump((RsContext)con, bits);
312}
313
314static void
315nContextPause(JNIEnv *_env, jobject _this, jlong con)
316{
317    LOG_API("nContextPause, con(%p)", (RsContext)con);
318    rsContextPause((RsContext)con);
319}
320
321static void
322nContextResume(JNIEnv *_env, jobject _this, jlong con)
323{
324    LOG_API("nContextResume, con(%p)", (RsContext)con);
325    rsContextResume((RsContext)con);
326}
327
328
329static jstring
330nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
331{
332    LOG_API("nContextGetErrorMessage, con(%p)", (RsContext)con);
333    char buf[1024];
334
335    size_t receiveLen;
336    uint32_t subID;
337    int id = rsContextGetMessage((RsContext)con,
338                                 buf, sizeof(buf),
339                                 &receiveLen, sizeof(receiveLen),
340                                 &subID, sizeof(subID));
341    if (!id && receiveLen) {
342        ALOGV("message receive buffer too small.  %i", receiveLen);
343    }
344    return _env->NewStringUTF(buf);
345}
346
347static jint
348nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
349{
350    jint len = _env->GetArrayLength(data);
351    LOG_API("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
352    jint *ptr = _env->GetIntArrayElements(data, NULL);
353    size_t receiveLen;
354    uint32_t subID;
355    int id = rsContextGetMessage((RsContext)con,
356                                 ptr, len * 4,
357                                 &receiveLen, sizeof(receiveLen),
358                                 &subID, sizeof(subID));
359    if (!id && receiveLen) {
360        ALOGV("message receive buffer too small.  %i", receiveLen);
361    }
362    _env->ReleaseIntArrayElements(data, ptr, 0);
363    return (jint)id;
364}
365
366static jint
367nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
368{
369    LOG_API("nContextPeekMessage, con(%p)", (RsContext)con);
370    jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
371    size_t receiveLen;
372    uint32_t subID;
373    int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
374                                  &subID, sizeof(subID));
375    auxDataPtr[0] = (jint)subID;
376    auxDataPtr[1] = (jint)receiveLen;
377    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
378    return (jint)id;
379}
380
381static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
382{
383    LOG_API("nContextInitToClient, con(%p)", (RsContext)con);
384    rsContextInitToClient((RsContext)con);
385}
386
387static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
388{
389    LOG_API("nContextDeinitToClient, con(%p)", (RsContext)con);
390    rsContextDeinitToClient((RsContext)con);
391}
392
393static void
394nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
395{
396    jint *ptr = NULL;
397    jint len = 0;
398    if (data) {
399        len = _env->GetArrayLength(data);
400        jint *ptr = _env->GetIntArrayElements(data, NULL);
401    }
402    LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
403    rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
404    if (data) {
405        _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
406    }
407}
408
409
410
411static jlong
412nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size)
413{
414    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con, type, kind, norm, size);
415    return (jlong)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind, norm, size);
416}
417
418static jlong
419nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
420                jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
421{
422    int fieldCount = _env->GetArrayLength(_ids);
423    LOG_API("nElementCreate2, con(%p)", (RsContext)con);
424
425    jlong *jIds = _env->GetLongArrayElements(_ids, NULL);
426    jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
427
428    RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
429    uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
430
431    for(int i = 0; i < fieldCount; i ++) {
432        ids[i] = (RsElement)jIds[i];
433        arraySizes[i] = (uint32_t)jArraySizes[i];
434    }
435
436    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
437
438    const char **nameArray = names.c_str();
439    size_t *sizeArray = names.c_str_len();
440
441    jlong id = (jlong)rsElementCreate2((RsContext)con,
442                                     (const RsElement *)ids, fieldCount,
443                                     nameArray, fieldCount * sizeof(size_t),  sizeArray,
444                                     (const uint32_t *)arraySizes, fieldCount);
445
446    free(ids);
447    free(arraySizes);
448    _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
449    _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
450
451    return (jlong)id;
452}
453
454static void
455nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData)
456{
457    int dataSize = _env->GetArrayLength(_elementData);
458    LOG_API("nElementGetNativeData, con(%p)", (RsContext)con);
459
460    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
461    assert(dataSize == 5);
462
463    uintptr_t elementData[5];
464    rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize);
465
466    for(jint i = 0; i < dataSize; i ++) {
467        const jint data = (jint)elementData[i];
468        _env->SetIntArrayRegion(_elementData, i, 1, &data);
469    }
470}
471
472
473static void
474nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
475                       jlongArray _IDs,
476                       jobjectArray _names,
477                       jintArray _arraySizes)
478{
479    uint32_t dataSize = _env->GetArrayLength(_IDs);
480    LOG_API("nElementGetSubElements, con(%p)", (RsContext)con);
481
482    uintptr_t *ids = (uintptr_t*)malloc(dataSize * sizeof(uintptr_t));
483    const char **names = (const char **)malloc(dataSize * sizeof(const char *));
484    uint32_t *arraySizes = (uint32_t *)malloc(dataSize * sizeof(uint32_t));
485
486    rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
487
488    for(uint32_t i = 0; i < dataSize; i++) {
489        const jlong id = (jlong)ids[i];
490        const jint arraySize = (jint)arraySizes[i];
491        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
492        _env->SetLongArrayRegion(_IDs, i, 1, &id);
493        _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
494    }
495
496    free(ids);
497    free(names);
498    free(arraySizes);
499}
500
501// -----------------------------------
502
503static jlong
504nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
505            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
506{
507    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
508            (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv);
509
510    return (jlong)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips, faces, yuv);
511}
512
513static void
514nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jlongArray _typeData)
515{
516    // We are packing 6 items: mDimX; mDimY; mDimZ;
517    // mDimLOD; mDimFaces; mElement; into typeData
518    int elementCount = _env->GetArrayLength(_typeData);
519
520    assert(elementCount == 6);
521    LOG_API("nTypeGetNativeData, con(%p)", (RsContext)con);
522
523    uintptr_t typeData[6];
524    rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
525
526    for(jint i = 0; i < elementCount; i ++) {
527        const jlong data = (jlong)typeData[i];
528        _env->SetLongArrayRegion(_typeData, i, 1, &data);
529    }
530}
531
532// -----------------------------------
533
534static jlong
535nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, jlong pointer)
536{
537    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
538    return (jlong) rsAllocationCreateTyped((RsContext)con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uintptr_t)pointer);
539}
540
541static void
542nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
543{
544    LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a, bits);
545    rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
546}
547
548static jobject
549nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
550{
551    LOG_API("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
552
553    IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con, (RsAllocation)a);
554    sp<IGraphicBufferProducer> bp = v;
555    v->decStrong(NULL);
556
557    jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp);
558    return o;
559}
560
561static void
562nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
563{
564    LOG_API("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)",
565            (RsContext)con, (RsAllocation)alloc, (Surface *)sur);
566
567    sp<Surface> s;
568    if (sur != 0) {
569        s = android_view_Surface_getSurface(_env, sur);
570    }
571
572    rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, static_cast<ANativeWindow *>(s.get()));
573}
574
575static void
576nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
577{
578    LOG_API("nAllocationIoSend, con(%p), alloc(%p)", (RsContext)con, alloc);
579    rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
580}
581
582static void
583nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
584{
585    LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, alloc);
586    rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
587}
588
589
590static void
591nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
592{
593    LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
594    rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
595}
596
597static jlong
598nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
599{
600    SkBitmap const * nativeBitmap =
601            (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
602    const SkBitmap& bitmap(*nativeBitmap);
603
604    bitmap.lockPixels();
605    const void* ptr = bitmap.getPixels();
606    jlong id = (jlong)rsAllocationCreateFromBitmap((RsContext)con,
607                                                  (RsType)type, (RsAllocationMipmapControl)mip,
608                                                  ptr, bitmap.getSize(), usage);
609    bitmap.unlockPixels();
610    return id;
611}
612
613static jlong
614nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
615{
616    SkBitmap const * nativeBitmap =
617            (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
618    const SkBitmap& bitmap(*nativeBitmap);
619
620    bitmap.lockPixels();
621    const void* ptr = bitmap.getPixels();
622    jlong id = (jlong)rsAllocationCreateTyped((RsContext)con,
623                                            (RsType)type, (RsAllocationMipmapControl)mip,
624                                            (uint32_t)usage, (uintptr_t)ptr);
625    bitmap.unlockPixels();
626    return id;
627}
628
629static jlong
630nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, jobject jbitmap, jint usage)
631{
632    SkBitmap const * nativeBitmap =
633            (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
634    const SkBitmap& bitmap(*nativeBitmap);
635
636    bitmap.lockPixels();
637    const void* ptr = bitmap.getPixels();
638    jlong id = (jlong)rsAllocationCubeCreateFromBitmap((RsContext)con,
639                                                      (RsType)type, (RsAllocationMipmapControl)mip,
640                                                      ptr, bitmap.getSize(), usage);
641    bitmap.unlockPixels();
642    return id;
643}
644
645static void
646nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
647{
648    SkBitmap const * nativeBitmap =
649            (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
650    const SkBitmap& bitmap(*nativeBitmap);
651    int w = bitmap.width();
652    int h = bitmap.height();
653
654    bitmap.lockPixels();
655    const void* ptr = bitmap.getPixels();
656    rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
657                       0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
658                       w, h, ptr, bitmap.getSize(), 0);
659    bitmap.unlockPixels();
660}
661
662static void
663nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
664{
665    SkBitmap const * nativeBitmap =
666            (SkBitmap const *)_env->GetLongField(jbitmap, gNativeBitmapID);
667    const SkBitmap& bitmap(*nativeBitmap);
668
669    bitmap.lockPixels();
670    void* ptr = bitmap.getPixels();
671    rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
672    bitmap.unlockPixels();
673    bitmap.notifyPixelsChanged();
674}
675
676static void ReleaseBitmapCallback(void *bmp)
677{
678    SkBitmap const * nativeBitmap = (SkBitmap const *)bmp;
679    nativeBitmap->unlockPixels();
680}
681
682
683// Copies from the Java object data into the Allocation pointed to by _alloc.
684static void
685nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
686                  jint count, jobject data, jint sizeBytes, jint dataType)
687{
688    RsAllocation *alloc = (RsAllocation *)_alloc;
689    LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), dataType(%i)",
690            (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes, dataType);
691    PER_ARRAY_TYPE(NULL, rsAllocation1DData, true, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
692}
693
694// Copies from the Java array data into the Allocation pointed to by alloc.
695static void
696//    native void rsnAllocationElementData1D(long con, long id, int xoff, int compIdx, byte[] d, int sizeBytes);
697nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint offset, jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
698{
699    jint len = _env->GetArrayLength(data);
700    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
701    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
702    rsAllocation1DElementData((RsContext)con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
703    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
704}
705
706// Copies from the Java object data into the Allocation pointed to by _alloc.
707static void
708nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
709                  jint w, jint h, jobject data, jint sizeBytes, jint dataType)
710{
711    RsAllocation *alloc = (RsAllocation *)_alloc;
712    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
713    LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)",
714            (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
715    PER_ARRAY_TYPE(NULL, rsAllocation2DData, true, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
716}
717
718// Copies from the Allocation pointed to by srcAlloc into the Allocation
719// pointed to by dstAlloc.
720static void
721nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
722                        jlong dstAlloc, jint dstXoff, jint dstYoff,
723                        jint dstMip, jint dstFace,
724                        jint width, jint height,
725                        jlong srcAlloc, jint srcXoff, jint srcYoff,
726                        jint srcMip, jint srcFace)
727{
728    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
729            " dstMip(%i), dstFace(%i), width(%i), height(%i),"
730            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
731            (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
732            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
733
734    rsAllocationCopy2DRange((RsContext)con,
735                            (RsAllocation)dstAlloc,
736                            dstXoff, dstYoff,
737                            dstMip, dstFace,
738                            width, height,
739                            (RsAllocation)srcAlloc,
740                            srcXoff, srcYoff,
741                            srcMip, srcFace);
742}
743
744// Copies from the Java object data into the Allocation pointed to by _alloc.
745static void
746nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
747                    jint w, jint h, jint d, jobject data, int sizeBytes, int dataType)
748{
749    RsAllocation *alloc = (RsAllocation *)_alloc;
750    LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i), h(%i), d(%i), sizeBytes(%i)",
751            (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, sizeBytes);
752    PER_ARRAY_TYPE(NULL, rsAllocation3DData, true, (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
753}
754
755// Copies from the Allocation pointed to by srcAlloc into the Allocation
756// pointed to by dstAlloc.
757static void
758nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
759                        jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
760                        jint dstMip,
761                        jint width, jint height, jint depth,
762                        jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
763                        jint srcMip)
764{
765    LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
766            " dstMip(%i), width(%i), height(%i),"
767            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
768            (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip,
769            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip);
770
771    rsAllocationCopy3DRange((RsContext)con,
772                            (RsAllocation)dstAlloc,
773                            dstXoff, dstYoff, dstZoff, dstMip,
774                            width, height, depth,
775                            (RsAllocation)srcAlloc,
776                            srcXoff, srcYoff, srcZoff, srcMip);
777}
778
779
780// Copies from the Allocation pointed to by _alloc into the Java object data.
781static void
782nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, int dataType)
783{
784    RsAllocation *alloc = (RsAllocation *)_alloc;
785    LOG_API("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
786    PER_ARRAY_TYPE(0, rsAllocationRead, false, (RsContext)con, alloc, ptr, len * typeBytes);
787}
788
789// Copies from the Allocation pointed to by _alloc into the Java object data.
790static void
791nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
792                  jint count, jobject data, int sizeBytes, int dataType)
793{
794    RsAllocation *alloc = (RsAllocation *)_alloc;
795    LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), dataType(%i)",
796            (RsContext)con, alloc, offset, count, sizeBytes, dataType);
797    PER_ARRAY_TYPE(0, rsAllocation1DRead, false, (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
798}
799
800// Copies from the Allocation pointed to by _alloc into the Java object data.
801static void
802nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
803                  jint w, jint h, jobject data, int sizeBytes, int dataType)
804{
805    RsAllocation *alloc = (RsAllocation *)_alloc;
806    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
807    LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) type(%i)",
808            (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
809    PER_ARRAY_TYPE(0, rsAllocation2DRead, false, (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
810}
811
812static jlong
813nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
814{
815    LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
816    return (jlong) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
817}
818
819static void
820nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
821{
822    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con, (RsAllocation)alloc, dimX);
823    rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
824}
825
826// -----------------------------------
827
828static jlong
829nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset)
830{
831    Asset* asset = reinterpret_cast<Asset*>(native_asset);
832    ALOGV("______nFileA3D %p", asset);
833
834    jlong id = (jlong)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
835    return id;
836}
837
838static jlong
839nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
840{
841    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
842    if (mgr == NULL) {
843        return 0;
844    }
845
846    AutoJavaStringToUTF8 str(_env, _path);
847    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
848    if (asset == NULL) {
849        return 0;
850    }
851
852    jlong id = (jlong)rsaFileA3DCreateFromAsset((RsContext)con, asset);
853    return id;
854}
855
856static jlong
857nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
858{
859    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
860    jlong id = (jlong)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
861
862    return id;
863}
864
865static jint
866nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D)
867{
868    int32_t numEntries = 0;
869    rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D);
870    return (jint)numEntries;
871}
872
873static void
874nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
875{
876    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
877    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
878
879    rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
880
881    for(jint i = 0; i < numEntries; i ++) {
882        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
883        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
884    }
885
886    free(fileEntries);
887}
888
889static jlong
890nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
891{
892    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
893    jlong id = (jlong)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
894    return id;
895}
896
897// -----------------------------------
898
899static jlong
900nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con,
901                    jstring fileName, jfloat fontSize, jint dpi)
902{
903    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
904    jlong id = (jlong)rsFontCreateFromFile((RsContext)con,
905                                         fileNameUTF.c_str(), fileNameUTF.length(),
906                                         fontSize, dpi);
907
908    return id;
909}
910
911static jlong
912nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con,
913                           jstring name, jfloat fontSize, jint dpi, jlong native_asset)
914{
915    Asset* asset = reinterpret_cast<Asset*>(native_asset);
916    AutoJavaStringToUTF8 nameUTF(_env, name);
917
918    jlong id = (jlong)rsFontCreateFromMemory((RsContext)con,
919                                           nameUTF.c_str(), nameUTF.length(),
920                                           fontSize, dpi,
921                                           asset->getBuffer(false), asset->getLength());
922    return id;
923}
924
925static jlong
926nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
927                     jfloat fontSize, jint dpi)
928{
929    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
930    if (mgr == NULL) {
931        return 0;
932    }
933
934    AutoJavaStringToUTF8 str(_env, _path);
935    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
936    if (asset == NULL) {
937        return 0;
938    }
939
940    jlong id = (jlong)rsFontCreateFromMemory((RsContext)con,
941                                           str.c_str(), str.length(),
942                                           fontSize, dpi,
943                                           asset->getBuffer(false), asset->getLength());
944    delete asset;
945    return id;
946}
947
948// -----------------------------------
949
950static void
951nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
952{
953    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
954    rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
955}
956
957static void
958nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
959{
960    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script, slot, val);
961    rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
962}
963
964static jint
965nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
966{
967    LOG_API("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
968    int value = 0;
969    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
970    return value;
971}
972
973static void
974nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
975{
976    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script, slot, val);
977    rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
978}
979
980static void
981nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
982{
983    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con, (void *)script, slot, val);
984    rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
985}
986
987static jlong
988nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
989{
990    LOG_API("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
991    jlong value = 0;
992    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
993    return value;
994}
995
996static void
997nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
998{
999    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script, slot, val);
1000    rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1001}
1002
1003static jfloat
1004nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1005{
1006    LOG_API("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1007    jfloat value = 0;
1008    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1009    return value;
1010}
1011
1012static void
1013nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
1014{
1015    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script, slot, val);
1016    rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1017}
1018
1019static jdouble
1020nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1021{
1022    LOG_API("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1023    jdouble value = 0;
1024    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1025    return value;
1026}
1027
1028static void
1029nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1030{
1031    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1032    jint len = _env->GetArrayLength(data);
1033    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1034    rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1035    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1036}
1037
1038static void
1039nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1040{
1041    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1042    jint len = _env->GetArrayLength(data);
1043    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1044    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1045    _env->ReleaseByteArrayElements(data, ptr, 0);
1046}
1047
1048static void
1049nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jlong elem, jintArray dims)
1050{
1051    LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1052    jint len = _env->GetArrayLength(data);
1053    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1054    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1055    jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
1056    rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1057                     (const uint32_t*) dimsPtr, dimsLen);
1058    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1059    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1060}
1061
1062
1063static void
1064nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
1065{
1066    LOG_API("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
1067
1068    jint length = _env->GetArrayLength(timeZone);
1069    jbyte* timeZone_ptr;
1070    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1071
1072    rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1073
1074    if (timeZone_ptr) {
1075        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1076    }
1077}
1078
1079static void
1080nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
1081{
1082    LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1083    rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
1084}
1085
1086static void
1087nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1088{
1089    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1090    jint len = _env->GetArrayLength(data);
1091    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
1092    rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1093    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1094}
1095
1096static void
1097nScriptForEach(JNIEnv *_env, jobject _this, jlong con,
1098               jlong script, jint slot, jlong ain, jlong aout)
1099{
1100    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1101    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, NULL, 0);
1102}
1103static void
1104nScriptForEachV(JNIEnv *_env, jobject _this, jlong con,
1105                jlong script, jint slot, jlong ain, jlong aout, jbyteArray params)
1106{
1107    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1108    jint len = _env->GetArrayLength(params);
1109    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1110    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, NULL, 0);
1111    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1112}
1113
1114static void
1115nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con,
1116                      jlong script, jint slot, jlong ain, jlong aout,
1117                      jint xstart, jint xend,
1118                      jint ystart, jint yend, jint zstart, jint zend)
1119{
1120    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1121    RsScriptCall sc;
1122    sc.xStart = xstart;
1123    sc.xEnd = xend;
1124    sc.yStart = ystart;
1125    sc.yEnd = yend;
1126    sc.zStart = zstart;
1127    sc.zEnd = zend;
1128    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1129    sc.arrayStart = 0;
1130    sc.arrayEnd = 0;
1131    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc));
1132}
1133
1134static void
1135nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con,
1136                       jlong script, jint slot, jlong ain, jlong aout,
1137                       jbyteArray params, jint xstart, jint xend,
1138                       jint ystart, jint yend, jint zstart, jint zend)
1139{
1140    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1141    jint len = _env->GetArrayLength(params);
1142    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
1143    RsScriptCall sc;
1144    sc.xStart = xstart;
1145    sc.xEnd = xend;
1146    sc.yStart = ystart;
1147    sc.yEnd = yend;
1148    sc.zStart = zstart;
1149    sc.zEnd = zend;
1150    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1151    sc.arrayStart = 0;
1152    sc.arrayEnd = 0;
1153    rsScriptForEach((RsContext)con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, &sc, sizeof(sc));
1154    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
1155}
1156
1157static void
1158nScriptForEachMultiClipped(JNIEnv *_env, jobject _this, jlong con,
1159                      jlong script, jint slot, jlongArray ains, jlong aout,
1160                      jint xstart, jint xend,
1161                      jint ystart, jint yend, jint zstart, jint zend)
1162{
1163    LOG_API("nScriptForEachMultiClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1164
1165    jint   in_len = _env->GetArrayLength(ains);
1166    jlong* in_ptr = _env->GetLongArrayElements(ains, NULL);
1167
1168    RsAllocation *in_allocs = NULL;
1169
1170    if (sizeof(RsAllocation) == sizeof(jlong)) {
1171      in_allocs = (RsAllocation*)in_ptr;
1172
1173    } else {
1174      // Convert from 64-bit jlong types to the native pointer type.
1175
1176      in_allocs = new RsAllocation[in_len];
1177
1178      for (int index = in_len; --index >= 0;) {
1179        in_allocs[index] = (RsAllocation)in_ptr[index];
1180      }
1181    }
1182
1183    RsScriptCall sc;
1184    sc.xStart = xstart;
1185    sc.xEnd = xend;
1186    sc.yStart = ystart;
1187    sc.yEnd = yend;
1188    sc.zStart = zstart;
1189    sc.zEnd = zend;
1190    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1191    sc.arrayStart = 0;
1192    sc.arrayEnd = 0;
1193
1194    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot, in_allocs, in_len, (RsAllocation)aout, NULL, 0, &sc, sizeof(sc));
1195
1196    if (sizeof(RsAllocation) != sizeof(jlong)) {
1197      delete[] in_allocs;
1198    }
1199
1200    _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
1201}
1202
1203static void
1204nScriptForEachMultiClippedV(JNIEnv *_env, jobject _this, jlong con,
1205                       jlong script, jint slot, jlongArray ains, jlong aout,
1206                       jbyteArray params, jint xstart, jint xend,
1207                       jint ystart, jint yend, jint zstart, jint zend)
1208{
1209    LOG_API("nScriptForEachMultiClippedV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1210
1211    jint   in_len = _env->GetArrayLength(ains);
1212    jlong* in_ptr = _env->GetLongArrayElements(ains, NULL);
1213
1214    RsAllocation *in_allocs = NULL;
1215
1216    if (sizeof(RsAllocation) == sizeof(jlong)) {
1217      in_allocs = (RsAllocation*)in_ptr;
1218
1219    } else {
1220      // Convert from 64-bit jlong types to the native pointer type.
1221
1222      in_allocs = new RsAllocation[in_len];
1223
1224      for (int index = in_len; --index >= 0;) {
1225        in_allocs[index] = (RsAllocation)in_ptr[index];
1226      }
1227    }
1228
1229    jint   param_len = _env->GetArrayLength(params);
1230    jbyte* param_ptr = _env->GetByteArrayElements(params, NULL);
1231
1232    RsScriptCall sc;
1233    sc.xStart = xstart;
1234    sc.xEnd = xend;
1235    sc.yStart = ystart;
1236    sc.yEnd = yend;
1237    sc.zStart = zstart;
1238    sc.zEnd = zend;
1239    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
1240    sc.arrayStart = 0;
1241    sc.arrayEnd = 0;
1242    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot, in_allocs, in_len, (RsAllocation)aout, param_ptr, param_len, &sc, sizeof(sc));
1243
1244    if (sizeof(RsAllocation) != sizeof(jlong)) {
1245      delete[] in_allocs;
1246    }
1247
1248    _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
1249    _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
1250}
1251
1252// -----------------------------------
1253
1254static jlong
1255nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
1256               jstring resName, jstring cacheDir,
1257               jbyteArray scriptRef, jint length)
1258{
1259    LOG_API("nScriptCCreate, con(%p)", (RsContext)con);
1260
1261    AutoJavaStringToUTF8 resNameUTF(_env, resName);
1262    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
1263    jlong ret = 0;
1264    jbyte* script_ptr = NULL;
1265    jint _exception = 0;
1266    jint remaining;
1267    if (!scriptRef) {
1268        _exception = 1;
1269        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
1270        goto exit;
1271    }
1272    if (length < 0) {
1273        _exception = 1;
1274        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
1275        goto exit;
1276    }
1277    remaining = _env->GetArrayLength(scriptRef);
1278    if (remaining < length) {
1279        _exception = 1;
1280        //jniThrowException(_env, "java/lang/IllegalArgumentException",
1281        //        "length > script.length - offset");
1282        goto exit;
1283    }
1284    script_ptr = (jbyte *)
1285        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
1286
1287    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
1288
1289    ret = (jlong)rsScriptCCreate((RsContext)con,
1290                                resNameUTF.c_str(), resNameUTF.length(),
1291                                cacheDirUTF.c_str(), cacheDirUTF.length(),
1292                                (const char *)script_ptr, length);
1293
1294exit:
1295    if (script_ptr) {
1296        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
1297                _exception ? JNI_ABORT: 0);
1298    }
1299
1300    return (jlong)ret;
1301}
1302
1303static jlong
1304nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
1305{
1306    LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid);
1307    return (jlong)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
1308}
1309
1310static jlong
1311nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
1312{
1313    LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con, (void *)sid, slot, sig);
1314    return (jlong)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
1315}
1316
1317static jlong
1318nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
1319{
1320    LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot);
1321    return (jlong)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
1322}
1323
1324static jlong
1325nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
1326    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
1327{
1328    LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con);
1329
1330    jint kernelsLen = _env->GetArrayLength(_kernels);
1331    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, NULL);
1332    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
1333    for(int i = 0; i < kernelsLen; ++i) {
1334        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
1335    }
1336
1337    jint srcLen = _env->GetArrayLength(_src);
1338    jlong *jSrcPtr = _env->GetLongArrayElements(_src, NULL);
1339    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
1340    for(int i = 0; i < srcLen; ++i) {
1341        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
1342    }
1343
1344    jint dstkLen = _env->GetArrayLength(_dstk);
1345    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, NULL);
1346    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
1347    for(int i = 0; i < dstkLen; ++i) {
1348        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
1349    }
1350
1351    jint dstfLen = _env->GetArrayLength(_dstf);
1352    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, NULL);
1353    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
1354    for(int i = 0; i < dstfLen; ++i) {
1355        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
1356    }
1357
1358    jint typesLen = _env->GetArrayLength(_types);
1359    jlong *jTypesPtr = _env->GetLongArrayElements(_types, NULL);
1360    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
1361    for(int i = 0; i < typesLen; ++i) {
1362        typesPtr[i] = (RsType)jTypesPtr[i];
1363    }
1364
1365    jlong id = (jlong)rsScriptGroupCreate((RsContext)con,
1366                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
1367                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
1368                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
1369                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
1370                               (RsType *)typesPtr, typesLen * sizeof(RsType));
1371
1372    free(kernelsPtr);
1373    free(srcPtr);
1374    free(dstkPtr);
1375    free(dstfPtr);
1376    free(typesPtr);
1377    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
1378    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
1379    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
1380    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
1381    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
1382    return id;
1383}
1384
1385static void
1386nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1387{
1388    LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1389        (void *)gid, (void *)kid, (void *)alloc);
1390    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1391}
1392
1393static void
1394nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
1395{
1396    LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
1397        (void *)gid, (void *)kid, (void *)alloc);
1398    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
1399}
1400
1401static void
1402nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
1403{
1404    LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
1405    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
1406}
1407
1408// ---------------------------------------------------------------------------
1409
1410static jlong
1411nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
1412                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
1413                    jboolean depthMask, jboolean ditherEnable,
1414                    jint srcFunc, jint destFunc,
1415                    jint depthFunc)
1416{
1417    LOG_API("nProgramStoreCreate, con(%p)", (RsContext)con);
1418    return (jlong)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
1419                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
1420                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
1421}
1422
1423// ---------------------------------------------------------------------------
1424
1425static void
1426nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
1427{
1428    LOG_API("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
1429    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
1430}
1431
1432static void
1433nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
1434{
1435    LOG_API("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1436    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
1437}
1438
1439static void
1440nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
1441{
1442    LOG_API("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1443    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
1444}
1445
1446// ---------------------------------------------------------------------------
1447
1448static jlong
1449nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
1450                       jobjectArray texNames, jlongArray params)
1451{
1452    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1453    jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
1454    jint paramLen = _env->GetArrayLength(params);
1455
1456    int texCount = _env->GetArrayLength(texNames);
1457    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
1458    const char ** nameArray = names.c_str();
1459    size_t* sizeArray = names.c_str_len();
1460
1461    LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
1462
1463    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
1464    for(int i = 0; i < paramLen; ++i) {
1465        paramPtr[i] = (uintptr_t)jParamPtr[i];
1466    }
1467    jlong ret = (jlong)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
1468                                             nameArray, texCount, sizeArray,
1469                                             paramPtr, paramLen);
1470
1471    free(paramPtr);
1472    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
1473    return ret;
1474}
1475
1476
1477// ---------------------------------------------------------------------------
1478
1479static jlong
1480nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
1481                     jobjectArray texNames, jlongArray params)
1482{
1483    AutoJavaStringToUTF8 shaderUTF(_env, shader);
1484    jlong *jParamPtr = _env->GetLongArrayElements(params, NULL);
1485    jint paramLen = _env->GetArrayLength(params);
1486
1487    LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
1488
1489    int texCount = _env->GetArrayLength(texNames);
1490    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
1491    const char ** nameArray = names.c_str();
1492    size_t* sizeArray = names.c_str_len();
1493
1494    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
1495    for(int i = 0; i < paramLen; ++i) {
1496        paramPtr[i] = (uintptr_t)jParamPtr[i];
1497    }
1498
1499    jlong ret = (jlong)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
1500                                           nameArray, texCount, sizeArray,
1501                                           paramPtr, paramLen);
1502
1503    free(paramPtr);
1504    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
1505    return ret;
1506}
1507
1508// ---------------------------------------------------------------------------
1509
1510static jlong
1511nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
1512{
1513    LOG_API("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con, pointSprite, cull);
1514    return (jlong)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
1515}
1516
1517
1518// ---------------------------------------------------------------------------
1519
1520static void
1521nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
1522{
1523    LOG_API("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
1524    rsContextBindRootScript((RsContext)con, (RsScript)script);
1525}
1526
1527static void
1528nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
1529{
1530    LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
1531    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
1532}
1533
1534static void
1535nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
1536{
1537    LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con, (RsProgramFragment)pf);
1538    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
1539}
1540
1541static void
1542nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
1543{
1544    LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
1545    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
1546}
1547
1548static void
1549nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
1550{
1551    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
1552    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
1553}
1554
1555
1556// ---------------------------------------------------------------------------
1557
1558static jlong
1559nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
1560               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
1561{
1562    LOG_API("nSamplerCreate, con(%p)", (RsContext)con);
1563    return (jlong)rsSamplerCreate((RsContext)con,
1564                                 (RsSamplerValue)magFilter,
1565                                 (RsSamplerValue)minFilter,
1566                                 (RsSamplerValue)wrapS,
1567                                 (RsSamplerValue)wrapT,
1568                                 (RsSamplerValue)wrapR,
1569                                 aniso);
1570}
1571
1572// ---------------------------------------------------------------------------
1573
1574static jlong
1575nPathCreate(JNIEnv *_env, jobject _this, jlong con, jint prim, jboolean isStatic, jlong _vtx, jlong _loop, jfloat q) {
1576    LOG_API("nPathCreate, con(%p)", (RsContext)con);
1577
1578    jlong id = (jlong)rsPathCreate((RsContext)con, (RsPathPrimitive)prim, isStatic,
1579                                   (RsAllocation)_vtx,
1580                                   (RsAllocation)_loop, q);
1581    return id;
1582}
1583
1584static jlong
1585nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
1586{
1587    LOG_API("nMeshCreate, con(%p)", (RsContext)con);
1588
1589    jint vtxLen = _env->GetArrayLength(_vtx);
1590    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, NULL);
1591    RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
1592    for(int i = 0; i < vtxLen; ++i) {
1593        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
1594    }
1595
1596    jint idxLen = _env->GetArrayLength(_idx);
1597    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, NULL);
1598    RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
1599    for(int i = 0; i < idxLen; ++i) {
1600        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
1601    }
1602
1603    jint primLen = _env->GetArrayLength(_prim);
1604    jint *primPtr = _env->GetIntArrayElements(_prim, NULL);
1605
1606    jlong id = (jlong)rsMeshCreate((RsContext)con,
1607                               (RsAllocation *)vtxPtr, vtxLen,
1608                               (RsAllocation *)idxPtr, idxLen,
1609                               (uint32_t *)primPtr, primLen);
1610
1611    free(vtxPtr);
1612    free(idxPtr);
1613    _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
1614    _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
1615    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
1616    return id;
1617}
1618
1619static jint
1620nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
1621{
1622    LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1623    jint vtxCount = 0;
1624    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
1625    return vtxCount;
1626}
1627
1628static jint
1629nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
1630{
1631    LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1632    jint idxCount = 0;
1633    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
1634    return idxCount;
1635}
1636
1637static void
1638nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
1639{
1640    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1641
1642    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
1643    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
1644
1645    for(jint i = 0; i < numVtxIDs; i ++) {
1646        const jlong alloc = (jlong)allocs[i];
1647        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
1648    }
1649
1650    free(allocs);
1651}
1652
1653static void
1654nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
1655{
1656    LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
1657
1658    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
1659    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
1660
1661    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
1662
1663    for(jint i = 0; i < numIndices; i ++) {
1664        const jlong alloc = (jlong)allocs[i];
1665        const jint prim = (jint)prims[i];
1666        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
1667        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
1668    }
1669
1670    free(allocs);
1671    free(prims);
1672}
1673
1674static jint
1675nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
1676    return (jint)sizeof(void*);
1677}
1678
1679
1680// ---------------------------------------------------------------------------
1681
1682
1683static const char *classPathName = "android/renderscript/RenderScript";
1684
1685static JNINativeMethod methods[] = {
1686{"_nInit",                         "()V",                                     (void*)_nInit },
1687
1688{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
1689{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
1690{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
1691{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
1692{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
1693{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
1694
1695{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
1696{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
1697
1698
1699// All methods below are thread protected in java.
1700{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
1701{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
1702{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
1703{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
1704{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
1705{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
1706{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
1707{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
1708{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
1709{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
1710{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
1711{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
1712{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
1713
1714{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
1715{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
1716{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
1717{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
1718{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
1719{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
1720
1721{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
1722{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
1723{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
1724
1725{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
1726{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
1727{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
1728{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
1729
1730{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
1731{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
1732
1733{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
1734{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
1735{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
1736{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
1737
1738{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
1739{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
1740
1741{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
1742{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
1743{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
1744{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
1745{"rsnAllocationIoReceive",           "(JJ)V",                                 (void*)nAllocationIoReceive },
1746{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;II)V",          (void*)nAllocationData1D },
1747{"rsnAllocationElementData1D",       "(JJIII[BI)V",                           (void*)nAllocationElementData1D },
1748{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;II)V",       (void*)nAllocationData2D },
1749{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
1750{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;II)V",      (void*)nAllocationData3D },
1751{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
1752{"rsnAllocationRead",                "(JJLjava/lang/Object;I)V",              (void*)nAllocationRead },
1753{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;II)V",          (void*)nAllocationRead1D },
1754{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;II)V",       (void*)nAllocationRead2D },
1755{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
1756{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
1757{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
1758
1759{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
1760{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
1761{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
1762{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
1763{"rsnScriptForEach",                 "(JJIJJ)V",                              (void*)nScriptForEach },
1764{"rsnScriptForEach",                 "(JJIJJ[B)V",                            (void*)nScriptForEachV },
1765{"rsnScriptForEachClipped",          "(JJIJJIIIIII)V",                        (void*)nScriptForEachClipped },
1766{"rsnScriptForEachClipped",          "(JJIJJ[BIIIIII)V",                      (void*)nScriptForEachClippedV },
1767{"rsnScriptForEachMultiClipped",     "(JJI[JJIIIIII)V",                       (void*)nScriptForEachMultiClipped },
1768{"rsnScriptForEachMultiClipped",     "(JJI[JJ[BIIIIII)V",                     (void*)nScriptForEachMultiClippedV },
1769{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
1770{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
1771{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
1772{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
1773{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
1774{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
1775{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
1776{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
1777{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
1778{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
1779{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
1780{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
1781
1782{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
1783{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
1784{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
1785{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
1786{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
1787{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
1788{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
1789{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
1790
1791{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
1792
1793{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
1794{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
1795{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
1796
1797{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
1798{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
1799{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
1800
1801{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
1802{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
1803{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
1804{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
1805{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
1806
1807{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
1808
1809{"rsnPathCreate",                    "(JIZJJF)J",                             (void*)nPathCreate },
1810{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
1811
1812{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
1813{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
1814{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
1815{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
1816
1817{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
1818};
1819
1820static int registerFuncs(JNIEnv *_env)
1821{
1822    return android::AndroidRuntime::registerNativeMethods(
1823            _env, classPathName, methods, NELEM(methods));
1824}
1825
1826// ---------------------------------------------------------------------------
1827
1828jint JNI_OnLoad(JavaVM* vm, void* reserved)
1829{
1830    JNIEnv* env = NULL;
1831    jint result = -1;
1832
1833    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
1834        ALOGE("ERROR: GetEnv failed\n");
1835        goto bail;
1836    }
1837    assert(env != NULL);
1838
1839    if (registerFuncs(env) < 0) {
1840        ALOGE("ERROR: Renderscript native registration failed\n");
1841        goto bail;
1842    }
1843
1844    /* success -- return valid version number */
1845    result = JNI_VERSION_1_4;
1846
1847bail:
1848    return result;
1849}
1850