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