android_renderscript_RenderScript.cpp revision f94e77da7e6634937d65a9a608c504de91b53f1c
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    jlong id = 0;
2350
2351    RsScriptKernelID* kernelsPtr;
2352    jint kernelsLen = _env->GetArrayLength(_kernels);
2353    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
2354
2355    RsScriptKernelID* srcPtr;
2356    jint srcLen = _env->GetArrayLength(_src);
2357    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
2358
2359    RsScriptKernelID* dstkPtr;
2360    jint dstkLen = _env->GetArrayLength(_dstk);
2361    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
2362
2363    RsScriptKernelID* dstfPtr;
2364    jint dstfLen = _env->GetArrayLength(_dstf);
2365    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
2366
2367    RsType* typesPtr;
2368    jint typesLen = _env->GetArrayLength(_types);
2369    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
2370
2371    if (jKernelsPtr == nullptr) {
2372        ALOGE("Failed to get Java array elements: kernels");
2373        goto cleanup;
2374    }
2375    if (jSrcPtr == nullptr) {
2376        ALOGE("Failed to get Java array elements: src");
2377        goto cleanup;
2378    }
2379    if (jDstkPtr == nullptr) {
2380        ALOGE("Failed to get Java array elements: dstk");
2381        goto cleanup;
2382    }
2383    if (jDstfPtr == nullptr) {
2384        ALOGE("Failed to get Java array elements: dstf");
2385        goto cleanup;
2386    }
2387    if (jTypesPtr == nullptr) {
2388        ALOGE("Failed to get Java array elements: types");
2389        goto cleanup;
2390    }
2391
2392    kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
2393    for(int i = 0; i < kernelsLen; ++i) {
2394        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
2395    }
2396
2397    srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
2398    for(int i = 0; i < srcLen; ++i) {
2399        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
2400    }
2401
2402    dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
2403    for(int i = 0; i < dstkLen; ++i) {
2404        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
2405    }
2406
2407    dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
2408    for(int i = 0; i < dstfLen; ++i) {
2409        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
2410    }
2411
2412    typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
2413    for(int i = 0; i < typesLen; ++i) {
2414        typesPtr[i] = (RsType)jTypesPtr[i];
2415    }
2416
2417    id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
2418                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
2419                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
2420                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
2421                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
2422                               (RsType *)typesPtr, typesLen * sizeof(RsType));
2423
2424    free(kernelsPtr);
2425    free(srcPtr);
2426    free(dstkPtr);
2427    free(dstfPtr);
2428    free(typesPtr);
2429
2430cleanup:
2431    if (jKernelsPtr != nullptr) {
2432        _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
2433    }
2434    if (jSrcPtr != nullptr) {
2435        _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
2436    }
2437    if (jDstkPtr != nullptr) {
2438        _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
2439    }
2440    if (jDstfPtr != nullptr) {
2441        _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
2442    }
2443    if (jTypesPtr != nullptr) {
2444        _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
2445    }
2446
2447    return id;
2448}
2449
2450static void
2451nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2452{
2453    if (kLogApi) {
2454        ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2455              (void *)gid, (void *)kid, (void *)alloc);
2456    }
2457    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2458}
2459
2460static void
2461nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2462{
2463    if (kLogApi) {
2464        ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2465              (void *)gid, (void *)kid, (void *)alloc);
2466    }
2467    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2468}
2469
2470static void
2471nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
2472{
2473    if (kLogApi) {
2474        ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
2475    }
2476    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
2477}
2478
2479// ---------------------------------------------------------------------------
2480
2481static jlong
2482nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
2483                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
2484                    jboolean depthMask, jboolean ditherEnable,
2485                    jint srcFunc, jint destFunc,
2486                    jint depthFunc)
2487{
2488    if (kLogApi) {
2489        ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
2490    }
2491    return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
2492                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
2493                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
2494}
2495
2496// ---------------------------------------------------------------------------
2497
2498static void
2499nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
2500{
2501    if (kLogApi) {
2502        ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
2503              (RsProgramVertex)vpv, slot, (RsAllocation)a);
2504    }
2505    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
2506}
2507
2508static void
2509nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2510{
2511    if (kLogApi) {
2512        ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2513              (RsProgramFragment)vpf, slot, (RsAllocation)a);
2514    }
2515    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
2516}
2517
2518static void
2519nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2520{
2521    if (kLogApi) {
2522        ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2523              (RsProgramFragment)vpf, slot, (RsSampler)a);
2524    }
2525    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
2526}
2527
2528// ---------------------------------------------------------------------------
2529
2530static jlong
2531nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2532                       jobjectArray texNames, jlongArray params)
2533{
2534    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2535    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2536    jint paramLen = _env->GetArrayLength(params);
2537    if (jParamPtr == nullptr) {
2538        ALOGE("Failed to get Java array elements");
2539        return 0;
2540    }
2541
2542    int texCount = _env->GetArrayLength(texNames);
2543    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2544    const char ** nameArray = names.c_str();
2545    size_t* sizeArray = names.c_str_len();
2546
2547    if (kLogApi) {
2548        ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2549    }
2550
2551    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2552    for(int i = 0; i < paramLen; ++i) {
2553        paramPtr[i] = (uintptr_t)jParamPtr[i];
2554    }
2555    jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2556                                             nameArray, texCount, sizeArray,
2557                                             paramPtr, paramLen);
2558
2559    free(paramPtr);
2560    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2561    return ret;
2562}
2563
2564
2565// ---------------------------------------------------------------------------
2566
2567static jlong
2568nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2569                     jobjectArray texNames, jlongArray params)
2570{
2571    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2572    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2573    jint paramLen = _env->GetArrayLength(params);
2574    if (jParamPtr == nullptr) {
2575        ALOGE("Failed to get Java array elements");
2576        return 0;
2577    }
2578
2579    if (kLogApi) {
2580        ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2581    }
2582
2583    int texCount = _env->GetArrayLength(texNames);
2584    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2585    const char ** nameArray = names.c_str();
2586    size_t* sizeArray = names.c_str_len();
2587
2588    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2589    for(int i = 0; i < paramLen; ++i) {
2590        paramPtr[i] = (uintptr_t)jParamPtr[i];
2591    }
2592
2593    jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2594                                           nameArray, texCount, sizeArray,
2595                                           paramPtr, paramLen);
2596
2597    free(paramPtr);
2598    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2599    return ret;
2600}
2601
2602// ---------------------------------------------------------------------------
2603
2604static jlong
2605nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
2606{
2607    if (kLogApi) {
2608        ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
2609              pointSprite, cull);
2610    }
2611    return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
2612}
2613
2614
2615// ---------------------------------------------------------------------------
2616
2617static void
2618nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
2619{
2620    if (kLogApi) {
2621        ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
2622    }
2623    rsContextBindRootScript((RsContext)con, (RsScript)script);
2624}
2625
2626static void
2627nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
2628{
2629    if (kLogApi) {
2630        ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
2631    }
2632    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
2633}
2634
2635static void
2636nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2637{
2638    if (kLogApi) {
2639        ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
2640              (RsProgramFragment)pf);
2641    }
2642    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
2643}
2644
2645static void
2646nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2647{
2648    if (kLogApi) {
2649        ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
2650    }
2651    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
2652}
2653
2654static void
2655nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2656{
2657    if (kLogApi) {
2658        ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
2659    }
2660    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
2661}
2662
2663
2664// ---------------------------------------------------------------------------
2665
2666static jlong
2667nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
2668               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
2669{
2670    if (kLogApi) {
2671        ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
2672    }
2673    return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
2674                                 (RsSamplerValue)magFilter,
2675                                 (RsSamplerValue)minFilter,
2676                                 (RsSamplerValue)wrapS,
2677                                 (RsSamplerValue)wrapT,
2678                                 (RsSamplerValue)wrapR,
2679                                 aniso);
2680}
2681
2682// ---------------------------------------------------------------------------
2683
2684static jlong
2685nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
2686{
2687    if (kLogApi) {
2688        ALOGD("nMeshCreate, con(%p)", (RsContext)con);
2689    }
2690
2691    jlong id = 0;
2692
2693    RsAllocation* vtxPtr;
2694    jint vtxLen = _env->GetArrayLength(_vtx);
2695    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
2696
2697    RsAllocation* idxPtr;
2698    jint idxLen = _env->GetArrayLength(_idx);
2699    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
2700
2701    jint primLen = _env->GetArrayLength(_prim);
2702    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
2703
2704    if (jVtxPtr == nullptr) {
2705        ALOGE("Failed to get Java array elements: vtx");
2706        goto cleanupMesh;
2707    }
2708    if (jIdxPtr == nullptr) {
2709        ALOGE("Failed to get Java array elements: idx");
2710        goto cleanupMesh;
2711    }
2712    if (primPtr == nullptr) {
2713        ALOGE("Failed to get Java array elements: prim");
2714        goto cleanupMesh;
2715    }
2716
2717    vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
2718    for(int i = 0; i < vtxLen; ++i) {
2719        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
2720    }
2721
2722    idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
2723    for(int i = 0; i < idxLen; ++i) {
2724        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
2725    }
2726
2727    id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
2728                                        (RsAllocation *)vtxPtr, vtxLen,
2729                                        (RsAllocation *)idxPtr, idxLen,
2730                                        (uint32_t *)primPtr, primLen);
2731
2732    free(vtxPtr);
2733    free(idxPtr);
2734
2735cleanupMesh:
2736    if (jVtxPtr != nullptr) {
2737        _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
2738    }
2739    if (jIdxPtr != nullptr) {
2740        _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
2741    }
2742    if (primPtr != nullptr) {
2743        _env->ReleaseIntArrayElements(_prim, primPtr, 0);
2744    }
2745
2746    return id;
2747}
2748
2749static jint
2750nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2751{
2752    if (kLogApi) {
2753        ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2754    }
2755    jint vtxCount = 0;
2756    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
2757    return vtxCount;
2758}
2759
2760static jint
2761nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2762{
2763    if (kLogApi) {
2764        ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2765    }
2766    jint idxCount = 0;
2767    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
2768    return idxCount;
2769}
2770
2771static void
2772nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
2773{
2774    if (kLogApi) {
2775        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2776    }
2777
2778    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
2779    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
2780
2781    for(jint i = 0; i < numVtxIDs; i ++) {
2782        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2783        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
2784    }
2785
2786    free(allocs);
2787}
2788
2789static void
2790nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
2791{
2792    if (kLogApi) {
2793        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2794    }
2795
2796    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
2797    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
2798
2799    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
2800
2801    for(jint i = 0; i < numIndices; i ++) {
2802        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2803        const jint prim = (jint)prims[i];
2804        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
2805        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
2806    }
2807
2808    free(allocs);
2809    free(prims);
2810}
2811
2812static jint
2813nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
2814    return (jint)sizeof(void*);
2815}
2816
2817static jobject
2818nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
2819                        jlongArray strideArr, jint xBytesSize,
2820                        jint dimY, jint dimZ) {
2821    if (kLogApi) {
2822        ALOGD("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
2823    }
2824
2825    jlong *jStridePtr = _env->GetLongArrayElements(strideArr, nullptr);
2826    if (jStridePtr == nullptr) {
2827        ALOGE("Failed to get Java array elements: strideArr");
2828        return 0;
2829    }
2830
2831    size_t strideIn = xBytesSize;
2832    void* ptr = nullptr;
2833    if (alloc != 0) {
2834        ptr = rsAllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
2835                                     RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
2836                                     &strideIn, sizeof(size_t));
2837    }
2838
2839    jobject byteBuffer = nullptr;
2840    if (ptr != nullptr) {
2841        size_t bufferSize = strideIn;
2842        jStridePtr[0] = strideIn;
2843        if (dimY > 0) {
2844            bufferSize *= dimY;
2845        }
2846        if (dimZ > 0) {
2847            bufferSize *= dimZ;
2848        }
2849        byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize);
2850    }
2851    _env->ReleaseLongArrayElements(strideArr, jStridePtr, 0);
2852    return byteBuffer;
2853}
2854// ---------------------------------------------------------------------------
2855
2856
2857static const char *classPathName = "android/renderscript/RenderScript";
2858
2859static const JNINativeMethod methods[] = {
2860{"_nInit",                         "()V",                                     (void*)_nInit },
2861
2862{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
2863{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
2864{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
2865{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
2866{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
2867{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
2868
2869{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
2870{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
2871
2872
2873// All methods below are thread protected in java.
2874{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
2875{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
2876{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
2877{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
2878{"rsnContextSetCacheDir",            "(JLjava/lang/String;)V",                (void*)nContextSetCacheDir },
2879{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
2880{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
2881{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
2882{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
2883{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
2884{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
2885{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
2886{"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
2887{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
2888{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
2889{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
2890{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
2891{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
2892
2893{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
2894{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
2895{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
2896{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
2897{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
2898{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
2899
2900{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
2901{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
2902{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
2903
2904{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
2905{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
2906{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
2907{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
2908
2909{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
2910{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
2911
2912{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
2913{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
2914{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
2915{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
2916
2917{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
2918{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
2919
2920{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
2921{"rsnAllocationSetupBufferQueue",    "(JJI)V",                                (void*)nAllocationSetupBufferQueue },
2922{"rsnAllocationShareBufferQueue",    "(JJJ)V",                                (void*)nAllocationShareBufferQueue },
2923{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
2924{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
2925{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
2926{"rsnAllocationIoReceive",           "(JJ)J",                                 (void*)nAllocationIoReceive },
2927{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
2928{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
2929{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
2930{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
2931{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
2932{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
2933{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
2934{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
2935{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
2936{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
2937{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationRead3D },
2938{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
2939{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
2940{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
2941
2942{"rsnAllocationAdapterCreate",       "(JJJ)J",                                (void*)nAllocationAdapterCreate },
2943{"rsnAllocationAdapterOffset",       "(JJIIIIIIIII)V",                        (void*)nAllocationAdapterOffset },
2944
2945{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
2946{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
2947{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
2948{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
2949
2950{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
2951{"rsnScriptReduce",                  "(JJIJJ[I)V",                            (void*)nScriptReduce },
2952{"rsnScriptReduceNew",               "(JJI[JJ[I)V",                           (void*)nScriptReduceNew },
2953
2954{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
2955{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
2956{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
2957{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
2958{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
2959{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
2960{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
2961{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
2962{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
2963{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
2964{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
2965{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
2966
2967{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
2968{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
2969{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
2970{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
2971{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
2972{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
2973{"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
2974{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
2975{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
2976{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
2977{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
2978
2979{"rsnScriptIntrinsicBLAS_Single",    "(JJIIIIIIIIIFJJFJIIII)V",               (void*)nScriptIntrinsicBLAS_Single },
2980{"rsnScriptIntrinsicBLAS_Double",    "(JJIIIIIIIIIDJJDJIIII)V",               (void*)nScriptIntrinsicBLAS_Double },
2981{"rsnScriptIntrinsicBLAS_Complex",   "(JJIIIIIIIIIFFJJFFJIIII)V",             (void*)nScriptIntrinsicBLAS_Complex },
2982{"rsnScriptIntrinsicBLAS_Z",         "(JJIIIIIIIIIDDJJDDJIIII)V",             (void*)nScriptIntrinsicBLAS_Z },
2983
2984{"rsnScriptIntrinsicBLAS_BNNM",      "(JJIIIJIJIJII)V",                       (void*)nScriptIntrinsicBLAS_BNNM },
2985
2986{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
2987
2988{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
2989{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
2990{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
2991
2992{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
2993{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
2994{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
2995
2996{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
2997{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
2998{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
2999{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
3000{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
3001
3002{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
3003
3004{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
3005
3006{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
3007{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
3008{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
3009{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
3010
3011{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
3012{"rsnAllocationGetByteBuffer",       "(JJ[JIII)Ljava/nio/ByteBuffer;",        (void*)nAllocationGetByteBuffer },
3013};
3014
3015static int registerFuncs(JNIEnv *_env)
3016{
3017    return android::AndroidRuntime::registerNativeMethods(
3018            _env, classPathName, methods, NELEM(methods));
3019}
3020
3021// ---------------------------------------------------------------------------
3022
3023jint JNI_OnLoad(JavaVM* vm, void* reserved)
3024{
3025    JNIEnv* env = nullptr;
3026    jint result = -1;
3027
3028    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
3029        ALOGE("ERROR: GetEnv failed\n");
3030        goto bail;
3031    }
3032    assert(env != nullptr);
3033
3034    if (registerFuncs(env) < 0) {
3035        ALOGE("ERROR: Renderscript native registration failed\n");
3036        goto bail;
3037    }
3038
3039    /* success -- return valid version number */
3040    result = JNI_VERSION_1_4;
3041
3042bail:
3043    return result;
3044}
3045