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#include <android/bitmap.h>
26#include "jni.h"
27#include "JNIHelp.h"
28#include "android_runtime/AndroidRuntime.h"
29#include <rs.h>
30#include <rsEnv.h>
31
32//#define LOG_API ALOG
33#define LOG_API(...)
34
35using namespace android;
36
37class AutoJavaStringToUTF8 {
38public:
39    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
40        fCStr = env->GetStringUTFChars(str, NULL);
41        fLength = env->GetStringUTFLength(str);
42    }
43    ~AutoJavaStringToUTF8() {
44        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
45    }
46    const char* c_str() const { return fCStr; }
47    jsize length() const { return fLength; }
48
49private:
50    JNIEnv*     fEnv;
51    jstring     fJStr;
52    const char* fCStr;
53    jsize       fLength;
54};
55
56class AutoJavaStringArrayToUTF8 {
57public:
58    AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
59    : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
60        mCStrings = NULL;
61        mSizeArray = NULL;
62        if (stringsLength > 0) {
63            mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
64            mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
65            for (jsize ct = 0; ct < stringsLength; ct ++) {
66                jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
67                mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL);
68                mSizeArray[ct] = mEnv->GetStringUTFLength(s);
69            }
70        }
71    }
72    ~AutoJavaStringArrayToUTF8() {
73        for (jsize ct=0; ct < mStringsLength; ct++) {
74            jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
75            mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
76        }
77        free(mCStrings);
78        free(mSizeArray);
79    }
80    const char **c_str() const { return mCStrings; }
81    size_t *c_str_len() const { return mSizeArray; }
82    jsize length() const { return mStringsLength; }
83
84private:
85    JNIEnv      *mEnv;
86    jobjectArray mStrings;
87    const char **mCStrings;
88    size_t      *mSizeArray;
89    jsize        mStringsLength;
90};
91
92// ---------------------------------------------------------------------------
93
94static jfieldID gContextId = 0;
95static jfieldID gNativeBitmapID = 0;
96static jfieldID gTypeNativeCache = 0;
97
98static void _nInit(JNIEnv *_env, jclass _this)
99{
100    gContextId             = _env->GetFieldID(_this, "mContext", "I");
101
102    jclass bitmapClass = _env->FindClass("android/graphics/Bitmap");
103    gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
104}
105
106// ---------------------------------------------------------------------------
107
108static void
109nContextFinish(JNIEnv *_env, jobject _this, RsContext con)
110{
111    LOG_API("nContextFinish, con(%p)", con);
112    rsContextFinish(con);
113}
114
115static void
116nObjDestroy(JNIEnv *_env, jobject _this, RsContext con, jint obj)
117{
118    LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj);
119    rsObjDestroy(con, (void *)obj);
120}
121
122// ---------------------------------------------------------------------------
123
124static jint
125nDeviceCreate(JNIEnv *_env, jobject _this)
126{
127    LOG_API("nDeviceCreate");
128    return (jint)rsDeviceCreate();
129}
130
131static void
132nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev)
133{
134    LOG_API("nDeviceDestroy");
135    return rsDeviceDestroy((RsDevice)dev);
136}
137
138static void
139nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value)
140{
141    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
142    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
143}
144
145static jint
146nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jint sdkVer)
147{
148    LOG_API("nContextCreate");
149    return (jint)rsContextCreate((RsDevice)dev, ver, sdkVer);
150}
151
152
153static void
154nContextSetPriority(JNIEnv *_env, jobject _this, RsContext con, jint p)
155{
156    LOG_API("ContextSetPriority, con(%p), priority(%i)", con, p);
157    rsContextSetPriority(con, p);
158}
159
160
161
162static void
163nContextDestroy(JNIEnv *_env, jobject _this, RsContext con)
164{
165    LOG_API("nContextDestroy, con(%p)", con);
166    rsContextDestroy(con);
167}
168
169static void
170nContextDump(JNIEnv *_env, jobject _this, RsContext con, jint bits)
171{
172    LOG_API("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
173    rsContextDump((RsContext)con, bits);
174}
175
176
177static jstring
178nContextGetErrorMessage(JNIEnv *_env, jobject _this, RsContext con)
179{
180    LOG_API("nContextGetErrorMessage, con(%p)", con);
181    char buf[1024];
182
183    size_t receiveLen;
184    uint32_t subID;
185    int id = rsContextGetMessage(con,
186                                 buf, sizeof(buf),
187                                 &receiveLen, sizeof(receiveLen),
188                                 &subID, sizeof(subID));
189    if (!id && receiveLen) {
190        ALOGV("message receive buffer too small.  %i", receiveLen);
191    }
192    return _env->NewStringUTF(buf);
193}
194
195static jint
196nContextGetUserMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data)
197{
198    jint len = _env->GetArrayLength(data);
199    LOG_API("nContextGetMessage, con(%p), len(%i)", con, len);
200    jint *ptr = _env->GetIntArrayElements(data, NULL);
201    size_t receiveLen;
202    uint32_t subID;
203    int id = rsContextGetMessage(con,
204                                 ptr, len * 4,
205                                 &receiveLen, sizeof(receiveLen),
206                                 &subID, sizeof(subID));
207    if (!id && receiveLen) {
208        ALOGV("message receive buffer too small.  %i", receiveLen);
209    }
210    _env->ReleaseIntArrayElements(data, ptr, 0);
211    return id;
212}
213
214static jint
215nContextPeekMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray auxData)
216{
217    LOG_API("nContextPeekMessage, con(%p)", con);
218    jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL);
219    size_t receiveLen;
220    uint32_t subID;
221    int id = rsContextPeekMessage(con, &receiveLen, sizeof(receiveLen),
222                                  &subID, sizeof(subID));
223    auxDataPtr[0] = (jint)subID;
224    auxDataPtr[1] = (jint)receiveLen;
225    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
226    return id;
227}
228
229static void nContextInitToClient(JNIEnv *_env, jobject _this, RsContext con)
230{
231    LOG_API("nContextInitToClient, con(%p)", con);
232    rsContextInitToClient(con);
233}
234
235static void nContextDeinitToClient(JNIEnv *_env, jobject _this, RsContext con)
236{
237    LOG_API("nContextDeinitToClient, con(%p)", con);
238    rsContextDeinitToClient(con);
239}
240
241
242static jint
243nElementCreate(JNIEnv *_env, jobject _this, RsContext con, jint type, jint kind, jboolean norm, jint size)
244{
245    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size);
246    return (jint)rsElementCreate(con, (RsDataType)type, (RsDataKind)kind, norm, size);
247}
248
249static jint
250nElementCreate2(JNIEnv *_env, jobject _this, RsContext con,
251                jintArray _ids, jobjectArray _names, jintArray _arraySizes)
252{
253    int fieldCount = _env->GetArrayLength(_ids);
254    LOG_API("nElementCreate2, con(%p)", con);
255
256    jint *ids = _env->GetIntArrayElements(_ids, NULL);
257    jint *arraySizes = _env->GetIntArrayElements(_arraySizes, NULL);
258
259    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
260
261    const char **nameArray = names.c_str();
262    size_t *sizeArray = names.c_str_len();
263
264    jint id = (jint)rsElementCreate2(con,
265                                     (RsElement *)ids, fieldCount,
266                                     nameArray, fieldCount * sizeof(size_t),  sizeArray,
267                                     (const uint32_t *)arraySizes, fieldCount);
268
269    _env->ReleaseIntArrayElements(_ids, ids, JNI_ABORT);
270    _env->ReleaseIntArrayElements(_arraySizes, arraySizes, JNI_ABORT);
271    return (jint)id;
272}
273
274
275
276static void
277nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id,
278                       jintArray _IDs,
279                       jobjectArray _names,
280                       jintArray _arraySizes)
281{
282    int dataSize = _env->GetArrayLength(_IDs);
283    LOG_API("nElementGetSubElements, con(%p)", con);
284
285    uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
286    const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
287    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
288
289    rsaElementGetSubElements(con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
290
291    for(jint i = 0; i < dataSize; i++) {
292        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
293        _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
294        _env->SetIntArrayRegion(_arraySizes, i, 1, (const jint*)&arraySizes[i]);
295    }
296
297    free(ids);
298    free(names);
299    free(arraySizes);
300}
301
302// -----------------------------------
303
304static int
305nTypeCreate(JNIEnv *_env, jobject _this, RsContext con, RsElement eid,
306            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces)
307{
308    LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i)",
309            con, eid, dimx, dimy, dimz, mips, faces);
310
311    jint id = (jint)rsTypeCreate(con, (RsElement)eid, dimx, dimy, dimz, mips, faces);
312    return (jint)id;
313}
314
315// -----------------------------------
316
317static jint
318nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage, jint pointer)
319{
320    LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", con, (RsElement)type, mips, usage, (void *)pointer);
321    return (jint) rsAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uint32_t)pointer);
322}
323
324static void
325nAllocationSyncAll(JNIEnv *_env, jobject _this, RsContext con, jint a, jint bits)
326{
327    LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", con, (RsAllocation)a, bits);
328    rsAllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
329}
330
331static void
332nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
333{
334    LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", con, (RsAllocation)alloc);
335    rsAllocationGenerateMipmaps(con, (RsAllocation)alloc);
336}
337
338static size_t GetBitmapSize(JNIEnv *env, jobject jbitmap) {
339    AndroidBitmapInfo info;
340    memset(&info, 0, sizeof(info));
341    AndroidBitmap_getInfo(env, jbitmap, &info);
342    size_t s = info.width * info.height;
343    switch (info.format) {
344        case ANDROID_BITMAP_FORMAT_RGBA_8888: s *= 4; break;
345        case ANDROID_BITMAP_FORMAT_RGB_565: s *= 2; break;
346        case ANDROID_BITMAP_FORMAT_RGBA_4444: s *= 2; break;
347    }
348    return s;
349}
350
351static int
352nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
353{
354    void *pixels = NULL;
355    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
356
357    jint id = 0;
358    if (pixels != NULL) {
359        id = (jint)rsAllocationCreateFromBitmap(con, (RsType)type,
360                                                (RsAllocationMipmapControl)mip, pixels,
361                                                GetBitmapSize(_env, jbitmap), usage);
362        AndroidBitmap_unlockPixels(_env, jbitmap);
363    }
364    return id;
365}
366
367static int
368nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mip, jobject jbitmap, jint usage)
369{
370    void *pixels = NULL;
371    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
372
373    jint id = 0;
374    if (pixels != NULL) {
375        id = (jint)rsAllocationCubeCreateFromBitmap(con,
376                                                    (RsType)type, (RsAllocationMipmapControl)mip,
377                                                    pixels, GetBitmapSize(_env, jbitmap), usage);
378        AndroidBitmap_unlockPixels(_env, jbitmap);
379    }
380    return id;
381}
382
383static void
384nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
385{
386    AndroidBitmapInfo info;
387    memset(&info, 0, sizeof(info));
388    AndroidBitmap_getInfo(_env, jbitmap, &info);
389
390    void *pixels = NULL;
391    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
392
393    if (pixels != NULL) {
394        rsAllocation2DData(con, (RsAllocation)alloc, 0, 0,
395                           0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
396                           info.width, info.height, pixels, GetBitmapSize(_env, jbitmap));
397        AndroidBitmap_unlockPixels(_env, jbitmap);
398    }
399}
400
401static void
402nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
403{
404    AndroidBitmapInfo info;
405    memset(&info, 0, sizeof(info));
406    AndroidBitmap_getInfo(_env, jbitmap, &info);
407
408    void *pixels = NULL;
409    AndroidBitmap_lockPixels(_env, jbitmap, &pixels);
410
411    if (pixels != NULL) {
412        rsAllocationCopyToBitmap(con, (RsAllocation)alloc, pixels, GetBitmapSize(_env, jbitmap));
413        AndroidBitmap_unlockPixels(_env, jbitmap);
414    }
415    //bitmap.notifyPixelsChanged();
416}
417
418
419static void
420nAllocationData1D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jintArray data, int sizeBytes)
421{
422    jint len = _env->GetArrayLength(data);
423    LOG_API("nAllocation1DData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
424    jint *ptr = _env->GetIntArrayElements(data, NULL);
425    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
426    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
427}
428
429static void
430nAllocationData1D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jshortArray data, int sizeBytes)
431{
432    jint len = _env->GetArrayLength(data);
433    LOG_API("nAllocation1DData_s, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
434    jshort *ptr = _env->GetShortArrayElements(data, NULL);
435    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
436    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
437}
438
439static void
440nAllocationData1D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jbyteArray data, int sizeBytes)
441{
442    jint len = _env->GetArrayLength(data);
443    LOG_API("nAllocation1DData_b, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
444    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
445    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
446    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
447}
448
449static void
450nAllocationData1D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint count, jfloatArray data, int sizeBytes)
451{
452    jint len = _env->GetArrayLength(data);
453    LOG_API("nAllocation1DData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, count, len, sizeBytes);
454    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
455    rsAllocation1DData(con, (RsAllocation)alloc, offset, lod, count, ptr, sizeBytes);
456    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
457}
458
459static void
460//    native void rsnAllocationElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
461nAllocationElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint offset, jint lod, jint compIdx, jbyteArray data, int sizeBytes)
462{
463    jint len = _env->GetArrayLength(data);
464    LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
465    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
466    rsAllocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
467    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
468}
469
470static void
471nAllocationData2D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
472                    jint w, jint h, jshortArray data, int sizeBytes)
473{
474    jint len = _env->GetArrayLength(data);
475    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);
476    jshort *ptr = _env->GetShortArrayElements(data, NULL);
477    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
478    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
479}
480
481static void
482nAllocationData2D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
483                    jint w, jint h, jbyteArray data, int sizeBytes)
484{
485    jint len = _env->GetArrayLength(data);
486    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);
487    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
488    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
489    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
490}
491
492static void
493nAllocationData2D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
494                    jint w, jint h, jintArray data, int sizeBytes)
495{
496    jint len = _env->GetArrayLength(data);
497    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);
498    jint *ptr = _env->GetIntArrayElements(data, NULL);
499    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
500    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
501}
502
503static void
504nAllocationData2D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint lod, jint face,
505                    jint w, jint h, jfloatArray data, int sizeBytes)
506{
507    jint len = _env->GetArrayLength(data);
508    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);
509    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
510    rsAllocation2DData(con, (RsAllocation)alloc, xoff, yoff, lod, (RsAllocationCubemapFace)face, w, h, ptr, sizeBytes);
511    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
512}
513
514static void
515nAllocationData2D_alloc(JNIEnv *_env, jobject _this, RsContext con,
516                        jint dstAlloc, jint dstXoff, jint dstYoff,
517                        jint dstMip, jint dstFace,
518                        jint width, jint height,
519                        jint srcAlloc, jint srcXoff, jint srcYoff,
520                        jint srcMip, jint srcFace)
521{
522    LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
523            " dstMip(%i), dstFace(%i), width(%i), height(%i),"
524            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
525            con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
526            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
527
528    rsAllocationCopy2DRange(con,
529                            (RsAllocation)dstAlloc,
530                            dstXoff, dstYoff,
531                            dstMip, dstFace,
532                            width, height,
533                            (RsAllocation)srcAlloc,
534                            srcXoff, srcYoff,
535                            srcMip, srcFace);
536}
537
538static void
539nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
540{
541    jint len = _env->GetArrayLength(data);
542    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
543    jint *ptr = _env->GetIntArrayElements(data, NULL);
544    jsize length = _env->GetArrayLength(data);
545    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(int));
546    _env->ReleaseIntArrayElements(data, ptr, 0);
547}
548
549static void
550nAllocationRead_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jshortArray data)
551{
552    jint len = _env->GetArrayLength(data);
553    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
554    jshort *ptr = _env->GetShortArrayElements(data, NULL);
555    jsize length = _env->GetArrayLength(data);
556    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(short));
557    _env->ReleaseShortArrayElements(data, ptr, 0);
558}
559
560static void
561nAllocationRead_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jbyteArray data)
562{
563    jint len = _env->GetArrayLength(data);
564    LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
565    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
566    jsize length = _env->GetArrayLength(data);
567    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(char));
568    _env->ReleaseByteArrayElements(data, ptr, 0);
569}
570
571static void
572nAllocationRead_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jfloatArray data)
573{
574    jint len = _env->GetArrayLength(data);
575    LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
576    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
577    jsize length = _env->GetArrayLength(data);
578    rsAllocationRead(con, (RsAllocation)alloc, ptr, length * sizeof(float));
579    _env->ReleaseFloatArrayElements(data, ptr, 0);
580}
581
582static jint
583nAllocationGetType(JNIEnv *_env, jobject _this, RsContext con, jint a)
584{
585    LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a);
586    return (jint) rsaAllocationGetType(con, (RsAllocation)a);
587}
588
589static void
590nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
591{
592    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
593    rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
594}
595
596static void
597nAllocationResize2D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX, jint dimY)
598{
599    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i), sizeY(%i)", con, (RsAllocation)alloc, dimX, dimY);
600    rsAllocationResize2D(con, (RsAllocation)alloc, dimX, dimY);
601}
602
603// -----------------------------------
604
605static void
606nScriptBindAllocation(JNIEnv *_env, jobject _this, RsContext con, jint script, jint alloc, jint slot)
607{
608    LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot);
609    rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot);
610}
611
612static void
613nScriptSetVarI(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
614{
615    LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
616    rsScriptSetVarI(con, (RsScript)script, slot, val);
617}
618
619static void
620nScriptSetVarObj(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jint val)
621{
622    LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", con, (void *)script, slot, val);
623    rsScriptSetVarObj(con, (RsScript)script, slot, (RsObjectBase)val);
624}
625
626static void
627nScriptSetVarJ(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jlong val)
628{
629    LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", con, (void *)script, slot, val);
630    rsScriptSetVarJ(con, (RsScript)script, slot, val);
631}
632
633static void
634nScriptSetVarF(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, float val)
635{
636    LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", con, (void *)script, slot, val);
637    rsScriptSetVarF(con, (RsScript)script, slot, val);
638}
639
640static void
641nScriptSetVarD(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, double val)
642{
643    LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", con, (void *)script, slot, val);
644    rsScriptSetVarD(con, (RsScript)script, slot, val);
645}
646
647static void
648nScriptSetVarV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
649{
650    LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
651    jint len = _env->GetArrayLength(data);
652    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
653    rsScriptSetVarV(con, (RsScript)script, slot, ptr, len);
654    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
655}
656
657static void
658nScriptSetVarVE(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data, jint elem, jintArray dims)
659{
660    LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
661    jint len = _env->GetArrayLength(data);
662    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
663    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
664    jint *dimsPtr = _env->GetIntArrayElements(dims, NULL);
665    rsScriptSetVarVE(con, (RsScript)script, slot, ptr, len, (RsElement)elem,
666                     (const size_t*) dimsPtr, dimsLen);
667    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
668    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
669}
670
671
672static void
673nScriptSetTimeZone(JNIEnv *_env, jobject _this, RsContext con, jint script, jbyteArray timeZone)
674{
675    LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone);
676
677    jint length = _env->GetArrayLength(timeZone);
678    jbyte* timeZone_ptr;
679    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
680
681    rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length);
682
683    if (timeZone_ptr) {
684        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
685    }
686}
687
688static void
689nScriptInvoke(JNIEnv *_env, jobject _this, RsContext con, jint obj, jint slot)
690{
691    LOG_API("nScriptInvoke, con(%p), script(%p)", con, (void *)obj);
692    rsScriptInvoke(con, (RsScript)obj, slot);
693}
694
695static void
696nScriptInvokeV(JNIEnv *_env, jobject _this, RsContext con, jint script, jint slot, jbyteArray data)
697{
698    LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
699    jint len = _env->GetArrayLength(data);
700    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
701    rsScriptInvokeV(con, (RsScript)script, slot, ptr, len);
702    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
703}
704
705static void
706nScriptForEach(JNIEnv *_env, jobject _this, RsContext con,
707               jint script, jint slot, jint ain, jint aout)
708{
709    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
710    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0);
711}
712static void
713nScriptForEachV(JNIEnv *_env, jobject _this, RsContext con,
714                jint script, jint slot, jint ain, jint aout, jbyteArray params)
715{
716    LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
717    jint len = _env->GetArrayLength(params);
718    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
719    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len);
720    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
721}
722
723
724// -----------------------------------
725
726static jint
727nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con,
728               jstring resName, jstring cacheDir,
729               jbyteArray scriptRef, jint length)
730{
731    LOG_API("nScriptCCreate, con(%p)", con);
732
733    AutoJavaStringToUTF8 resNameUTF(_env, resName);
734    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
735    jint ret = 0;
736    jbyte* script_ptr = NULL;
737    jint _exception = 0;
738    jint remaining;
739    if (!scriptRef) {
740        _exception = 1;
741        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
742        goto exit;
743    }
744    if (length < 0) {
745        _exception = 1;
746        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
747        goto exit;
748    }
749    remaining = _env->GetArrayLength(scriptRef);
750    if (remaining < length) {
751        _exception = 1;
752        //jniThrowException(_env, "java/lang/IllegalArgumentException",
753        //        "length > script.length - offset");
754        goto exit;
755    }
756    script_ptr = (jbyte *)
757        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
758
759    //rsScriptCSetText(con, (const char *)script_ptr, length);
760
761    ret = (jint)rsScriptCCreate(con,
762                                resNameUTF.c_str(), resNameUTF.length(),
763                                cacheDirUTF.c_str(), cacheDirUTF.length(),
764                                (const char *)script_ptr, length);
765
766exit:
767    if (script_ptr) {
768        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
769                _exception ? JNI_ABORT: 0);
770    }
771
772    return ret;
773}
774
775// ---------------------------------------------------------------------------
776
777static jint
778nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con, jint magFilter, jint minFilter,
779               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
780{
781    LOG_API("nSamplerCreate, con(%p)", con);
782    return (jint)rsSamplerCreate(con,
783                                 (RsSamplerValue)magFilter,
784                                 (RsSamplerValue)minFilter,
785                                 (RsSamplerValue)wrapS,
786                                 (RsSamplerValue)wrapT,
787                                 (RsSamplerValue)wrapR,
788                                 aniso);
789}
790
791// ---------------------------------------------------------------------------
792
793
794static const char *classPathName = "android/support/v8/renderscript/RenderScript";
795
796static JNINativeMethod methods[] = {
797{"_nInit",                         "()V",                                     (void*)_nInit },
798
799{"nDeviceCreate",                  "()I",                                     (void*)nDeviceCreate },
800{"nDeviceDestroy",                 "(I)V",                                    (void*)nDeviceDestroy },
801{"nDeviceSetConfig",               "(III)V",                                  (void*)nDeviceSetConfig },
802{"nContextGetUserMessage",         "(I[I)I",                                  (void*)nContextGetUserMessage },
803{"nContextGetErrorMessage",        "(I)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
804{"nContextPeekMessage",            "(I[I)I",                                  (void*)nContextPeekMessage },
805
806{"nContextInitToClient",           "(I)V",                                    (void*)nContextInitToClient },
807{"nContextDeinitToClient",         "(I)V",                                    (void*)nContextDeinitToClient },
808
809
810// All methods below are thread protected in java.
811{"rsnContextCreate",                 "(III)I",                                (void*)nContextCreate },
812{"rsnContextFinish",                 "(I)V",                                  (void*)nContextFinish },
813{"rsnContextSetPriority",            "(II)V",                                 (void*)nContextSetPriority },
814{"rsnContextDestroy",                "(I)V",                                  (void*)nContextDestroy },
815{"rsnContextDump",                   "(II)V",                                 (void*)nContextDump },
816{"rsnObjDestroy",                    "(II)V",                                 (void*)nObjDestroy },
817
818{"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
819{"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
820{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
821
822{"rsnTypeCreate",                    "(IIIIIZZ)I",                            (void*)nTypeCreate },
823
824{"rsnAllocationCreateTyped",         "(IIIII)I",                               (void*)nAllocationCreateTyped },
825{"rsnAllocationCreateFromBitmap",    "(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCreateFromBitmap },
826{"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I",      (void*)nAllocationCubeCreateFromBitmap },
827
828{"rsnAllocationCopyFromBitmap",      "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
829{"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
830
831{"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
832{"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
833{"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
834{"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
835{"rsnAllocationData1D",              "(IIIII[FI)V",                           (void*)nAllocationData1D_f },
836{"rsnAllocationElementData1D",       "(IIIII[BI)V",                           (void*)nAllocationElementData1D },
837{"rsnAllocationData2D",              "(IIIIIIII[II)V",                        (void*)nAllocationData2D_i },
838{"rsnAllocationData2D",              "(IIIIIIII[SI)V",                        (void*)nAllocationData2D_s },
839{"rsnAllocationData2D",              "(IIIIIIII[BI)V",                        (void*)nAllocationData2D_b },
840{"rsnAllocationData2D",              "(IIIIIIII[FI)V",                        (void*)nAllocationData2D_f },
841{"rsnAllocationData2D",              "(IIIIIIIIIIIII)V",                      (void*)nAllocationData2D_alloc },
842{"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
843{"rsnAllocationRead",                "(II[S)V",                               (void*)nAllocationRead_s },
844{"rsnAllocationRead",                "(II[B)V",                               (void*)nAllocationRead_b },
845{"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
846{"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
847{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
848{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
849{"rsnAllocationGenerateMipmaps",     "(II)V",                                 (void*)nAllocationGenerateMipmaps },
850
851{"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
852{"rsnScriptSetTimeZone",             "(II[B)V",                               (void*)nScriptSetTimeZone },
853{"rsnScriptInvoke",                  "(III)V",                                (void*)nScriptInvoke },
854{"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
855{"rsnScriptForEach",                 "(IIIII)V",                              (void*)nScriptForEach },
856{"rsnScriptForEach",                 "(IIIII[B)V",                            (void*)nScriptForEachV },
857{"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
858{"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
859{"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },
860{"rsnScriptSetVarD",                 "(IIID)V",                               (void*)nScriptSetVarD },
861{"rsnScriptSetVarV",                 "(III[B)V",                              (void*)nScriptSetVarV },
862{"rsnScriptSetVarVE",                "(III[BI[I)V",                           (void*)nScriptSetVarVE },
863{"rsnScriptSetVarObj",               "(IIII)V",                               (void*)nScriptSetVarObj },
864
865{"rsnScriptCCreate",                 "(ILjava/lang/String;Ljava/lang/String;[BI)I",  (void*)nScriptCCreate },
866
867{"rsnSamplerCreate",                 "(IIIIIIF)I",                            (void*)nSamplerCreate },
868
869};
870
871static int registerFuncs(JNIEnv *_env)
872{
873    return android::AndroidRuntime::registerNativeMethods(
874            _env, classPathName, methods, NELEM(methods));
875}
876
877// ---------------------------------------------------------------------------
878
879jint JNI_OnLoad(JavaVM* vm, void* reserved)
880{
881    JNIEnv* env = NULL;
882    jint result = -1;
883
884    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
885        ALOGE("ERROR: GetEnv failed\n");
886        goto bail;
887    }
888    assert(env != NULL);
889
890    if (registerFuncs(env) < 0) {
891        ALOGE("ERROR: MediaPlayer native registration failed\n");
892        goto bail;
893    }
894
895    /* success -- return valid version number */
896    result = JNI_VERSION_1_4;
897
898bail:
899    return result;
900}
901