android_renderscript_RenderScript.cpp revision 8c1509249c5552270d8accc2c9512f499a8f5e2d
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 "RenderScript_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 <inttypes.h>
26
27#include <androidfw/Asset.h>
28#include <androidfw/AssetManager.h>
29#include <androidfw/ResourceTypes.h>
30
31#include "jni.h"
32#include "JNIHelp.h"
33#include "android_runtime/AndroidRuntime.h"
34#include "android_runtime/android_view_Surface.h"
35#include "android_runtime/android_util_AssetManager.h"
36#include "android/graphics/GraphicsJNI.h"
37
38#include <rs.h>
39#include <rsEnv.h>
40#include <gui/Surface.h>
41#include <gui/GLConsumer.h>
42#include <android_runtime/android_graphics_SurfaceTexture.h>
43
44//#define LOG_API ALOGE
45static constexpr bool kLogApi = false;
46
47using namespace android;
48
49template <typename... T>
50void UNUSED(T... t) {}
51
52#define PER_ARRAY_TYPE(flag, fnc, readonly, ...) {                                      \
53    jint len = 0;                                                                       \
54    void *ptr = nullptr;                                                                \
55    void *srcPtr = nullptr;                                                             \
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        /* readonly = true, also indicates we are copying to the allocation   . */      \
61        relFlag = JNI_ABORT;                                                            \
62    }                                                                                   \
63    switch(dataType) {                                                                  \
64    case RS_TYPE_FLOAT_32:                                                              \
65        len = _env->GetArrayLength((jfloatArray)data);                                  \
66        ptr = _env->GetFloatArrayElements((jfloatArray)data, flag);                     \
67        if (ptr == nullptr) {                                                           \
68            ALOGE("Failed to get Java array elements.");                                \
69            return;                                                                     \
70        }                                                                               \
71        typeBytes = 4;                                                                  \
72        if (usePadding) {                                                               \
73            srcPtr = ptr;                                                               \
74            len = len / 3 * 4;                                                          \
75            if (count == 0) {                                                           \
76                count = len / 4;                                                        \
77            }                                                                           \
78            ptr = malloc (len * typeBytes);                                             \
79            if (readonly) {                                                             \
80                copyWithPadding(ptr, srcPtr, mSize, count);                             \
81                fnc(__VA_ARGS__);                                                       \
82            } else {                                                                    \
83                fnc(__VA_ARGS__);                                                       \
84                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
85            }                                                                           \
86            free(ptr);                                                                  \
87            ptr = srcPtr;                                                               \
88        } else {                                                                        \
89            fnc(__VA_ARGS__);                                                           \
90        }                                                                               \
91        _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag);     \
92        return;                                                                         \
93    case RS_TYPE_FLOAT_64:                                                              \
94        len = _env->GetArrayLength((jdoubleArray)data);                                 \
95        ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag);                   \
96        if (ptr == nullptr) {                                                           \
97            ALOGE("Failed to get Java array elements.");                                \
98            return;                                                                     \
99        }                                                                               \
100        typeBytes = 8;                                                                  \
101        if (usePadding) {                                                               \
102            srcPtr = ptr;                                                               \
103            len = len / 3 * 4;                                                          \
104            if (count == 0) {                                                           \
105                count = len / 4;                                                        \
106            }                                                                           \
107            ptr = malloc (len * typeBytes);                                             \
108            if (readonly) {                                                             \
109                copyWithPadding(ptr, srcPtr, mSize, count);                             \
110                fnc(__VA_ARGS__);                                                       \
111            } else {                                                                    \
112                fnc(__VA_ARGS__);                                                       \
113                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
114            }                                                                           \
115            free(ptr);                                                                  \
116            ptr = srcPtr;                                                               \
117        } else {                                                                        \
118            fnc(__VA_ARGS__);                                                           \
119        }                                                                               \
120        _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag);  \
121        return;                                                                         \
122    case RS_TYPE_SIGNED_8:                                                              \
123    case RS_TYPE_UNSIGNED_8:                                                            \
124        len = _env->GetArrayLength((jbyteArray)data);                                   \
125        ptr = _env->GetByteArrayElements((jbyteArray)data, flag);                       \
126        if (ptr == nullptr) {                                                           \
127            ALOGE("Failed to get Java array elements.");                                \
128            return;                                                                     \
129        }                                                                               \
130        typeBytes = 1;                                                                  \
131        if (usePadding) {                                                               \
132            srcPtr = ptr;                                                               \
133            len = len / 3 * 4;                                                          \
134            if (count == 0) {                                                           \
135                count = len / 4;                                                        \
136            }                                                                           \
137            ptr = malloc (len * typeBytes);                                             \
138            if (readonly) {                                                             \
139                copyWithPadding(ptr, srcPtr, mSize, count);                             \
140                fnc(__VA_ARGS__);                                                       \
141            } else {                                                                    \
142                fnc(__VA_ARGS__);                                                       \
143                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
144            }                                                                           \
145            free(ptr);                                                                  \
146            ptr = srcPtr;                                                               \
147        } else {                                                                        \
148            fnc(__VA_ARGS__);                                                           \
149        }                                                                               \
150        _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag);         \
151        return;                                                                         \
152    case RS_TYPE_SIGNED_16:                                                             \
153    case RS_TYPE_UNSIGNED_16:                                                           \
154        len = _env->GetArrayLength((jshortArray)data);                                  \
155        ptr = _env->GetShortArrayElements((jshortArray)data, flag);                     \
156        if (ptr == nullptr) {                                                           \
157            ALOGE("Failed to get Java array elements.");                                \
158            return;                                                                     \
159        }                                                                               \
160        typeBytes = 2;                                                                  \
161        if (usePadding) {                                                               \
162            srcPtr = ptr;                                                               \
163            len = len / 3 * 4;                                                          \
164            if (count == 0) {                                                           \
165                count = len / 4;                                                        \
166            }                                                                           \
167            ptr = malloc (len * typeBytes);                                             \
168            if (readonly) {                                                             \
169                copyWithPadding(ptr, srcPtr, mSize, count);                             \
170                fnc(__VA_ARGS__);                                                       \
171            } else {                                                                    \
172                fnc(__VA_ARGS__);                                                       \
173                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
174            }                                                                           \
175            free(ptr);                                                                  \
176            ptr = srcPtr;                                                               \
177        } else {                                                                        \
178            fnc(__VA_ARGS__);                                                           \
179        }                                                                               \
180        _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag);     \
181        return;                                                                         \
182    case RS_TYPE_SIGNED_32:                                                             \
183    case RS_TYPE_UNSIGNED_32:                                                           \
184        len = _env->GetArrayLength((jintArray)data);                                    \
185        ptr = _env->GetIntArrayElements((jintArray)data, flag);                         \
186        if (ptr == nullptr) {                                                           \
187            ALOGE("Failed to get Java array elements.");                                \
188            return;                                                                     \
189        }                                                                               \
190        typeBytes = 4;                                                                  \
191        if (usePadding) {                                                               \
192            srcPtr = ptr;                                                               \
193            len = len / 3 * 4;                                                          \
194            if (count == 0) {                                                           \
195                count = len / 4;                                                        \
196            }                                                                           \
197            ptr = malloc (len * typeBytes);                                             \
198            if (readonly) {                                                             \
199                copyWithPadding(ptr, srcPtr, mSize, count);                             \
200                fnc(__VA_ARGS__);                                                       \
201            } else {                                                                    \
202                fnc(__VA_ARGS__);                                                       \
203                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
204            }                                                                           \
205            free(ptr);                                                                  \
206            ptr = srcPtr;                                                               \
207        } else {                                                                        \
208            fnc(__VA_ARGS__);                                                           \
209        }                                                                               \
210        _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag);           \
211        return;                                                                         \
212    case RS_TYPE_SIGNED_64:                                                             \
213    case RS_TYPE_UNSIGNED_64:                                                           \
214        len = _env->GetArrayLength((jlongArray)data);                                   \
215        ptr = _env->GetLongArrayElements((jlongArray)data, flag);                       \
216        if (ptr == nullptr) {                                                           \
217            ALOGE("Failed to get Java array elements.");                                \
218            return;                                                                     \
219        }                                                                               \
220        typeBytes = 8;                                                                  \
221        if (usePadding) {                                                               \
222            srcPtr = ptr;                                                               \
223            len = len / 3 * 4;                                                          \
224            if (count == 0) {                                                           \
225                count = len / 4;                                                        \
226            }                                                                           \
227            ptr = malloc (len * typeBytes);                                             \
228            if (readonly) {                                                             \
229                copyWithPadding(ptr, srcPtr, mSize, count);                             \
230                fnc(__VA_ARGS__);                                                       \
231            } else {                                                                    \
232                fnc(__VA_ARGS__);                                                       \
233                copyWithUnPadding(srcPtr, ptr, mSize, count);                           \
234            }                                                                           \
235            free(ptr);                                                                  \
236            ptr = srcPtr;                                                               \
237        } else {                                                                        \
238            fnc(__VA_ARGS__);                                                           \
239        }                                                                               \
240        _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag);        \
241        return;                                                                         \
242    default:                                                                            \
243        break;                                                                          \
244    }                                                                                   \
245    UNUSED(len, ptr, srcPtr, typeBytes, relFlag);                                       \
246}
247
248
249class AutoJavaStringToUTF8 {
250public:
251    AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) {
252        fCStr = env->GetStringUTFChars(str, nullptr);
253        fLength = env->GetStringUTFLength(str);
254    }
255    ~AutoJavaStringToUTF8() {
256        fEnv->ReleaseStringUTFChars(fJStr, fCStr);
257    }
258    const char* c_str() const { return fCStr; }
259    jsize length() const { return fLength; }
260
261private:
262    JNIEnv*     fEnv;
263    jstring     fJStr;
264    const char* fCStr;
265    jsize       fLength;
266};
267
268class AutoJavaStringArrayToUTF8 {
269public:
270    AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength)
271    : mEnv(env), mStrings(strings), mStringsLength(stringsLength) {
272        mCStrings = nullptr;
273        mSizeArray = nullptr;
274        if (stringsLength > 0) {
275            mCStrings = (const char **)calloc(stringsLength, sizeof(char *));
276            mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t));
277            for (jsize ct = 0; ct < stringsLength; ct ++) {
278                jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
279                mCStrings[ct] = mEnv->GetStringUTFChars(s, nullptr);
280                mSizeArray[ct] = mEnv->GetStringUTFLength(s);
281            }
282        }
283    }
284    ~AutoJavaStringArrayToUTF8() {
285        for (jsize ct=0; ct < mStringsLength; ct++) {
286            jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct);
287            mEnv->ReleaseStringUTFChars(s, mCStrings[ct]);
288        }
289        free(mCStrings);
290        free(mSizeArray);
291    }
292    const char **c_str() const { return mCStrings; }
293    size_t *c_str_len() const { return mSizeArray; }
294    jsize length() const { return mStringsLength; }
295
296private:
297    JNIEnv      *mEnv;
298    jobjectArray mStrings;
299    const char **mCStrings;
300    size_t      *mSizeArray;
301    jsize        mStringsLength;
302};
303
304// ---------------------------------------------------------------------------
305
306static jfieldID gContextId = 0;
307
308static void _nInit(JNIEnv *_env, jclass _this)
309{
310    gContextId             = _env->GetFieldID(_this, "mContext", "J");
311}
312
313// ---------------------------------------------------------------------------
314
315static void copyWithPadding(void* ptr, void* srcPtr, int mSize, int count) {
316    int sizeBytesPad = mSize * 4;
317    int sizeBytes = mSize * 3;
318    uint8_t *dst = static_cast<uint8_t *>(ptr);
319    uint8_t *src = static_cast<uint8_t *>(srcPtr);
320    for (int i = 0; i < count; i++) {
321        memcpy(dst, src, sizeBytes);
322        dst += sizeBytesPad;
323        src += sizeBytes;
324    }
325}
326
327static void copyWithUnPadding(void* ptr, void* srcPtr, int mSize, int count) {
328    int sizeBytesPad = mSize * 4;
329    int sizeBytes = mSize * 3;
330    uint8_t *dst = static_cast<uint8_t *>(ptr);
331    uint8_t *src = static_cast<uint8_t *>(srcPtr);
332    for (int i = 0; i < count; i++) {
333        memcpy(dst, src, sizeBytes);
334        dst += sizeBytes;
335        src += sizeBytesPad;
336    }
337}
338
339
340// ---------------------------------------------------------------------------
341static void
342nContextFinish(JNIEnv *_env, jobject _this, jlong con)
343{
344    if (kLogApi) {
345        ALOGD("nContextFinish, con(%p)", (RsContext)con);
346    }
347    rsContextFinish((RsContext)con);
348}
349
350static jlong
351nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
352               jlong returnValue, jlongArray fieldIDArray,
353               jlongArray valueArray, jintArray sizeArray,
354               jlongArray depClosureArray, jlongArray depFieldIDArray) {
355  jlong ret = 0;
356
357  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
358  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
359  if (jFieldIDs == nullptr) {
360      ALOGE("Failed to get Java array elements: fieldIDs.");
361      return ret;
362  }
363
364  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
365  jsize values_length = _env->GetArrayLength(valueArray);
366  if (jValues == nullptr) {
367      ALOGE("Failed to get Java array elements: values.");
368      return ret;
369  }
370
371  jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
372  jsize sizes_length = _env->GetArrayLength(sizeArray);
373  if (jSizes == nullptr) {
374      ALOGE("Failed to get Java array elements: sizes.");
375      return ret;
376  }
377
378  jlong* jDepClosures =
379      _env->GetLongArrayElements(depClosureArray, nullptr);
380  jsize depClosures_length = _env->GetArrayLength(depClosureArray);
381  if (jDepClosures == nullptr) {
382      ALOGE("Failed to get Java array elements: depClosures.");
383      return ret;
384  }
385
386  jlong* jDepFieldIDs =
387      _env->GetLongArrayElements(depFieldIDArray, nullptr);
388  jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray);
389  if (jDepFieldIDs == nullptr) {
390      ALOGE("Failed to get Java array elements: depFieldIDs.");
391      return ret;
392  }
393
394  size_t numValues, numDependencies;
395  RsScriptFieldID* fieldIDs;
396  RsClosure* depClosures;
397  RsScriptFieldID* depFieldIDs;
398
399  if (fieldIDs_length != values_length || values_length != sizes_length) {
400      ALOGE("Unmatched field IDs, values, and sizes in closure creation.");
401      goto exit;
402  }
403
404  numValues = (size_t)fieldIDs_length;
405
406  if (depClosures_length != depFieldIDs_length) {
407      ALOGE("Unmatched closures and field IDs for dependencies in closure creation.");
408      goto exit;
409  }
410
411  numDependencies = (size_t)depClosures_length;
412
413  if (numDependencies > numValues) {
414      ALOGE("Unexpected number of dependencies in closure creation");
415      goto exit;
416  }
417
418  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
419      ALOGE("Too many arguments or globals in closure creation");
420      goto exit;
421  }
422
423  fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
424  if (fieldIDs == nullptr) {
425      goto exit;
426  }
427
428  for (size_t i = 0; i < numValues; i++) {
429    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
430  }
431
432  depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies);
433  if (depClosures == nullptr) {
434      goto exit;
435  }
436
437  for (size_t i = 0; i < numDependencies; i++) {
438    depClosures[i] = (RsClosure)jDepClosures[i];
439  }
440
441  depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies);
442  if (depFieldIDs == nullptr) {
443      goto exit;
444  }
445
446  for (size_t i = 0; i < numDependencies; i++) {
447    depFieldIDs[i] = (RsClosure)jDepFieldIDs[i];
448  }
449
450  ret = (jlong)(uintptr_t)rsClosureCreate(
451      (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue,
452      fieldIDs, numValues, jValues, numValues,
453      (int*)jSizes, numValues,
454      depClosures, numDependencies,
455      depFieldIDs, numDependencies);
456
457exit:
458
459  _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT);
460  _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT);
461  _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
462  _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
463  _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
464
465  return ret;
466}
467
468static jlong
469nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
470                     jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
471                     jintArray sizeArray) {
472  jlong ret = 0;
473
474  jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
475  jsize jParamLength = _env->GetArrayLength(paramArray);
476  if (jParams == nullptr) {
477      ALOGE("Failed to get Java array elements: params.");
478      return ret;
479  }
480
481  jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr);
482  jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray);
483  if (jFieldIDs == nullptr) {
484      ALOGE("Failed to get Java array elements: fieldIDs.");
485      return ret;
486  }
487
488  jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr);
489  jsize values_length = _env->GetArrayLength(valueArray);
490  if (jValues == nullptr) {
491      ALOGE("Failed to get Java array elements: values.");
492      return ret;
493  }
494
495  jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr);
496  jsize sizes_length = _env->GetArrayLength(sizeArray);
497  if (jSizes == nullptr) {
498      ALOGE("Failed to get Java array elements: sizes.");
499      return ret;
500  }
501
502  size_t numValues;
503  RsScriptFieldID* fieldIDs;
504
505  if (fieldIDs_length != values_length || values_length != sizes_length) {
506      ALOGE("Unmatched field IDs, values, and sizes in closure creation.");
507      goto exit;
508  }
509
510  numValues = (size_t) fieldIDs_length;
511
512  if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
513      ALOGE("Too many arguments or globals in closure creation");
514      goto exit;
515  }
516
517  fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues);
518  if (fieldIDs == nullptr) {
519      goto exit;
520  }
521
522  for (size_t i = 0; i< numValues; i++) {
523    fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i];
524  }
525
526  ret = (jlong)(uintptr_t)rsInvokeClosureCreate(
527      (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
528      fieldIDs, numValues, jValues, numValues,
529      (int*)jSizes, numValues);
530
531exit:
532
533  _env->ReleaseIntArrayElements (sizeArray,       jSizes,       JNI_ABORT);
534  _env->ReleaseLongArrayElements(valueArray,      jValues,      JNI_ABORT);
535  _env->ReleaseLongArrayElements(fieldIDArray,    jFieldIDs,    JNI_ABORT);
536  _env->ReleaseByteArrayElements(paramArray,      jParams,      JNI_ABORT);
537
538  return ret;
539}
540
541static void
542nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
543               jint index, jlong value, jint size) {
544  // Size is signed with -1 indicating the value is an Allocation
545  rsClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index,
546                  (uintptr_t)value, size);
547}
548
549static void
550nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
551                  jlong fieldID, jlong value, jint size) {
552  // Size is signed with -1 indicating the value is an Allocation
553  rsClosureSetGlobal((RsContext)con, (RsClosure)closureID,
554                     (RsScriptFieldID)fieldID, (int64_t)value, size);
555}
556
557static long
558nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name,
559                    jstring cacheDir, jlongArray closureArray) {
560  jlong ret = 0;
561
562  AutoJavaStringToUTF8 nameUTF(_env, name);
563  AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
564
565  jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr);
566  jsize numClosures = _env->GetArrayLength(closureArray);
567  if (jClosures == nullptr) {
568      ALOGE("Failed to get Java array elements: closures.");
569      return ret;
570  }
571
572  RsClosure* closures;
573
574  if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
575    ALOGE("Too many closures in script group");
576    goto exit;
577  }
578
579  closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures);
580  if (closures == nullptr) {
581      goto exit;
582  }
583
584  for (int i = 0; i < numClosures; i++) {
585    closures[i] = (RsClosure)jClosures[i];
586  }
587
588  ret = (jlong)(uintptr_t)rsScriptGroup2Create(
589      (RsContext)con, nameUTF.c_str(), nameUTF.length(),
590      cacheDirUTF.c_str(), cacheDirUTF.length(),
591      closures, numClosures);
592
593exit:
594
595  _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT);
596
597  return ret;
598}
599
600static void
601nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) {
602  rsScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID);
603}
604
605static void
606nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
607                            jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
608                            jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY,
609                            jint KL, jint KU) {
610    RsBlasCall call;
611    memset(&call, 0, sizeof(call));
612    call.func = (RsBlasFunction)func;
613    call.transA = (RsBlasTranspose)TransA;
614    call.transB = (RsBlasTranspose)TransB;
615    call.side = (RsBlasSide)Side;
616    call.uplo = (RsBlasUplo)Uplo;
617    call.diag = (RsBlasDiag)Diag;
618    call.M = M;
619    call.N = N;
620    call.K = K;
621    call.alpha.f = alpha;
622    call.beta.f = beta;
623    call.incX = incX;
624    call.incY = incY;
625    call.KL = KL;
626    call.KU = KU;
627
628    RsAllocation in_allocs[3];
629    in_allocs[0] = (RsAllocation)A;
630    in_allocs[1] = (RsAllocation)B;
631    in_allocs[2] = (RsAllocation)C;
632
633    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
634                         in_allocs, sizeof(in_allocs), nullptr,
635                         &call, sizeof(call), nullptr, 0);
636}
637
638static void
639nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
640                            jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
641                            jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY,
642                            jint KL, jint KU) {
643    RsBlasCall call;
644    memset(&call, 0, sizeof(call));
645    call.func = (RsBlasFunction)func;
646    call.transA = (RsBlasTranspose)TransA;
647    call.transB = (RsBlasTranspose)TransB;
648    call.side = (RsBlasSide)Side;
649    call.uplo = (RsBlasUplo)Uplo;
650    call.diag = (RsBlasDiag)Diag;
651    call.M = M;
652    call.N = N;
653    call.K = K;
654    call.alpha.d = alpha;
655    call.beta.d = beta;
656    call.incX = incX;
657    call.incY = incY;
658    call.KL = KL;
659    call.KU = KU;
660
661    RsAllocation in_allocs[3];
662    in_allocs[0] = (RsAllocation)A;
663    in_allocs[1] = (RsAllocation)B;
664    in_allocs[2] = (RsAllocation)C;
665
666    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
667                         in_allocs, NELEM(in_allocs), nullptr,
668                         &call, sizeof(call), nullptr, 0);
669}
670
671static void
672nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
673                             jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
674                             jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX,
675                             jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU) {
676    RsBlasCall call;
677    memset(&call, 0, sizeof(call));
678    call.func = (RsBlasFunction)func;
679    call.transA = (RsBlasTranspose)TransA;
680    call.transB = (RsBlasTranspose)TransB;
681    call.side = (RsBlasSide)Side;
682    call.uplo = (RsBlasUplo)Uplo;
683    call.diag = (RsBlasDiag)Diag;
684    call.M = M;
685    call.N = N;
686    call.K = K;
687    call.alpha.c.r = alphaX;
688    call.alpha.c.i = alphaY;
689    call.beta.c.r = betaX;
690    call.beta.c.i = betaY;
691    call.incX = incX;
692    call.incY = incY;
693    call.KL = KL;
694    call.KU = KU;
695
696    RsAllocation in_allocs[3];
697    in_allocs[0] = (RsAllocation)A;
698    in_allocs[1] = (RsAllocation)B;
699    in_allocs[2] = (RsAllocation)C;
700
701    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
702                         in_allocs, NELEM(in_allocs), nullptr,
703                         &call, sizeof(call), nullptr, 0);
704}
705
706static void
707nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA,
708                       jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K,
709                       jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX,
710                       jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU) {
711    RsBlasCall call;
712    memset(&call, 0, sizeof(call));
713    call.func = (RsBlasFunction)func;
714    call.transA = (RsBlasTranspose)TransA;
715    call.transB = (RsBlasTranspose)TransB;
716    call.side = (RsBlasSide)Side;
717    call.uplo = (RsBlasUplo)Uplo;
718    call.diag = (RsBlasDiag)Diag;
719    call.M = M;
720    call.N = N;
721    call.K = K;
722    call.alpha.z.r = alphaX;
723    call.alpha.z.i = alphaY;
724    call.beta.z.r = betaX;
725    call.beta.z.i = betaY;
726    call.incX = incX;
727    call.incY = incY;
728    call.KL = KL;
729    call.KU = KU;
730
731    RsAllocation in_allocs[3];
732    in_allocs[0] = (RsAllocation)A;
733    in_allocs[1] = (RsAllocation)B;
734    in_allocs[2] = (RsAllocation)C;
735
736    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
737                         in_allocs, NELEM(in_allocs), nullptr,
738                         &call, sizeof(call), nullptr, 0);
739}
740
741
742static void
743nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong id, jint M, jint N, jint K,
744                                             jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset,
745                                             jint c_mult_int) {
746    RsBlasCall call;
747    memset(&call, 0, sizeof(call));
748    call.func = RsBlas_bnnm;
749    call.M = M;
750    call.N = N;
751    call.K = K;
752    call.a_offset = a_offset & 0xFF;
753    call.b_offset = b_offset & 0xFF;
754    call.c_offset = c_offset;
755    call.c_mult_int = c_mult_int;
756
757    RsAllocation in_allocs[3];
758    in_allocs[0] = (RsAllocation)A;
759    in_allocs[1] = (RsAllocation)B;
760    in_allocs[2] = (RsAllocation)C;
761
762    rsScriptForEachMulti((RsContext)con, (RsScript)id, 0,
763                         in_allocs, NELEM(in_allocs), nullptr,
764                         &call, sizeof(call), nullptr, 0);
765}
766
767
768static void
769nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str)
770{
771    if (kLogApi) {
772        ALOGD("nAssignName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
773    }
774    jint len = _env->GetArrayLength(str);
775    jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
776    if (cptr == nullptr) {
777        ALOGE("Failed to get Java array elements");
778        return;
779    }
780
781    rsAssignName((RsContext)con, (void *)obj, (const char *)cptr, len);
782    _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
783}
784
785static jstring
786nGetName(JNIEnv *_env, jobject _this, jlong con, jlong obj)
787{
788    if (kLogApi) {
789        ALOGD("nGetName, con(%p), obj(%p)", (RsContext)con, (void *)obj);
790    }
791    const char *name = nullptr;
792    rsaGetName((RsContext)con, (void *)obj, &name);
793    if(name == nullptr || strlen(name) == 0) {
794        return nullptr;
795    }
796    return _env->NewStringUTF(name);
797}
798
799static void
800nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj)
801{
802    if (kLogApi) {
803        ALOGD("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj);
804    }
805    rsObjDestroy((RsContext)con, (void *)obj);
806}
807
808// ---------------------------------------------------------------------------
809
810static jlong
811nDeviceCreate(JNIEnv *_env, jobject _this)
812{
813    if (kLogApi) {
814        ALOGD("nDeviceCreate");
815    }
816    return (jlong)(uintptr_t)rsDeviceCreate();
817}
818
819static void
820nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev)
821{
822    if (kLogApi) {
823        ALOGD("nDeviceDestroy");
824    }
825    return rsDeviceDestroy((RsDevice)dev);
826}
827
828static void
829nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value)
830{
831    if (kLogApi) {
832        ALOGD("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
833    }
834    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
835}
836
837static jlong
838nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint flags, jint sdkVer, jint contextType)
839{
840    if (kLogApi) {
841        ALOGD("nContextCreate");
842    }
843    return (jlong)(uintptr_t)rsContextCreate((RsDevice)dev, 0, sdkVer, (RsContextType)contextType, flags);
844}
845
846static jlong
847nContextCreateGL(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer,
848                 jint colorMin, jint colorPref,
849                 jint alphaMin, jint alphaPref,
850                 jint depthMin, jint depthPref,
851                 jint stencilMin, jint stencilPref,
852                 jint samplesMin, jint samplesPref, jfloat samplesQ,
853                 jint dpi)
854{
855    RsSurfaceConfig sc;
856    sc.alphaMin = alphaMin;
857    sc.alphaPref = alphaPref;
858    sc.colorMin = colorMin;
859    sc.colorPref = colorPref;
860    sc.depthMin = depthMin;
861    sc.depthPref = depthPref;
862    sc.samplesMin = samplesMin;
863    sc.samplesPref = samplesPref;
864    sc.samplesQ = samplesQ;
865
866    if (kLogApi) {
867        ALOGD("nContextCreateGL");
868    }
869    return (jlong)(uintptr_t)rsContextCreateGL((RsDevice)dev, ver, sdkVer, sc, dpi);
870}
871
872static void
873nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p)
874{
875    if (kLogApi) {
876        ALOGD("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p);
877    }
878    rsContextSetPriority((RsContext)con, p);
879}
880
881static void
882nContextSetCacheDir(JNIEnv *_env, jobject _this, jlong con, jstring cacheDir)
883{
884    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
885
886    if (kLogApi) {
887        ALOGD("ContextSetCacheDir, con(%p), cacheDir(%s)", (RsContext)con, cacheDirUTF.c_str());
888    }
889    rsContextSetCacheDir((RsContext)con, cacheDirUTF.c_str(), cacheDirUTF.length());
890}
891
892
893
894static void
895nContextSetSurface(JNIEnv *_env, jobject _this, jlong con, jint width, jint height, jobject wnd)
896{
897    if (kLogApi) {
898        ALOGD("nContextSetSurface, con(%p), width(%i), height(%i), surface(%p)", (RsContext)con,
899              width, height, (Surface *)wnd);
900    }
901
902    ANativeWindow * window = nullptr;
903    if (wnd == nullptr) {
904
905    } else {
906        window = android_view_Surface_getNativeWindow(_env, wnd).get();
907    }
908
909    rsContextSetSurface((RsContext)con, width, height, window);
910}
911
912static void
913nContextDestroy(JNIEnv *_env, jobject _this, jlong con)
914{
915    if (kLogApi) {
916        ALOGD("nContextDestroy, con(%p)", (RsContext)con);
917    }
918    rsContextDestroy((RsContext)con);
919}
920
921static void
922nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits)
923{
924    if (kLogApi) {
925        ALOGD("nContextDump, con(%p)  bits(%i)", (RsContext)con, bits);
926    }
927    rsContextDump((RsContext)con, bits);
928}
929
930static void
931nContextPause(JNIEnv *_env, jobject _this, jlong con)
932{
933    if (kLogApi) {
934        ALOGD("nContextPause, con(%p)", (RsContext)con);
935    }
936    rsContextPause((RsContext)con);
937}
938
939static void
940nContextResume(JNIEnv *_env, jobject _this, jlong con)
941{
942    if (kLogApi) {
943        ALOGD("nContextResume, con(%p)", (RsContext)con);
944    }
945    rsContextResume((RsContext)con);
946}
947
948
949static jstring
950nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con)
951{
952    if (kLogApi) {
953        ALOGD("nContextGetErrorMessage, con(%p)", (RsContext)con);
954    }
955    char buf[1024];
956
957    size_t receiveLen;
958    uint32_t subID;
959    int id = rsContextGetMessage((RsContext)con,
960                                 buf, sizeof(buf),
961                                 &receiveLen, sizeof(receiveLen),
962                                 &subID, sizeof(subID));
963    if (!id && receiveLen) {
964        ALOGV("message receive buffer too small.  %zu", receiveLen);
965    }
966    return _env->NewStringUTF(buf);
967}
968
969static jint
970nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data)
971{
972    jint len = _env->GetArrayLength(data);
973    if (kLogApi) {
974        ALOGD("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len);
975    }
976    jint *ptr = _env->GetIntArrayElements(data, nullptr);
977    if (ptr == nullptr) {
978        ALOGE("Failed to get Java array elements");
979        return 0;
980    }
981    size_t receiveLen;
982    uint32_t subID;
983    int id = rsContextGetMessage((RsContext)con,
984                                 ptr, len * 4,
985                                 &receiveLen, sizeof(receiveLen),
986                                 &subID, sizeof(subID));
987    if (!id && receiveLen) {
988        ALOGV("message receive buffer too small.  %zu", receiveLen);
989    }
990    _env->ReleaseIntArrayElements(data, ptr, 0);
991    return (jint)id;
992}
993
994static jint
995nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData)
996{
997    if (kLogApi) {
998        ALOGD("nContextPeekMessage, con(%p)", (RsContext)con);
999    }
1000    jint *auxDataPtr = _env->GetIntArrayElements(auxData, nullptr);
1001    if (auxDataPtr == nullptr) {
1002        ALOGE("Failed to get Java array elements");
1003        return 0;
1004    }
1005    size_t receiveLen;
1006    uint32_t subID;
1007    int id = rsContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen),
1008                                  &subID, sizeof(subID));
1009    auxDataPtr[0] = (jint)subID;
1010    auxDataPtr[1] = (jint)receiveLen;
1011    _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0);
1012    return (jint)id;
1013}
1014
1015static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con)
1016{
1017    if (kLogApi) {
1018        ALOGD("nContextInitToClient, con(%p)", (RsContext)con);
1019    }
1020    rsContextInitToClient((RsContext)con);
1021}
1022
1023static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con)
1024{
1025    if (kLogApi) {
1026        ALOGD("nContextDeinitToClient, con(%p)", (RsContext)con);
1027    }
1028    rsContextDeinitToClient((RsContext)con);
1029}
1030
1031static void
1032nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data)
1033{
1034    jint *ptr = nullptr;
1035    jint len = 0;
1036    if (data) {
1037        len = _env->GetArrayLength(data);
1038        ptr = _env->GetIntArrayElements(data, nullptr);
1039        if (ptr == nullptr) {
1040            ALOGE("Failed to get Java array elements");
1041            return;
1042        }
1043    }
1044    if (kLogApi) {
1045        ALOGD("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
1046    }
1047    rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
1048    if (data) {
1049        _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
1050    }
1051}
1052
1053
1054
1055static jlong
1056nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm,
1057               jint size)
1058{
1059    if (kLogApi) {
1060        ALOGD("nElementCreate, con(%p), type(%" PRId64 "), kind(%i), norm(%i), size(%i)", (RsContext)con,
1061              type, kind, norm, size);
1062    }
1063    return (jlong)(uintptr_t)rsElementCreate((RsContext)con, (RsDataType)type, (RsDataKind)kind,
1064                                             norm, size);
1065}
1066
1067static jlong
1068nElementCreate2(JNIEnv *_env, jobject _this, jlong con,
1069                jlongArray _ids, jobjectArray _names, jintArray _arraySizes)
1070{
1071    int fieldCount = _env->GetArrayLength(_ids);
1072    if (kLogApi) {
1073        ALOGD("nElementCreate2, con(%p)", (RsContext)con);
1074    }
1075
1076    jlong *jIds = _env->GetLongArrayElements(_ids, nullptr);
1077    if (jIds == nullptr) {
1078        ALOGE("Failed to get Java array elements: ids");
1079        return 0;
1080    }
1081    jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, nullptr);
1082    if (jArraySizes == nullptr) {
1083        ALOGE("Failed to get Java array elements: arraySizes");
1084        return 0;
1085    }
1086
1087    RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement));
1088    uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t));
1089
1090    for(int i = 0; i < fieldCount; i ++) {
1091        ids[i] = (RsElement)jIds[i];
1092        arraySizes[i] = (uint32_t)jArraySizes[i];
1093    }
1094
1095    AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount);
1096
1097    const char **nameArray = names.c_str();
1098    size_t *sizeArray = names.c_str_len();
1099
1100    jlong id = (jlong)(uintptr_t)rsElementCreate2((RsContext)con,
1101                                     (const RsElement *)ids, fieldCount,
1102                                     nameArray, fieldCount * sizeof(size_t),  sizeArray,
1103                                     (const uint32_t *)arraySizes, fieldCount);
1104
1105    free(ids);
1106    free(arraySizes);
1107    _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT);
1108    _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT);
1109
1110    return (jlong)(uintptr_t)id;
1111}
1112
1113static void
1114nElementGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jintArray _elementData)
1115{
1116    int dataSize = _env->GetArrayLength(_elementData);
1117    if (kLogApi) {
1118        ALOGD("nElementGetNativeData, con(%p)", (RsContext)con);
1119    }
1120
1121    // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
1122    assert(dataSize == 5);
1123
1124    uintptr_t elementData[5];
1125    rsaElementGetNativeData((RsContext)con, (RsElement)id, elementData, dataSize);
1126
1127    for(jint i = 0; i < dataSize; i ++) {
1128        const jint data = (jint)elementData[i];
1129        _env->SetIntArrayRegion(_elementData, i, 1, &data);
1130    }
1131}
1132
1133
1134static void
1135nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id,
1136                       jlongArray _IDs,
1137                       jobjectArray _names,
1138                       jintArray _arraySizes)
1139{
1140    uint32_t dataSize = _env->GetArrayLength(_IDs);
1141    if (kLogApi) {
1142        ALOGD("nElementGetSubElements, con(%p)", (RsContext)con);
1143    }
1144
1145    uintptr_t *ids = (uintptr_t*)malloc(dataSize * sizeof(uintptr_t));
1146    const char **names = (const char **)malloc(dataSize * sizeof(const char *));
1147    uint32_t *arraySizes = (uint32_t *)malloc(dataSize * sizeof(uint32_t));
1148
1149    rsaElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes,
1150                             (uint32_t)dataSize);
1151
1152    for(uint32_t i = 0; i < dataSize; i++) {
1153        const jlong id = (jlong)(uintptr_t)ids[i];
1154        const jint arraySize = (jint)arraySizes[i];
1155        _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
1156        _env->SetLongArrayRegion(_IDs, i, 1, &id);
1157        _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize);
1158    }
1159
1160    free(ids);
1161    free(names);
1162    free(arraySizes);
1163}
1164
1165// -----------------------------------
1166
1167static jlong
1168nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid,
1169            jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv)
1170{
1171    if (kLogApi) {
1172        ALOGD("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)",
1173              (RsContext)con, (void*)eid, dimx, dimy, dimz, mips, faces, yuv);
1174    }
1175
1176    return (jlong)(uintptr_t)rsTypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, dimz, mips,
1177                                          faces, yuv);
1178}
1179
1180static void
1181nTypeGetNativeData(JNIEnv *_env, jobject _this, jlong con, jlong id, jlongArray _typeData)
1182{
1183    // We are packing 6 items: mDimX; mDimY; mDimZ;
1184    // mDimLOD; mDimFaces; mElement; into typeData
1185    int elementCount = _env->GetArrayLength(_typeData);
1186
1187    assert(elementCount == 6);
1188    if (kLogApi) {
1189        ALOGD("nTypeGetNativeData, con(%p)", (RsContext)con);
1190    }
1191
1192    uintptr_t typeData[6];
1193    rsaTypeGetNativeData((RsContext)con, (RsType)id, typeData, 6);
1194
1195    for(jint i = 0; i < elementCount; i ++) {
1196        const jlong data = (jlong)(uintptr_t)typeData[i];
1197        _env->SetLongArrayRegion(_typeData, i, 1, &data);
1198    }
1199}
1200
1201// -----------------------------------
1202
1203static jlong
1204nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage,
1205                       jlong pointer)
1206{
1207    if (kLogApi) {
1208        ALOGD("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)",
1209              (RsContext)con, (RsElement)type, mips, usage, (void *)pointer);
1210    }
1211    return (jlong)(uintptr_t) rsAllocationCreateTyped((RsContext)con, (RsType)type,
1212                                                      (RsAllocationMipmapControl)mips,
1213                                                      (uint32_t)usage, (uintptr_t)pointer);
1214}
1215
1216static void
1217nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits)
1218{
1219    if (kLogApi) {
1220        ALOGD("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a,
1221              bits);
1222    }
1223    rsAllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits);
1224}
1225
1226static void
1227nAllocationSetupBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint numAlloc)
1228{
1229    if (kLogApi) {
1230        ALOGD("nAllocationSetupBufferQueue, con(%p), alloc(%p), numAlloc(%d)", (RsContext)con,
1231              (RsAllocation)alloc, numAlloc);
1232    }
1233    rsAllocationSetupBufferQueue((RsContext)con, (RsAllocation)alloc, (uint32_t)numAlloc);
1234}
1235
1236static void
1237nAllocationShareBufferQueue(JNIEnv *_env, jobject _this, jlong con, jlong alloc1, jlong alloc2)
1238{
1239    if (kLogApi) {
1240        ALOGD("nAllocationShareBufferQueue, con(%p), alloc1(%p), alloc2(%p)", (RsContext)con,
1241              (RsAllocation)alloc1, (RsAllocation)alloc2);
1242    }
1243
1244    rsAllocationShareBufferQueue((RsContext)con, (RsAllocation)alloc1, (RsAllocation)alloc2);
1245}
1246
1247static jobject
1248nAllocationGetSurface(JNIEnv *_env, jobject _this, jlong con, jlong a)
1249{
1250    if (kLogApi) {
1251        ALOGD("nAllocationGetSurface, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1252    }
1253
1254    IGraphicBufferProducer *v = (IGraphicBufferProducer *)rsAllocationGetSurface((RsContext)con,
1255                                                                                 (RsAllocation)a);
1256    sp<IGraphicBufferProducer> bp = v;
1257    v->decStrong(nullptr);
1258
1259    jobject o = android_view_Surface_createFromIGraphicBufferProducer(_env, bp);
1260    return o;
1261}
1262
1263static void
1264nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur)
1265{
1266    if (kLogApi) {
1267        ALOGD("nAllocationSetSurface, con(%p), alloc(%p), surface(%p)", (RsContext)con,
1268              (RsAllocation)alloc, (Surface *)sur);
1269    }
1270
1271    sp<Surface> s;
1272    if (sur != 0) {
1273        s = android_view_Surface_getSurface(_env, sur);
1274    }
1275
1276    rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc,
1277                           static_cast<ANativeWindow *>(s.get()));
1278}
1279
1280static void
1281nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1282{
1283    if (kLogApi) {
1284        ALOGD("nAllocationIoSend, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1285    }
1286    rsAllocationIoSend((RsContext)con, (RsAllocation)alloc);
1287}
1288
1289static jlong
1290nAllocationIoReceive(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1291{
1292    if (kLogApi) {
1293        ALOGD("nAllocationIoReceive, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1294    }
1295    return (jlong) rsAllocationIoReceive((RsContext)con, (RsAllocation)alloc);
1296}
1297
1298static void
1299nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc)
1300{
1301    if (kLogApi) {
1302        ALOGD("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc);
1303    }
1304    rsAllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc);
1305}
1306
1307static jlong
1308nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
1309                            jobject jbitmap, jint usage)
1310{
1311    SkBitmap bitmap;
1312    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1313
1314    bitmap.lockPixels();
1315    const void* ptr = bitmap.getPixels();
1316    jlong id = (jlong)(uintptr_t)rsAllocationCreateFromBitmap((RsContext)con,
1317                                                  (RsType)type, (RsAllocationMipmapControl)mip,
1318                                                  ptr, bitmap.getSize(), usage);
1319    bitmap.unlockPixels();
1320    return id;
1321}
1322
1323static jlong
1324nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type,
1325                                        jint mip, jobject jbitmap, jint usage)
1326{
1327    SkBitmap bitmap;
1328    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1329
1330    bitmap.lockPixels();
1331    const void* ptr = bitmap.getPixels();
1332    jlong id = (jlong)(uintptr_t)rsAllocationCreateTyped((RsContext)con,
1333                                            (RsType)type, (RsAllocationMipmapControl)mip,
1334                                            (uint32_t)usage, (uintptr_t)ptr);
1335    bitmap.unlockPixels();
1336    return id;
1337}
1338
1339static jlong
1340nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip,
1341                                jobject jbitmap, jint usage)
1342{
1343    SkBitmap bitmap;
1344    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1345
1346    bitmap.lockPixels();
1347    const void* ptr = bitmap.getPixels();
1348    jlong id = (jlong)(uintptr_t)rsAllocationCubeCreateFromBitmap((RsContext)con,
1349                                                      (RsType)type, (RsAllocationMipmapControl)mip,
1350                                                      ptr, bitmap.getSize(), usage);
1351    bitmap.unlockPixels();
1352    return id;
1353}
1354
1355static void
1356nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1357{
1358    SkBitmap bitmap;
1359    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1360    int w = bitmap.width();
1361    int h = bitmap.height();
1362
1363    bitmap.lockPixels();
1364    const void* ptr = bitmap.getPixels();
1365    rsAllocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0,
1366                       0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
1367                       w, h, ptr, bitmap.getSize(), 0);
1368    bitmap.unlockPixels();
1369}
1370
1371static void
1372nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap)
1373{
1374    SkBitmap bitmap;
1375    GraphicsJNI::getSkBitmap(_env, jbitmap, &bitmap);
1376
1377    bitmap.lockPixels();
1378    void* ptr = bitmap.getPixels();
1379    rsAllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, ptr, bitmap.getSize());
1380    bitmap.unlockPixels();
1381    bitmap.notifyPixelsChanged();
1382}
1383
1384// Copies from the Java object data into the Allocation pointed to by _alloc.
1385static void
1386nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1387                  jint count, jobject data, jint sizeBytes, jint dataType, jint mSize,
1388                  jboolean usePadding)
1389{
1390    RsAllocation *alloc = (RsAllocation *)_alloc;
1391    if (kLogApi) {
1392        ALOGD("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1393              "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes,
1394              dataType);
1395    }
1396    PER_ARRAY_TYPE(nullptr, rsAllocation1DData, true,
1397                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1398}
1399
1400static void
1401nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1402                       jint xoff, jint yoff, jint zoff,
1403                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1404{
1405    jint len = _env->GetArrayLength(data);
1406    if (kLogApi) {
1407        ALOGD("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1408              "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1409              sizeBytes);
1410    }
1411    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1412    if (ptr == nullptr) {
1413        ALOGE("Failed to get Java array elements");
1414        return;
1415    }
1416    rsAllocationElementData((RsContext)con, (RsAllocation)alloc,
1417                            xoff, yoff, zoff,
1418                            lod, ptr, sizeBytes, compIdx);
1419    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1420}
1421
1422
1423// Copies from the Java object data into the Allocation pointed to by _alloc.
1424static void
1425nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1426                  jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize,
1427                  jboolean usePadding)
1428{
1429    RsAllocation *alloc = (RsAllocation *)_alloc;
1430    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1431    if (kLogApi) {
1432        ALOGD("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1433              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1434    }
1435    int count = w * h;
1436    PER_ARRAY_TYPE(nullptr, rsAllocation2DData, true,
1437                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1438}
1439
1440// Copies from the Allocation pointed to by srcAlloc into the Allocation
1441// pointed to by dstAlloc.
1442static void
1443nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con,
1444                        jlong dstAlloc, jint dstXoff, jint dstYoff,
1445                        jint dstMip, jint dstFace,
1446                        jint width, jint height,
1447                        jlong srcAlloc, jint srcXoff, jint srcYoff,
1448                        jint srcMip, jint srcFace)
1449{
1450    if (kLogApi) {
1451        ALOGD("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1452              " dstMip(%i), dstFace(%i), width(%i), height(%i),"
1453              " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)",
1454              (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
1455              width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
1456    }
1457
1458    rsAllocationCopy2DRange((RsContext)con,
1459                            (RsAllocation)dstAlloc,
1460                            dstXoff, dstYoff,
1461                            dstMip, dstFace,
1462                            width, height,
1463                            (RsAllocation)srcAlloc,
1464                            srcXoff, srcYoff,
1465                            srcMip, srcFace);
1466}
1467
1468// Copies from the Java object data into the Allocation pointed to by _alloc.
1469static void
1470nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1471                  jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType,
1472                  jint mSize, jboolean usePadding)
1473{
1474    RsAllocation *alloc = (RsAllocation *)_alloc;
1475    if (kLogApi) {
1476        ALOGD("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1477              " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1478              lod, w, h, d, sizeBytes);
1479    }
1480    int count = w * h * d;
1481    PER_ARRAY_TYPE(nullptr, rsAllocation3DData, true,
1482                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1483}
1484
1485// Copies from the Allocation pointed to by srcAlloc into the Allocation
1486// pointed to by dstAlloc.
1487static void
1488nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con,
1489                        jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
1490                        jint dstMip,
1491                        jint width, jint height, jint depth,
1492                        jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
1493                        jint srcMip)
1494{
1495    if (kLogApi) {
1496        ALOGD("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
1497              " dstMip(%i), width(%i), height(%i),"
1498              " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
1499              (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip,
1500              width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip);
1501    }
1502
1503    rsAllocationCopy3DRange((RsContext)con,
1504                            (RsAllocation)dstAlloc,
1505                            dstXoff, dstYoff, dstZoff, dstMip,
1506                            width, height, depth,
1507                            (RsAllocation)srcAlloc,
1508                            srcXoff, srcYoff, srcZoff, srcMip);
1509}
1510
1511
1512// Copies from the Allocation pointed to by _alloc into the Java object data.
1513static void
1514nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType,
1515                jint mSize, jboolean usePadding)
1516{
1517    RsAllocation *alloc = (RsAllocation *)_alloc;
1518    if (kLogApi) {
1519        ALOGD("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
1520    }
1521    int count = 0;
1522    PER_ARRAY_TYPE(0, rsAllocationRead, false,
1523                   (RsContext)con, alloc, ptr, len * typeBytes);
1524}
1525
1526// Copies from the Allocation pointed to by _alloc into the Java object data.
1527static void
1528nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod,
1529                  jint count, jobject data, jint sizeBytes, jint dataType,
1530                  jint mSize, jboolean usePadding)
1531{
1532    RsAllocation *alloc = (RsAllocation *)_alloc;
1533    if (kLogApi) {
1534        ALOGD("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), "
1535              "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType);
1536    }
1537    PER_ARRAY_TYPE(0, rsAllocation1DRead, false,
1538                   (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes);
1539}
1540
1541// Copies from the Element in the Allocation pointed to by _alloc into the Java array data.
1542static void
1543nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1544                       jint xoff, jint yoff, jint zoff,
1545                       jint lod, jint compIdx, jbyteArray data, jint sizeBytes)
1546{
1547    jint len = _env->GetArrayLength(data);
1548    if (kLogApi) {
1549        ALOGD("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), "
1550              "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len,
1551              sizeBytes);
1552    }
1553    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1554    if (ptr == nullptr) {
1555        ALOGE("Failed to get Java array elements");
1556        return;
1557    }
1558    rsAllocationElementRead((RsContext)con, (RsAllocation)alloc,
1559                            xoff, yoff, zoff,
1560                            lod, ptr, sizeBytes, compIdx);
1561    _env->ReleaseByteArrayElements(data, ptr, 0);
1562}
1563
1564// Copies from the Allocation pointed to by _alloc into the Java object data.
1565static void
1566nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face,
1567                  jint w, jint h, jobject data, jint sizeBytes, jint dataType,
1568                  jint mSize, jboolean usePadding)
1569{
1570    RsAllocation *alloc = (RsAllocation *)_alloc;
1571    RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face;
1572    if (kLogApi) {
1573        ALOGD("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) "
1574              "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType);
1575    }
1576    int count = w * h;
1577    PER_ARRAY_TYPE(0, rsAllocation2DRead, false,
1578                   (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0);
1579}
1580
1581// Copies from the Allocation pointed to by _alloc into the Java object data.
1582static void
1583nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod,
1584                  jint w, jint h, jint d, jobject data, int sizeBytes, int dataType,
1585                  jint mSize, jboolean usePadding)
1586{
1587    RsAllocation *alloc = (RsAllocation *)_alloc;
1588    if (kLogApi) {
1589        ALOGD("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i),"
1590              " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff,
1591              lod, w, h, d, sizeBytes);
1592    }
1593    int count = w * h * d;
1594    PER_ARRAY_TYPE(nullptr, rsAllocation3DRead, false,
1595                   (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
1596}
1597
1598static jlong
1599nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a)
1600{
1601    if (kLogApi) {
1602        ALOGD("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a);
1603    }
1604    return (jlong)(uintptr_t) rsaAllocationGetType((RsContext)con, (RsAllocation)a);
1605}
1606
1607static void
1608nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX)
1609{
1610    if (kLogApi) {
1611        ALOGD("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con,
1612              (RsAllocation)alloc, dimX);
1613    }
1614    rsAllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX);
1615}
1616
1617
1618static jlong
1619nAllocationAdapterCreate(JNIEnv *_env, jobject _this, jlong con, jlong basealloc, jlong type)
1620{
1621    if (kLogApi) {
1622        ALOGD("nAllocationAdapterCreate, con(%p), base(%p), type(%p)",
1623              (RsContext)con, (RsAllocation)basealloc, (RsElement)type);
1624    }
1625    return (jlong)(uintptr_t) rsAllocationAdapterCreate((RsContext)con, (RsType)type,
1626                                                        (RsAllocation)basealloc);
1627
1628}
1629
1630static void
1631nAllocationAdapterOffset(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
1632                        jint x, jint y, jint z, jint face, jint lod,
1633                        jint a1, jint a2, jint a3, jint a4)
1634{
1635    uint32_t params[] = {
1636        (uint32_t)x, (uint32_t)y, (uint32_t)z, (uint32_t)face,
1637        (uint32_t)lod, (uint32_t)a1, (uint32_t)a2, (uint32_t)a3, (uint32_t)a4
1638    };
1639    if (kLogApi) {
1640        ALOGD("nAllocationAdapterOffset, con(%p), alloc(%p), x(%i), y(%i), z(%i), face(%i), lod(%i), arrays(%i %i %i %i)",
1641              (RsContext)con, (RsAllocation)alloc, x, y, z, face, lod, a1, a2, a3, a4);
1642    }
1643    rsAllocationAdapterOffset((RsContext)con, (RsAllocation)alloc,
1644                              params, sizeof(params));
1645}
1646
1647
1648// -----------------------------------
1649
1650static jlong
1651nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con, jlong native_asset)
1652{
1653    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1654    ALOGV("______nFileA3D %p", asset);
1655
1656    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromMemory((RsContext)con, asset->getBuffer(false), asset->getLength());
1657    return id;
1658}
1659
1660static jlong
1661nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
1662{
1663    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1664    if (mgr == nullptr) {
1665        return 0;
1666    }
1667
1668    AutoJavaStringToUTF8 str(_env, _path);
1669    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1670    if (asset == nullptr) {
1671        return 0;
1672    }
1673
1674    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
1675    return id;
1676}
1677
1678static jlong
1679nFileA3DCreateFromFile(JNIEnv *_env, jobject _this, jlong con, jstring fileName)
1680{
1681    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1682    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromFile((RsContext)con, fileNameUTF.c_str());
1683
1684    return id;
1685}
1686
1687static jint
1688nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D)
1689{
1690    int32_t numEntries = 0;
1691    rsaFileA3DGetNumIndexEntries((RsContext)con, &numEntries, (RsFile)fileA3D);
1692    return (jint)numEntries;
1693}
1694
1695static void
1696nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries)
1697{
1698    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1699    RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry));
1700
1701    rsaFileA3DGetIndexEntries((RsContext)con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D);
1702
1703    for(jint i = 0; i < numEntries; i ++) {
1704        _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName));
1705        _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID);
1706    }
1707
1708    free(fileEntries);
1709}
1710
1711static jlong
1712nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jlong con, jlong fileA3D, jint index)
1713{
1714    ALOGV("______nFileA3D %p", (RsFile) fileA3D);
1715    jlong id = (jlong)(uintptr_t)rsaFileA3DGetEntryByIndex((RsContext)con, (uint32_t)index, (RsFile)fileA3D);
1716    return id;
1717}
1718
1719// -----------------------------------
1720
1721static jlong
1722nFontCreateFromFile(JNIEnv *_env, jobject _this, jlong con,
1723                    jstring fileName, jfloat fontSize, jint dpi)
1724{
1725    AutoJavaStringToUTF8 fileNameUTF(_env, fileName);
1726    jlong id = (jlong)(uintptr_t)rsFontCreateFromFile((RsContext)con,
1727                                         fileNameUTF.c_str(), fileNameUTF.length(),
1728                                         fontSize, dpi);
1729
1730    return id;
1731}
1732
1733static jlong
1734nFontCreateFromAssetStream(JNIEnv *_env, jobject _this, jlong con,
1735                           jstring name, jfloat fontSize, jint dpi, jlong native_asset)
1736{
1737    Asset* asset = reinterpret_cast<Asset*>(native_asset);
1738    AutoJavaStringToUTF8 nameUTF(_env, name);
1739
1740    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1741                                           nameUTF.c_str(), nameUTF.length(),
1742                                           fontSize, dpi,
1743                                           asset->getBuffer(false), asset->getLength());
1744    return id;
1745}
1746
1747static jlong
1748nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
1749                     jfloat fontSize, jint dpi)
1750{
1751    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
1752    if (mgr == nullptr) {
1753        return 0;
1754    }
1755
1756    AutoJavaStringToUTF8 str(_env, _path);
1757    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
1758    if (asset == nullptr) {
1759        return 0;
1760    }
1761
1762    jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
1763                                           str.c_str(), str.length(),
1764                                           fontSize, dpi,
1765                                           asset->getBuffer(false), asset->getLength());
1766    delete asset;
1767    return id;
1768}
1769
1770// -----------------------------------
1771
1772static void
1773nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot)
1774{
1775    if (kLogApi) {
1776        ALOGD("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", (RsContext)con,
1777              (RsScript)script, (RsAllocation)alloc, slot);
1778    }
1779    rsScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot);
1780}
1781
1782static void
1783nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val)
1784{
1785    if (kLogApi) {
1786        ALOGD("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, (void *)script,
1787              slot, val);
1788    }
1789    rsScriptSetVarI((RsContext)con, (RsScript)script, slot, val);
1790}
1791
1792static jint
1793nScriptGetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1794{
1795    if (kLogApi) {
1796        ALOGD("nScriptGetVarI, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1797    }
1798    int value = 0;
1799    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1800    return value;
1801}
1802
1803static void
1804nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1805{
1806    if (kLogApi) {
1807        ALOGD("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1808              slot, val);
1809    }
1810    rsScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val);
1811}
1812
1813static void
1814nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val)
1815{
1816    if (kLogApi) {
1817        ALOGD("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%" PRId64 ")", (RsContext)con, (void *)script,
1818              slot, val);
1819    }
1820    rsScriptSetVarJ((RsContext)con, (RsScript)script, slot, val);
1821}
1822
1823static jlong
1824nScriptGetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1825{
1826    if (kLogApi) {
1827        ALOGD("nScriptGetVarJ, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1828    }
1829    jlong value = 0;
1830    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1831    return value;
1832}
1833
1834static void
1835nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val)
1836{
1837    if (kLogApi) {
1838        ALOGD("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, (void *)script,
1839              slot, val);
1840    }
1841    rsScriptSetVarF((RsContext)con, (RsScript)script, slot, val);
1842}
1843
1844static jfloat
1845nScriptGetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1846{
1847    if (kLogApi) {
1848        ALOGD("nScriptGetVarF, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1849    }
1850    jfloat value = 0;
1851    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1852    return value;
1853}
1854
1855static void
1856nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val)
1857{
1858    if (kLogApi) {
1859        ALOGD("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, (void *)script,
1860              slot, val);
1861    }
1862    rsScriptSetVarD((RsContext)con, (RsScript)script, slot, val);
1863}
1864
1865static jdouble
1866nScriptGetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot)
1867{
1868    if (kLogApi) {
1869        ALOGD("nScriptGetVarD, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1870    }
1871    jdouble value = 0;
1872    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, &value, sizeof(value));
1873    return value;
1874}
1875
1876static void
1877nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1878{
1879    if (kLogApi) {
1880        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1881    }
1882    jint len = _env->GetArrayLength(data);
1883    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1884    if (ptr == nullptr) {
1885        ALOGE("Failed to get Java array elements");
1886        return;
1887    }
1888    rsScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1889    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1890}
1891
1892static void
1893nScriptGetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1894{
1895    if (kLogApi) {
1896        ALOGD("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1897    }
1898    jint len = _env->GetArrayLength(data);
1899    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1900    if (ptr == nullptr) {
1901        ALOGE("Failed to get Java array elements");
1902        return;
1903    }
1904    rsScriptGetVarV((RsContext)con, (RsScript)script, slot, ptr, len);
1905    _env->ReleaseByteArrayElements(data, ptr, 0);
1906}
1907
1908static void
1909nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data,
1910                jlong elem, jintArray dims)
1911{
1912    if (kLogApi) {
1913        ALOGD("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1914    }
1915    jint len = _env->GetArrayLength(data);
1916    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1917    if (ptr == nullptr) {
1918        ALOGE("Failed to get Java array elements");
1919        return;
1920    }
1921    jint dimsLen = _env->GetArrayLength(dims) * sizeof(int);
1922    jint *dimsPtr = _env->GetIntArrayElements(dims, nullptr);
1923    if (dimsPtr == nullptr) {
1924        ALOGE("Failed to get Java array elements");
1925        return;
1926    }
1927    rsScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem,
1928                     (const uint32_t*) dimsPtr, dimsLen);
1929    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1930    _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT);
1931}
1932
1933
1934static void
1935nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone)
1936{
1937    if (kLogApi) {
1938        ALOGD("nScriptCSetTimeZone, con(%p), s(%p)", (RsContext)con, (void *)script);
1939    }
1940
1941    jint length = _env->GetArrayLength(timeZone);
1942    jbyte* timeZone_ptr;
1943    timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0);
1944    if (timeZone_ptr == nullptr) {
1945        ALOGE("Failed to get Java array elements");
1946        return;
1947    }
1948
1949    rsScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length);
1950
1951    if (timeZone_ptr) {
1952        _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0);
1953    }
1954}
1955
1956static void
1957nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot)
1958{
1959    if (kLogApi) {
1960        ALOGD("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj);
1961    }
1962    rsScriptInvoke((RsContext)con, (RsScript)obj, slot);
1963}
1964
1965static void
1966nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data)
1967{
1968    if (kLogApi) {
1969        ALOGD("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot);
1970    }
1971    jint len = _env->GetArrayLength(data);
1972    jbyte *ptr = _env->GetByteArrayElements(data, nullptr);
1973    if (ptr == nullptr) {
1974        ALOGE("Failed to get Java array elements");
1975        return;
1976    }
1977    rsScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len);
1978    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
1979}
1980
1981static void
1982nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
1983               jlongArray ains, jlong aout, jbyteArray params,
1984               jintArray limits)
1985{
1986    if (kLogApi) {
1987        ALOGD("nScriptForEach, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
1988    }
1989
1990    jint   in_len = 0;
1991    jlong *in_ptr = nullptr;
1992
1993    RsAllocation *in_allocs = nullptr;
1994
1995    if (ains != nullptr) {
1996        in_len = _env->GetArrayLength(ains);
1997        if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
1998            ALOGE("Too many arguments in kernel launch.");
1999            // TODO (b/20758983): Report back to Java and throw an exception
2000            return;
2001        }
2002
2003        in_ptr = _env->GetLongArrayElements(ains, nullptr);
2004        if (in_ptr == nullptr) {
2005            ALOGE("Failed to get Java array elements");
2006            return;
2007        }
2008
2009        if (sizeof(RsAllocation) == sizeof(jlong)) {
2010            in_allocs = (RsAllocation*)in_ptr;
2011        } else {
2012            // Convert from 64-bit jlong types to the native pointer type.
2013
2014            in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
2015            if (in_allocs == nullptr) {
2016                ALOGE("Failed launching kernel for lack of memory.");
2017                _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2018                return;
2019            }
2020
2021            for (int index = in_len; --index >= 0;) {
2022                in_allocs[index] = (RsAllocation)in_ptr[index];
2023            }
2024        }
2025    }
2026
2027    jint   param_len = 0;
2028    jbyte *param_ptr = nullptr;
2029
2030    if (params != nullptr) {
2031        param_len = _env->GetArrayLength(params);
2032        param_ptr = _env->GetByteArrayElements(params, nullptr);
2033        if (param_ptr == nullptr) {
2034            ALOGE("Failed to get Java array elements");
2035            return;
2036        }
2037    }
2038
2039    RsScriptCall sc, *sca = nullptr;
2040    uint32_t sc_size = 0;
2041
2042    jint  limit_len = 0;
2043    jint *limit_ptr = nullptr;
2044
2045    if (limits != nullptr) {
2046        limit_len = _env->GetArrayLength(limits);
2047        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
2048        if (limit_ptr == nullptr) {
2049            ALOGE("Failed to get Java array elements");
2050            return;
2051        }
2052
2053        assert(limit_len == 6);
2054        UNUSED(limit_len);  // As the assert might not be compiled.
2055
2056        sc.xStart     = limit_ptr[0];
2057        sc.xEnd       = limit_ptr[1];
2058        sc.yStart     = limit_ptr[2];
2059        sc.yEnd       = limit_ptr[3];
2060        sc.zStart     = limit_ptr[4];
2061        sc.zEnd       = limit_ptr[5];
2062        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
2063        sc.arrayStart = 0;
2064        sc.arrayEnd = 0;
2065        sc.array2Start = 0;
2066        sc.array2End = 0;
2067        sc.array3Start = 0;
2068        sc.array3End = 0;
2069        sc.array4Start = 0;
2070        sc.array4End = 0;
2071
2072        sca = &sc;
2073    }
2074
2075    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
2076                         in_allocs, in_len, (RsAllocation)aout,
2077                         param_ptr, param_len, sca, sc_size);
2078
2079    if (ains != nullptr) {
2080        _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2081    }
2082
2083    if (params != nullptr) {
2084        _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
2085    }
2086
2087    if (limits != nullptr) {
2088        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2089    }
2090}
2091
2092static void
2093nScriptReduce(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
2094              jlong ain, jlong aout, jintArray limits)
2095{
2096    if (kLogApi) {
2097        ALOGD("nScriptReduce, con(%p), s(%p), slot(%i) ain(%" PRId64 ") aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ain, aout);
2098    }
2099
2100    RsScriptCall sc, *sca = nullptr;
2101    uint32_t sc_size = 0;
2102
2103    jint  limit_len = 0;
2104    jint *limit_ptr = nullptr;
2105
2106    // If the caller passed limits, reflect them in the RsScriptCall.
2107    if (limits != nullptr) {
2108        limit_len = _env->GetArrayLength(limits);
2109        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
2110        if (limit_ptr == nullptr) {
2111            ALOGE("Failed to get Java array elements");
2112            return;
2113        }
2114
2115        // We expect to be passed an array [x1, x2] which specifies
2116        // the sub-range for a 1-dimensional reduction.
2117        assert(limit_len == 2);
2118        UNUSED(limit_len);  // As the assert might not be compiled.
2119
2120        sc.xStart     = limit_ptr[0];
2121        sc.xEnd       = limit_ptr[1];
2122        sc.yStart     = 0;
2123        sc.yEnd       = 0;
2124        sc.zStart     = 0;
2125        sc.zEnd       = 0;
2126        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
2127        sc.arrayStart = 0;
2128        sc.arrayEnd = 0;
2129        sc.array2Start = 0;
2130        sc.array2End = 0;
2131        sc.array3Start = 0;
2132        sc.array3End = 0;
2133        sc.array4Start = 0;
2134        sc.array4End = 0;
2135
2136        sca = &sc;
2137        sc_size = sizeof(sc);
2138    }
2139
2140    rsScriptReduce((RsContext)con, (RsScript)script, slot,
2141                   (RsAllocation)ain, (RsAllocation)aout,
2142                   sca, sc_size);
2143
2144    if (limits != nullptr) {
2145        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2146    }
2147}
2148
2149static void
2150nScriptReduceNew(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
2151                 jlongArray ains, jlong aout, jintArray limits)
2152{
2153    if (kLogApi) {
2154        ALOGD("nScriptReduceNew, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
2155    }
2156
2157    if (ains == nullptr) {
2158        ALOGE("At least one input required.");
2159        // TODO (b/20758983): Report back to Java and throw an exception
2160        return;
2161    }
2162    jint in_len = _env->GetArrayLength(ains);
2163    if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
2164        ALOGE("Too many arguments in kernel launch.");
2165        // TODO (b/20758983): Report back to Java and throw an exception
2166        return;
2167    }
2168
2169    jlong *in_ptr = _env->GetLongArrayElements(ains, nullptr);
2170    if (in_ptr == nullptr) {
2171        ALOGE("Failed to get Java array elements");
2172        // TODO (b/20758983): Report back to Java and throw an exception
2173        return;
2174    }
2175
2176    RsAllocation *in_allocs = nullptr;
2177    if (sizeof(RsAllocation) == sizeof(jlong)) {
2178        in_allocs = (RsAllocation*)in_ptr;
2179    } else {
2180        // Convert from 64-bit jlong types to the native pointer type.
2181
2182        in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
2183        if (in_allocs == nullptr) {
2184            ALOGE("Failed launching kernel for lack of memory.");
2185            // TODO (b/20758983): Report back to Java and throw an exception
2186            _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2187            return;
2188        }
2189
2190        for (int index = in_len; --index >= 0;) {
2191            in_allocs[index] = (RsAllocation)in_ptr[index];
2192        }
2193    }
2194
2195    RsScriptCall sc, *sca = nullptr;
2196    uint32_t sc_size = 0;
2197
2198    jint  limit_len = 0;
2199    jint *limit_ptr = nullptr;
2200
2201    if (limits != nullptr) {
2202        limit_len = _env->GetArrayLength(limits);
2203        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
2204        if (limit_ptr == nullptr) {
2205            ALOGE("Failed to get Java array elements");
2206            // TODO (b/20758983): Report back to Java and throw an exception
2207            return;
2208        }
2209
2210        assert(limit_len == 6);
2211        UNUSED(limit_len);  // As the assert might not be compiled.
2212
2213        sc.xStart     = limit_ptr[0];
2214        sc.xEnd       = limit_ptr[1];
2215        sc.yStart     = limit_ptr[2];
2216        sc.yEnd       = limit_ptr[3];
2217        sc.zStart     = limit_ptr[4];
2218        sc.zEnd       = limit_ptr[5];
2219        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
2220        sc.arrayStart = 0;
2221        sc.arrayEnd = 0;
2222        sc.array2Start = 0;
2223        sc.array2End = 0;
2224        sc.array3Start = 0;
2225        sc.array3End = 0;
2226        sc.array4Start = 0;
2227        sc.array4End = 0;
2228
2229        sca = &sc;
2230        sc_size = sizeof(sc);
2231    }
2232
2233    rsScriptReduceNew((RsContext)con, (RsScript)script, slot,
2234                      in_allocs, in_len, (RsAllocation)aout,
2235                      sca, sc_size);
2236
2237    _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2238
2239    if (limits != nullptr) {
2240        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2241    }
2242}
2243
2244// -----------------------------------
2245
2246static jlong
2247nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
2248               jstring resName, jstring cacheDir,
2249               jbyteArray scriptRef, jint length)
2250{
2251    if (kLogApi) {
2252        ALOGD("nScriptCCreate, con(%p)", (RsContext)con);
2253    }
2254
2255    AutoJavaStringToUTF8 resNameUTF(_env, resName);
2256    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
2257    jlong ret = 0;
2258    jbyte* script_ptr = nullptr;
2259    jint _exception = 0;
2260    jint remaining;
2261    if (!scriptRef) {
2262        _exception = 1;
2263        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
2264        goto exit;
2265    }
2266    if (length < 0) {
2267        _exception = 1;
2268        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
2269        goto exit;
2270    }
2271    remaining = _env->GetArrayLength(scriptRef);
2272    if (remaining < length) {
2273        _exception = 1;
2274        //jniThrowException(_env, "java/lang/IllegalArgumentException",
2275        //        "length > script.length - offset");
2276        goto exit;
2277    }
2278    script_ptr = (jbyte *)
2279        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
2280    if (script_ptr == nullptr) {
2281        ALOGE("Failed to get Java array elements");
2282        return ret;
2283    }
2284
2285    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
2286
2287    ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
2288                                resNameUTF.c_str(), resNameUTF.length(),
2289                                cacheDirUTF.c_str(), cacheDirUTF.length(),
2290                                (const char *)script_ptr, length);
2291
2292exit:
2293    if (script_ptr) {
2294        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
2295                _exception ? JNI_ABORT: 0);
2296    }
2297
2298    return (jlong)(uintptr_t)ret;
2299}
2300
2301static jlong
2302nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
2303{
2304    if (kLogApi) {
2305        ALOGD("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id,
2306              (void *)eid);
2307    }
2308    return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
2309}
2310
2311static jlong
2312nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
2313{
2314    if (kLogApi) {
2315        ALOGD("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
2316              (void *)sid, slot, sig);
2317    }
2318    return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
2319}
2320
2321static jlong
2322nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
2323{
2324    if (kLogApi) {
2325        ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con,
2326              (void *)sid, slot);
2327    }
2328    return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
2329}
2330
2331static jlong
2332nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
2333{
2334    if (kLogApi) {
2335        ALOGD("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid,
2336              slot);
2337    }
2338    return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
2339}
2340
2341static jlong
2342nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
2343    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
2344{
2345    if (kLogApi) {
2346        ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
2347    }
2348
2349    jint kernelsLen = _env->GetArrayLength(_kernels);
2350    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
2351    if (jKernelsPtr == nullptr) {
2352        ALOGE("Failed to get Java array elements: kernels");
2353        return 0;
2354    }
2355    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
2356    for(int i = 0; i < kernelsLen; ++i) {
2357        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
2358    }
2359
2360    jint srcLen = _env->GetArrayLength(_src);
2361    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
2362    if (jSrcPtr == nullptr) {
2363        ALOGE("Failed to get Java array elements: src");
2364        return 0;
2365    }
2366    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
2367    for(int i = 0; i < srcLen; ++i) {
2368        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
2369    }
2370
2371    jint dstkLen = _env->GetArrayLength(_dstk);
2372    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
2373    if (jDstkPtr == nullptr) {
2374        ALOGE("Failed to get Java array elements: dstk");
2375        return 0;
2376    }
2377    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
2378    for(int i = 0; i < dstkLen; ++i) {
2379        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
2380    }
2381
2382    jint dstfLen = _env->GetArrayLength(_dstf);
2383    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
2384    if (jDstfPtr == nullptr) {
2385        ALOGE("Failed to get Java array elements: dstf");
2386        return 0;
2387    }
2388    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
2389    for(int i = 0; i < dstfLen; ++i) {
2390        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
2391    }
2392
2393    jint typesLen = _env->GetArrayLength(_types);
2394    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
2395    if (jTypesPtr == nullptr) {
2396        ALOGE("Failed to get Java array elements: types");
2397        return 0;
2398    }
2399    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
2400    for(int i = 0; i < typesLen; ++i) {
2401        typesPtr[i] = (RsType)jTypesPtr[i];
2402    }
2403
2404    jlong id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
2405                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
2406                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
2407                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
2408                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
2409                               (RsType *)typesPtr, typesLen * sizeof(RsType));
2410
2411    free(kernelsPtr);
2412    free(srcPtr);
2413    free(dstkPtr);
2414    free(dstfPtr);
2415    free(typesPtr);
2416    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
2417    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
2418    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
2419    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
2420    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
2421    return id;
2422}
2423
2424static void
2425nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2426{
2427    if (kLogApi) {
2428        ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2429              (void *)gid, (void *)kid, (void *)alloc);
2430    }
2431    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2432}
2433
2434static void
2435nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2436{
2437    if (kLogApi) {
2438        ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2439              (void *)gid, (void *)kid, (void *)alloc);
2440    }
2441    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2442}
2443
2444static void
2445nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
2446{
2447    if (kLogApi) {
2448        ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
2449    }
2450    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
2451}
2452
2453// ---------------------------------------------------------------------------
2454
2455static jlong
2456nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
2457                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
2458                    jboolean depthMask, jboolean ditherEnable,
2459                    jint srcFunc, jint destFunc,
2460                    jint depthFunc)
2461{
2462    if (kLogApi) {
2463        ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
2464    }
2465    return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
2466                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
2467                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
2468}
2469
2470// ---------------------------------------------------------------------------
2471
2472static void
2473nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
2474{
2475    if (kLogApi) {
2476        ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
2477              (RsProgramVertex)vpv, slot, (RsAllocation)a);
2478    }
2479    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
2480}
2481
2482static void
2483nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2484{
2485    if (kLogApi) {
2486        ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2487              (RsProgramFragment)vpf, slot, (RsAllocation)a);
2488    }
2489    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
2490}
2491
2492static void
2493nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2494{
2495    if (kLogApi) {
2496        ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2497              (RsProgramFragment)vpf, slot, (RsSampler)a);
2498    }
2499    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
2500}
2501
2502// ---------------------------------------------------------------------------
2503
2504static jlong
2505nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2506                       jobjectArray texNames, jlongArray params)
2507{
2508    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2509    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2510    jint paramLen = _env->GetArrayLength(params);
2511    if (jParamPtr == nullptr) {
2512        ALOGE("Failed to get Java array elements");
2513        return 0;
2514    }
2515
2516    int texCount = _env->GetArrayLength(texNames);
2517    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2518    const char ** nameArray = names.c_str();
2519    size_t* sizeArray = names.c_str_len();
2520
2521    if (kLogApi) {
2522        ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2523    }
2524
2525    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2526    for(int i = 0; i < paramLen; ++i) {
2527        paramPtr[i] = (uintptr_t)jParamPtr[i];
2528    }
2529    jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2530                                             nameArray, texCount, sizeArray,
2531                                             paramPtr, paramLen);
2532
2533    free(paramPtr);
2534    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2535    return ret;
2536}
2537
2538
2539// ---------------------------------------------------------------------------
2540
2541static jlong
2542nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2543                     jobjectArray texNames, jlongArray params)
2544{
2545    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2546    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2547    jint paramLen = _env->GetArrayLength(params);
2548    if (jParamPtr == nullptr) {
2549        ALOGE("Failed to get Java array elements");
2550        return 0;
2551    }
2552
2553    if (kLogApi) {
2554        ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2555    }
2556
2557    int texCount = _env->GetArrayLength(texNames);
2558    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2559    const char ** nameArray = names.c_str();
2560    size_t* sizeArray = names.c_str_len();
2561
2562    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2563    for(int i = 0; i < paramLen; ++i) {
2564        paramPtr[i] = (uintptr_t)jParamPtr[i];
2565    }
2566
2567    jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2568                                           nameArray, texCount, sizeArray,
2569                                           paramPtr, paramLen);
2570
2571    free(paramPtr);
2572    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2573    return ret;
2574}
2575
2576// ---------------------------------------------------------------------------
2577
2578static jlong
2579nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
2580{
2581    if (kLogApi) {
2582        ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
2583              pointSprite, cull);
2584    }
2585    return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
2586}
2587
2588
2589// ---------------------------------------------------------------------------
2590
2591static void
2592nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
2593{
2594    if (kLogApi) {
2595        ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
2596    }
2597    rsContextBindRootScript((RsContext)con, (RsScript)script);
2598}
2599
2600static void
2601nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
2602{
2603    if (kLogApi) {
2604        ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
2605    }
2606    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
2607}
2608
2609static void
2610nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2611{
2612    if (kLogApi) {
2613        ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
2614              (RsProgramFragment)pf);
2615    }
2616    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
2617}
2618
2619static void
2620nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2621{
2622    if (kLogApi) {
2623        ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
2624    }
2625    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
2626}
2627
2628static void
2629nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2630{
2631    if (kLogApi) {
2632        ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
2633    }
2634    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
2635}
2636
2637
2638// ---------------------------------------------------------------------------
2639
2640static jlong
2641nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
2642               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
2643{
2644    if (kLogApi) {
2645        ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
2646    }
2647    return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
2648                                 (RsSamplerValue)magFilter,
2649                                 (RsSamplerValue)minFilter,
2650                                 (RsSamplerValue)wrapS,
2651                                 (RsSamplerValue)wrapT,
2652                                 (RsSamplerValue)wrapR,
2653                                 aniso);
2654}
2655
2656// ---------------------------------------------------------------------------
2657
2658static jlong
2659nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
2660{
2661    if (kLogApi) {
2662        ALOGD("nMeshCreate, con(%p)", (RsContext)con);
2663    }
2664
2665    jint vtxLen = _env->GetArrayLength(_vtx);
2666    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
2667    if (jVtxPtr == nullptr) {
2668        ALOGE("Failed to get Java array elements: vtx");
2669        return 0;
2670    }
2671    RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
2672    for(int i = 0; i < vtxLen; ++i) {
2673        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
2674    }
2675
2676    jint idxLen = _env->GetArrayLength(_idx);
2677    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
2678    if (jIdxPtr == nullptr) {
2679        ALOGE("Failed to get Java array elements: idx");
2680        return 0;
2681    }
2682    RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
2683    for(int i = 0; i < idxLen; ++i) {
2684        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
2685    }
2686
2687    jint primLen = _env->GetArrayLength(_prim);
2688    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
2689    if (primPtr == nullptr) {
2690        ALOGE("Failed to get Java array elements: prim");
2691        return 0;
2692    }
2693
2694    jlong id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
2695                               (RsAllocation *)vtxPtr, vtxLen,
2696                               (RsAllocation *)idxPtr, idxLen,
2697                               (uint32_t *)primPtr, primLen);
2698
2699    free(vtxPtr);
2700    free(idxPtr);
2701    _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
2702    _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
2703    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
2704    return id;
2705}
2706
2707static jint
2708nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2709{
2710    if (kLogApi) {
2711        ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2712    }
2713    jint vtxCount = 0;
2714    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
2715    return vtxCount;
2716}
2717
2718static jint
2719nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2720{
2721    if (kLogApi) {
2722        ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2723    }
2724    jint idxCount = 0;
2725    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
2726    return idxCount;
2727}
2728
2729static void
2730nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
2731{
2732    if (kLogApi) {
2733        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2734    }
2735
2736    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
2737    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
2738
2739    for(jint i = 0; i < numVtxIDs; i ++) {
2740        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2741        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
2742    }
2743
2744    free(allocs);
2745}
2746
2747static void
2748nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
2749{
2750    if (kLogApi) {
2751        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2752    }
2753
2754    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
2755    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
2756
2757    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
2758
2759    for(jint i = 0; i < numIndices; i ++) {
2760        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2761        const jint prim = (jint)prims[i];
2762        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
2763        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
2764    }
2765
2766    free(allocs);
2767    free(prims);
2768}
2769
2770static jint
2771nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
2772    return (jint)sizeof(void*);
2773}
2774
2775static jobject
2776nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
2777                        jlongArray strideArr, jint xBytesSize,
2778                        jint dimY, jint dimZ) {
2779    if (kLogApi) {
2780        ALOGD("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
2781    }
2782
2783    jlong *jStridePtr = _env->GetLongArrayElements(strideArr, nullptr);
2784    if (jStridePtr == nullptr) {
2785        ALOGE("Failed to get Java array elements: strideArr");
2786        return 0;
2787    }
2788
2789    size_t strideIn = xBytesSize;
2790    void* ptr = nullptr;
2791    if (alloc != 0) {
2792        ptr = rsAllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
2793                                     RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
2794                                     &strideIn, sizeof(size_t));
2795    }
2796
2797    jobject byteBuffer = nullptr;
2798    if (ptr != nullptr) {
2799        size_t bufferSize = strideIn;
2800        jStridePtr[0] = strideIn;
2801        if (dimY > 0) {
2802            bufferSize *= dimY;
2803        }
2804        if (dimZ > 0) {
2805            bufferSize *= dimZ;
2806        }
2807        byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize);
2808    }
2809    _env->ReleaseLongArrayElements(strideArr, jStridePtr, 0);
2810    return byteBuffer;
2811}
2812// ---------------------------------------------------------------------------
2813
2814
2815static const char *classPathName = "android/renderscript/RenderScript";
2816
2817static const JNINativeMethod methods[] = {
2818{"_nInit",                         "()V",                                     (void*)_nInit },
2819
2820{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
2821{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
2822{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
2823{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
2824{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
2825{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
2826
2827{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
2828{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
2829
2830
2831// All methods below are thread protected in java.
2832{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
2833{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
2834{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
2835{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
2836{"rsnContextSetCacheDir",            "(JLjava/lang/String;)V",                (void*)nContextSetCacheDir },
2837{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
2838{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
2839{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
2840{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
2841{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
2842{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
2843{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
2844{"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
2845{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
2846{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
2847{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
2848{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
2849{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
2850
2851{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
2852{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
2853{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
2854{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
2855{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
2856{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
2857
2858{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
2859{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
2860{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
2861
2862{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
2863{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
2864{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
2865{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
2866
2867{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
2868{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
2869
2870{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
2871{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
2872{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
2873{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
2874
2875{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
2876{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
2877
2878{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
2879{"rsnAllocationSetupBufferQueue",    "(JJI)V",                                (void*)nAllocationSetupBufferQueue },
2880{"rsnAllocationShareBufferQueue",    "(JJJ)V",                                (void*)nAllocationShareBufferQueue },
2881{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
2882{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
2883{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
2884{"rsnAllocationIoReceive",           "(JJ)J",                                 (void*)nAllocationIoReceive },
2885{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
2886{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
2887{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
2888{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
2889{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
2890{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
2891{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
2892{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
2893{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
2894{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
2895{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationRead3D },
2896{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
2897{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
2898{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
2899
2900{"rsnAllocationAdapterCreate",       "(JJJ)J",                                (void*)nAllocationAdapterCreate },
2901{"rsnAllocationAdapterOffset",       "(JJIIIIIIIII)V",                        (void*)nAllocationAdapterOffset },
2902
2903{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
2904{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
2905{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
2906{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
2907
2908{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
2909{"rsnScriptReduce",                  "(JJIJJ[I)V",                            (void*)nScriptReduce },
2910{"rsnScriptReduceNew",               "(JJI[JJ[I)V",                           (void*)nScriptReduceNew },
2911
2912{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
2913{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
2914{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
2915{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
2916{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
2917{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
2918{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
2919{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
2920{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
2921{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
2922{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
2923{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
2924
2925{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
2926{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
2927{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
2928{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
2929{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
2930{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
2931{"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
2932{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
2933{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
2934{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
2935{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
2936
2937{"rsnScriptIntrinsicBLAS_Single",    "(JJIIIIIIIIIFJJFJIIII)V",               (void*)nScriptIntrinsicBLAS_Single },
2938{"rsnScriptIntrinsicBLAS_Double",    "(JJIIIIIIIIIDJJDJIIII)V",               (void*)nScriptIntrinsicBLAS_Double },
2939{"rsnScriptIntrinsicBLAS_Complex",   "(JJIIIIIIIIIFFJJFFJIIII)V",             (void*)nScriptIntrinsicBLAS_Complex },
2940{"rsnScriptIntrinsicBLAS_Z",         "(JJIIIIIIIIIDDJJDDJIIII)V",             (void*)nScriptIntrinsicBLAS_Z },
2941
2942{"rsnScriptIntrinsicBLAS_BNNM",      "(JJIIIJIJIJII)V",                       (void*)nScriptIntrinsicBLAS_BNNM },
2943
2944{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
2945
2946{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
2947{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
2948{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
2949
2950{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
2951{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
2952{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
2953
2954{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
2955{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
2956{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
2957{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
2958{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
2959
2960{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
2961
2962{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
2963
2964{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
2965{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
2966{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
2967{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
2968
2969{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
2970{"rsnAllocationGetByteBuffer",       "(JJ[JIII)Ljava/nio/ByteBuffer;",        (void*)nAllocationGetByteBuffer },
2971};
2972
2973static int registerFuncs(JNIEnv *_env)
2974{
2975    return android::AndroidRuntime::registerNativeMethods(
2976            _env, classPathName, methods, NELEM(methods));
2977}
2978
2979// ---------------------------------------------------------------------------
2980
2981jint JNI_OnLoad(JavaVM* vm, void* reserved)
2982{
2983    JNIEnv* env = nullptr;
2984    jint result = -1;
2985
2986    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
2987        ALOGE("ERROR: GetEnv failed\n");
2988        goto bail;
2989    }
2990    assert(env != nullptr);
2991
2992    if (registerFuncs(env) < 0) {
2993        ALOGE("ERROR: Renderscript native registration failed\n");
2994        goto bail;
2995    }
2996
2997    /* success -- return valid version number */
2998    result = JNI_VERSION_1_4;
2999
3000bail:
3001    return result;
3002}
3003