android_renderscript_RenderScript.cpp revision a2dde698a6e08d40aa09692201593e7d3d04aabb
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, true);
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, true);
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, true);
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, true);
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, true);
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, true);
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, true);
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    }
2075
2076    rsScriptForEachMulti((RsContext)con, (RsScript)script, slot,
2077                         in_allocs, in_len, (RsAllocation)aout,
2078                         param_ptr, param_len, sca, sc_size);
2079
2080    if (ains != nullptr) {
2081        _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2082    }
2083
2084    if (params != nullptr) {
2085        _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT);
2086    }
2087
2088    if (limits != nullptr) {
2089        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2090    }
2091}
2092
2093static void
2094nScriptReduce(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
2095              jlong ain, jlong aout, jintArray limits)
2096{
2097    if (kLogApi) {
2098        ALOGD("nScriptReduce, con(%p), s(%p), slot(%i) ain(%" PRId64 ") aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ain, aout);
2099    }
2100
2101    RsScriptCall sc, *sca = nullptr;
2102    uint32_t sc_size = 0;
2103
2104    jint  limit_len = 0;
2105    jint *limit_ptr = nullptr;
2106
2107    // If the caller passed limits, reflect them in the RsScriptCall.
2108    if (limits != nullptr) {
2109        limit_len = _env->GetArrayLength(limits);
2110        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
2111        if (limit_ptr == nullptr) {
2112            ALOGE("Failed to get Java array elements");
2113            return;
2114        }
2115
2116        // We expect to be passed an array [x1, x2] which specifies
2117        // the sub-range for a 1-dimensional reduction.
2118        assert(limit_len == 2);
2119        UNUSED(limit_len);  // As the assert might not be compiled.
2120
2121        sc.xStart     = limit_ptr[0];
2122        sc.xEnd       = limit_ptr[1];
2123        sc.yStart     = 0;
2124        sc.yEnd       = 0;
2125        sc.zStart     = 0;
2126        sc.zEnd       = 0;
2127        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
2128        sc.arrayStart = 0;
2129        sc.arrayEnd = 0;
2130        sc.array2Start = 0;
2131        sc.array2End = 0;
2132        sc.array3Start = 0;
2133        sc.array3End = 0;
2134        sc.array4Start = 0;
2135        sc.array4End = 0;
2136
2137        sca = &sc;
2138        sc_size = sizeof(sc);
2139    }
2140
2141    rsScriptReduce((RsContext)con, (RsScript)script, slot,
2142                   (RsAllocation)ain, (RsAllocation)aout,
2143                   sca, sc_size);
2144
2145    if (limits != nullptr) {
2146        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2147    }
2148}
2149
2150static void
2151nScriptReduceNew(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
2152                 jlongArray ains, jlong aout, jintArray limits)
2153{
2154    if (kLogApi) {
2155        ALOGD("nScriptReduceNew, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
2156    }
2157
2158    if (ains == nullptr) {
2159        ALOGE("At least one input required.");
2160        // TODO (b/20758983): Report back to Java and throw an exception
2161        return;
2162    }
2163    jint in_len = _env->GetArrayLength(ains);
2164    if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
2165        ALOGE("Too many arguments in kernel launch.");
2166        // TODO (b/20758983): Report back to Java and throw an exception
2167        return;
2168    }
2169
2170    jlong *in_ptr = _env->GetLongArrayElements(ains, nullptr);
2171    if (in_ptr == nullptr) {
2172        ALOGE("Failed to get Java array elements");
2173        // TODO (b/20758983): Report back to Java and throw an exception
2174        return;
2175    }
2176
2177    RsAllocation *in_allocs = nullptr;
2178    if (sizeof(RsAllocation) == sizeof(jlong)) {
2179        in_allocs = (RsAllocation*)in_ptr;
2180    } else {
2181        // Convert from 64-bit jlong types to the native pointer type.
2182
2183        in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
2184        if (in_allocs == nullptr) {
2185            ALOGE("Failed launching kernel for lack of memory.");
2186            // TODO (b/20758983): Report back to Java and throw an exception
2187            _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2188            return;
2189        }
2190
2191        for (int index = in_len; --index >= 0;) {
2192            in_allocs[index] = (RsAllocation)in_ptr[index];
2193        }
2194    }
2195
2196    RsScriptCall sc, *sca = nullptr;
2197    uint32_t sc_size = 0;
2198
2199    jint  limit_len = 0;
2200    jint *limit_ptr = nullptr;
2201
2202    if (limits != nullptr) {
2203        limit_len = _env->GetArrayLength(limits);
2204        limit_ptr = _env->GetIntArrayElements(limits, nullptr);
2205        if (limit_ptr == nullptr) {
2206            ALOGE("Failed to get Java array elements");
2207            // TODO (b/20758983): Report back to Java and throw an exception
2208            return;
2209        }
2210
2211        assert(limit_len == 6);
2212        UNUSED(limit_len);  // As the assert might not be compiled.
2213
2214        sc.xStart     = limit_ptr[0];
2215        sc.xEnd       = limit_ptr[1];
2216        sc.yStart     = limit_ptr[2];
2217        sc.yEnd       = limit_ptr[3];
2218        sc.zStart     = limit_ptr[4];
2219        sc.zEnd       = limit_ptr[5];
2220        sc.strategy   = RS_FOR_EACH_STRATEGY_DONT_CARE;
2221        sc.arrayStart = 0;
2222        sc.arrayEnd = 0;
2223        sc.array2Start = 0;
2224        sc.array2End = 0;
2225        sc.array3Start = 0;
2226        sc.array3End = 0;
2227        sc.array4Start = 0;
2228        sc.array4End = 0;
2229
2230        sca = &sc;
2231        sc_size = sizeof(sc);
2232    }
2233
2234    rsScriptReduceNew((RsContext)con, (RsScript)script, slot,
2235                      in_allocs, in_len, (RsAllocation)aout,
2236                      sca, sc_size);
2237
2238    _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
2239
2240    if (limits != nullptr) {
2241        _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
2242    }
2243}
2244
2245// -----------------------------------
2246
2247static jlong
2248nScriptCCreate(JNIEnv *_env, jobject _this, jlong con,
2249               jstring resName, jstring cacheDir,
2250               jbyteArray scriptRef, jint length)
2251{
2252    if (kLogApi) {
2253        ALOGD("nScriptCCreate, con(%p)", (RsContext)con);
2254    }
2255
2256    AutoJavaStringToUTF8 resNameUTF(_env, resName);
2257    AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir);
2258    jlong ret = 0;
2259    jbyte* script_ptr = nullptr;
2260    jint _exception = 0;
2261    jint remaining;
2262    if (!scriptRef) {
2263        _exception = 1;
2264        //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null");
2265        goto exit;
2266    }
2267    if (length < 0) {
2268        _exception = 1;
2269        //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0");
2270        goto exit;
2271    }
2272    remaining = _env->GetArrayLength(scriptRef);
2273    if (remaining < length) {
2274        _exception = 1;
2275        //jniThrowException(_env, "java/lang/IllegalArgumentException",
2276        //        "length > script.length - offset");
2277        goto exit;
2278    }
2279    script_ptr = (jbyte *)
2280        _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
2281    if (script_ptr == nullptr) {
2282        ALOGE("Failed to get Java array elements");
2283        return ret;
2284    }
2285
2286    //rsScriptCSetText((RsContext)con, (const char *)script_ptr, length);
2287
2288    ret = (jlong)(uintptr_t)rsScriptCCreate((RsContext)con,
2289                                resNameUTF.c_str(), resNameUTF.length(),
2290                                cacheDirUTF.c_str(), cacheDirUTF.length(),
2291                                (const char *)script_ptr, length);
2292
2293exit:
2294    if (script_ptr) {
2295        _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr,
2296                _exception ? JNI_ABORT: 0);
2297    }
2298
2299    return (jlong)(uintptr_t)ret;
2300}
2301
2302static jlong
2303nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid)
2304{
2305    if (kLogApi) {
2306        ALOGD("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id,
2307              (void *)eid);
2308    }
2309    return (jlong)(uintptr_t)rsScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid);
2310}
2311
2312static jlong
2313nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig)
2314{
2315    if (kLogApi) {
2316        ALOGD("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
2317              (void *)sid, slot, sig);
2318    }
2319    return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
2320}
2321
2322static jlong
2323nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
2324{
2325    if (kLogApi) {
2326        ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con,
2327              (void *)sid, slot);
2328    }
2329    return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
2330}
2331
2332static jlong
2333nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
2334{
2335    if (kLogApi) {
2336        ALOGD("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid,
2337              slot);
2338    }
2339    return (jlong)(uintptr_t)rsScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot);
2340}
2341
2342static jlong
2343nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src,
2344    jlongArray _dstk, jlongArray _dstf, jlongArray _types)
2345{
2346    if (kLogApi) {
2347        ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
2348    }
2349
2350    jlong id = 0;
2351
2352    RsScriptKernelID* kernelsPtr;
2353    jint kernelsLen = _env->GetArrayLength(_kernels);
2354    jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
2355
2356    RsScriptKernelID* srcPtr;
2357    jint srcLen = _env->GetArrayLength(_src);
2358    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
2359
2360    RsScriptKernelID* dstkPtr;
2361    jint dstkLen = _env->GetArrayLength(_dstk);
2362    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
2363
2364    RsScriptKernelID* dstfPtr;
2365    jint dstfLen = _env->GetArrayLength(_dstf);
2366    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
2367
2368    RsType* typesPtr;
2369    jint typesLen = _env->GetArrayLength(_types);
2370    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
2371
2372    if (jKernelsPtr == nullptr) {
2373        ALOGE("Failed to get Java array elements: kernels");
2374        goto cleanup;
2375    }
2376    if (jSrcPtr == nullptr) {
2377        ALOGE("Failed to get Java array elements: src");
2378        goto cleanup;
2379    }
2380    if (jDstkPtr == nullptr) {
2381        ALOGE("Failed to get Java array elements: dstk");
2382        goto cleanup;
2383    }
2384    if (jDstfPtr == nullptr) {
2385        ALOGE("Failed to get Java array elements: dstf");
2386        goto cleanup;
2387    }
2388    if (jTypesPtr == nullptr) {
2389        ALOGE("Failed to get Java array elements: types");
2390        goto cleanup;
2391    }
2392
2393    kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
2394    for(int i = 0; i < kernelsLen; ++i) {
2395        kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
2396    }
2397
2398    srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
2399    for(int i = 0; i < srcLen; ++i) {
2400        srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
2401    }
2402
2403    dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
2404    for(int i = 0; i < dstkLen; ++i) {
2405        dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
2406    }
2407
2408    dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
2409    for(int i = 0; i < dstfLen; ++i) {
2410        dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
2411    }
2412
2413    typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
2414    for(int i = 0; i < typesLen; ++i) {
2415        typesPtr[i] = (RsType)jTypesPtr[i];
2416    }
2417
2418    id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
2419                               (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
2420                               (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
2421                               (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
2422                               (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID),
2423                               (RsType *)typesPtr, typesLen * sizeof(RsType));
2424
2425    free(kernelsPtr);
2426    free(srcPtr);
2427    free(dstkPtr);
2428    free(dstfPtr);
2429    free(typesPtr);
2430
2431cleanup:
2432    if (jKernelsPtr != nullptr) {
2433        _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
2434    }
2435    if (jSrcPtr != nullptr) {
2436        _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
2437    }
2438    if (jDstkPtr != nullptr) {
2439        _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
2440    }
2441    if (jDstfPtr != nullptr) {
2442        _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
2443    }
2444    if (jTypesPtr != nullptr) {
2445        _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
2446    }
2447
2448    return id;
2449}
2450
2451static void
2452nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2453{
2454    if (kLogApi) {
2455        ALOGD("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2456              (void *)gid, (void *)kid, (void *)alloc);
2457    }
2458    rsScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2459}
2460
2461static void
2462nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc)
2463{
2464    if (kLogApi) {
2465        ALOGD("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con,
2466              (void *)gid, (void *)kid, (void *)alloc);
2467    }
2468    rsScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, (RsAllocation)alloc);
2469}
2470
2471static void
2472nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid)
2473{
2474    if (kLogApi) {
2475        ALOGD("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid);
2476    }
2477    rsScriptGroupExecute((RsContext)con, (RsScriptGroup)gid);
2478}
2479
2480// ---------------------------------------------------------------------------
2481
2482static jlong
2483nProgramStoreCreate(JNIEnv *_env, jobject _this, jlong con,
2484                    jboolean colorMaskR, jboolean colorMaskG, jboolean colorMaskB, jboolean colorMaskA,
2485                    jboolean depthMask, jboolean ditherEnable,
2486                    jint srcFunc, jint destFunc,
2487                    jint depthFunc)
2488{
2489    if (kLogApi) {
2490        ALOGD("nProgramStoreCreate, con(%p)", (RsContext)con);
2491    }
2492    return (jlong)(uintptr_t)rsProgramStoreCreate((RsContext)con, colorMaskR, colorMaskG, colorMaskB, colorMaskA,
2493                                      depthMask, ditherEnable, (RsBlendSrcFunc)srcFunc,
2494                                      (RsBlendDstFunc)destFunc, (RsDepthFunc)depthFunc);
2495}
2496
2497// ---------------------------------------------------------------------------
2498
2499static void
2500nProgramBindConstants(JNIEnv *_env, jobject _this, jlong con, jlong vpv, jint slot, jlong a)
2501{
2502    if (kLogApi) {
2503        ALOGD("nProgramBindConstants, con(%p), vpf(%p), sloat(%i), a(%p)", (RsContext)con,
2504              (RsProgramVertex)vpv, slot, (RsAllocation)a);
2505    }
2506    rsProgramBindConstants((RsContext)con, (RsProgram)vpv, slot, (RsAllocation)a);
2507}
2508
2509static void
2510nProgramBindTexture(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2511{
2512    if (kLogApi) {
2513        ALOGD("nProgramBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2514              (RsProgramFragment)vpf, slot, (RsAllocation)a);
2515    }
2516    rsProgramBindTexture((RsContext)con, (RsProgramFragment)vpf, slot, (RsAllocation)a);
2517}
2518
2519static void
2520nProgramBindSampler(JNIEnv *_env, jobject _this, jlong con, jlong vpf, jint slot, jlong a)
2521{
2522    if (kLogApi) {
2523        ALOGD("nProgramBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", (RsContext)con,
2524              (RsProgramFragment)vpf, slot, (RsSampler)a);
2525    }
2526    rsProgramBindSampler((RsContext)con, (RsProgramFragment)vpf, slot, (RsSampler)a);
2527}
2528
2529// ---------------------------------------------------------------------------
2530
2531static jlong
2532nProgramFragmentCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2533                       jobjectArray texNames, jlongArray params)
2534{
2535    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2536    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2537    jint paramLen = _env->GetArrayLength(params);
2538    if (jParamPtr == nullptr) {
2539        ALOGE("Failed to get Java array elements");
2540        return 0;
2541    }
2542
2543    int texCount = _env->GetArrayLength(texNames);
2544    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2545    const char ** nameArray = names.c_str();
2546    size_t* sizeArray = names.c_str_len();
2547
2548    if (kLogApi) {
2549        ALOGD("nProgramFragmentCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2550    }
2551
2552    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2553    for(int i = 0; i < paramLen; ++i) {
2554        paramPtr[i] = (uintptr_t)jParamPtr[i];
2555    }
2556    jlong ret = (jlong)(uintptr_t)rsProgramFragmentCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2557                                             nameArray, texCount, sizeArray,
2558                                             paramPtr, paramLen);
2559
2560    free(paramPtr);
2561    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2562    return ret;
2563}
2564
2565
2566// ---------------------------------------------------------------------------
2567
2568static jlong
2569nProgramVertexCreate(JNIEnv *_env, jobject _this, jlong con, jstring shader,
2570                     jobjectArray texNames, jlongArray params)
2571{
2572    AutoJavaStringToUTF8 shaderUTF(_env, shader);
2573    jlong *jParamPtr = _env->GetLongArrayElements(params, nullptr);
2574    jint paramLen = _env->GetArrayLength(params);
2575    if (jParamPtr == nullptr) {
2576        ALOGE("Failed to get Java array elements");
2577        return 0;
2578    }
2579
2580    if (kLogApi) {
2581        ALOGD("nProgramVertexCreate, con(%p), paramLen(%i)", (RsContext)con, paramLen);
2582    }
2583
2584    int texCount = _env->GetArrayLength(texNames);
2585    AutoJavaStringArrayToUTF8 names(_env, texNames, texCount);
2586    const char ** nameArray = names.c_str();
2587    size_t* sizeArray = names.c_str_len();
2588
2589    uintptr_t * paramPtr = (uintptr_t*) malloc(sizeof(uintptr_t) * paramLen);
2590    for(int i = 0; i < paramLen; ++i) {
2591        paramPtr[i] = (uintptr_t)jParamPtr[i];
2592    }
2593
2594    jlong ret = (jlong)(uintptr_t)rsProgramVertexCreate((RsContext)con, shaderUTF.c_str(), shaderUTF.length(),
2595                                           nameArray, texCount, sizeArray,
2596                                           paramPtr, paramLen);
2597
2598    free(paramPtr);
2599    _env->ReleaseLongArrayElements(params, jParamPtr, JNI_ABORT);
2600    return ret;
2601}
2602
2603// ---------------------------------------------------------------------------
2604
2605static jlong
2606nProgramRasterCreate(JNIEnv *_env, jobject _this, jlong con, jboolean pointSprite, jint cull)
2607{
2608    if (kLogApi) {
2609        ALOGD("nProgramRasterCreate, con(%p), pointSprite(%i), cull(%i)", (RsContext)con,
2610              pointSprite, cull);
2611    }
2612    return (jlong)(uintptr_t)rsProgramRasterCreate((RsContext)con, pointSprite, (RsCullMode)cull);
2613}
2614
2615
2616// ---------------------------------------------------------------------------
2617
2618static void
2619nContextBindRootScript(JNIEnv *_env, jobject _this, jlong con, jlong script)
2620{
2621    if (kLogApi) {
2622        ALOGD("nContextBindRootScript, con(%p), script(%p)", (RsContext)con, (RsScript)script);
2623    }
2624    rsContextBindRootScript((RsContext)con, (RsScript)script);
2625}
2626
2627static void
2628nContextBindProgramStore(JNIEnv *_env, jobject _this, jlong con, jlong pfs)
2629{
2630    if (kLogApi) {
2631        ALOGD("nContextBindProgramStore, con(%p), pfs(%p)", (RsContext)con, (RsProgramStore)pfs);
2632    }
2633    rsContextBindProgramStore((RsContext)con, (RsProgramStore)pfs);
2634}
2635
2636static void
2637nContextBindProgramFragment(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2638{
2639    if (kLogApi) {
2640        ALOGD("nContextBindProgramFragment, con(%p), pf(%p)", (RsContext)con,
2641              (RsProgramFragment)pf);
2642    }
2643    rsContextBindProgramFragment((RsContext)con, (RsProgramFragment)pf);
2644}
2645
2646static void
2647nContextBindProgramVertex(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2648{
2649    if (kLogApi) {
2650        ALOGD("nContextBindProgramVertex, con(%p), pf(%p)", (RsContext)con, (RsProgramVertex)pf);
2651    }
2652    rsContextBindProgramVertex((RsContext)con, (RsProgramVertex)pf);
2653}
2654
2655static void
2656nContextBindProgramRaster(JNIEnv *_env, jobject _this, jlong con, jlong pf)
2657{
2658    if (kLogApi) {
2659        ALOGD("nContextBindProgramRaster, con(%p), pf(%p)", (RsContext)con, (RsProgramRaster)pf);
2660    }
2661    rsContextBindProgramRaster((RsContext)con, (RsProgramRaster)pf);
2662}
2663
2664
2665// ---------------------------------------------------------------------------
2666
2667static jlong
2668nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter,
2669               jint wrapS, jint wrapT, jint wrapR, jfloat aniso)
2670{
2671    if (kLogApi) {
2672        ALOGD("nSamplerCreate, con(%p)", (RsContext)con);
2673    }
2674    return (jlong)(uintptr_t)rsSamplerCreate((RsContext)con,
2675                                 (RsSamplerValue)magFilter,
2676                                 (RsSamplerValue)minFilter,
2677                                 (RsSamplerValue)wrapS,
2678                                 (RsSamplerValue)wrapT,
2679                                 (RsSamplerValue)wrapR,
2680                                 aniso);
2681}
2682
2683// ---------------------------------------------------------------------------
2684
2685static jlong
2686nMeshCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _vtx, jlongArray _idx, jintArray _prim)
2687{
2688    if (kLogApi) {
2689        ALOGD("nMeshCreate, con(%p)", (RsContext)con);
2690    }
2691
2692    jlong id = 0;
2693
2694    RsAllocation* vtxPtr;
2695    jint vtxLen = _env->GetArrayLength(_vtx);
2696    jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
2697
2698    RsAllocation* idxPtr;
2699    jint idxLen = _env->GetArrayLength(_idx);
2700    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
2701
2702    jint primLen = _env->GetArrayLength(_prim);
2703    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
2704
2705    if (jVtxPtr == nullptr) {
2706        ALOGE("Failed to get Java array elements: vtx");
2707        goto cleanupMesh;
2708    }
2709    if (jIdxPtr == nullptr) {
2710        ALOGE("Failed to get Java array elements: idx");
2711        goto cleanupMesh;
2712    }
2713    if (primPtr == nullptr) {
2714        ALOGE("Failed to get Java array elements: prim");
2715        goto cleanupMesh;
2716    }
2717
2718    vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
2719    for(int i = 0; i < vtxLen; ++i) {
2720        vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
2721    }
2722
2723    idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
2724    for(int i = 0; i < idxLen; ++i) {
2725        idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
2726    }
2727
2728    id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
2729                                        (RsAllocation *)vtxPtr, vtxLen,
2730                                        (RsAllocation *)idxPtr, idxLen,
2731                                        (uint32_t *)primPtr, primLen);
2732
2733    free(vtxPtr);
2734    free(idxPtr);
2735
2736cleanupMesh:
2737    if (jVtxPtr != nullptr) {
2738        _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
2739    }
2740    if (jIdxPtr != nullptr) {
2741        _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
2742    }
2743    if (primPtr != nullptr) {
2744        _env->ReleaseIntArrayElements(_prim, primPtr, 0);
2745    }
2746
2747    return id;
2748}
2749
2750static jint
2751nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2752{
2753    if (kLogApi) {
2754        ALOGD("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2755    }
2756    jint vtxCount = 0;
2757    rsaMeshGetVertexBufferCount((RsContext)con, (RsMesh)mesh, &vtxCount);
2758    return vtxCount;
2759}
2760
2761static jint
2762nMeshGetIndexCount(JNIEnv *_env, jobject _this, jlong con, jlong mesh)
2763{
2764    if (kLogApi) {
2765        ALOGD("nMeshGetIndexCount, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2766    }
2767    jint idxCount = 0;
2768    rsaMeshGetIndexCount((RsContext)con, (RsMesh)mesh, &idxCount);
2769    return idxCount;
2770}
2771
2772static void
2773nMeshGetVertices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _ids, jint numVtxIDs)
2774{
2775    if (kLogApi) {
2776        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2777    }
2778
2779    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation));
2780    rsaMeshGetVertices((RsContext)con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs);
2781
2782    for(jint i = 0; i < numVtxIDs; i ++) {
2783        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2784        _env->SetLongArrayRegion(_ids, i, 1, &alloc);
2785    }
2786
2787    free(allocs);
2788}
2789
2790static void
2791nMeshGetIndices(JNIEnv *_env, jobject _this, jlong con, jlong mesh, jlongArray _idxIds, jintArray _primitives, jint numIndices)
2792{
2793    if (kLogApi) {
2794        ALOGD("nMeshGetVertices, con(%p), Mesh(%p)", (RsContext)con, (RsMesh)mesh);
2795    }
2796
2797    RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation));
2798    uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t));
2799
2800    rsaMeshGetIndices((RsContext)con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices);
2801
2802    for(jint i = 0; i < numIndices; i ++) {
2803        const jlong alloc = (jlong)(uintptr_t)allocs[i];
2804        const jint prim = (jint)prims[i];
2805        _env->SetLongArrayRegion(_idxIds, i, 1, &alloc);
2806        _env->SetIntArrayRegion(_primitives, i, 1, &prim);
2807    }
2808
2809    free(allocs);
2810    free(prims);
2811}
2812
2813static jint
2814nSystemGetPointerSize(JNIEnv *_env, jobject _this) {
2815    return (jint)sizeof(void*);
2816}
2817
2818static jobject
2819nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc,
2820                        jlongArray strideArr, jint xBytesSize,
2821                        jint dimY, jint dimZ) {
2822    if (kLogApi) {
2823        ALOGD("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc);
2824    }
2825
2826    jlong *jStridePtr = _env->GetLongArrayElements(strideArr, nullptr);
2827    if (jStridePtr == nullptr) {
2828        ALOGE("Failed to get Java array elements: strideArr");
2829        return 0;
2830    }
2831
2832    size_t strideIn = xBytesSize;
2833    void* ptr = nullptr;
2834    if (alloc != 0) {
2835        ptr = rsAllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0,
2836                                     RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0,
2837                                     &strideIn, sizeof(size_t));
2838    }
2839
2840    jobject byteBuffer = nullptr;
2841    if (ptr != nullptr) {
2842        size_t bufferSize = strideIn;
2843        jStridePtr[0] = strideIn;
2844        if (dimY > 0) {
2845            bufferSize *= dimY;
2846        }
2847        if (dimZ > 0) {
2848            bufferSize *= dimZ;
2849        }
2850        byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize);
2851    }
2852    _env->ReleaseLongArrayElements(strideArr, jStridePtr, 0);
2853    return byteBuffer;
2854}
2855// ---------------------------------------------------------------------------
2856
2857
2858static const char *classPathName = "android/renderscript/RenderScript";
2859
2860static const JNINativeMethod methods[] = {
2861{"_nInit",                         "()V",                                     (void*)_nInit },
2862
2863{"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
2864{"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
2865{"nDeviceSetConfig",               "(JII)V",                                  (void*)nDeviceSetConfig },
2866{"nContextGetUserMessage",         "(J[I)I",                                  (void*)nContextGetUserMessage },
2867{"nContextGetErrorMessage",        "(J)Ljava/lang/String;",                   (void*)nContextGetErrorMessage },
2868{"nContextPeekMessage",            "(J[I)I",                                  (void*)nContextPeekMessage },
2869
2870{"nContextInitToClient",           "(J)V",                                    (void*)nContextInitToClient },
2871{"nContextDeinitToClient",         "(J)V",                                    (void*)nContextDeinitToClient },
2872
2873
2874// All methods below are thread protected in java.
2875{"rsnContextCreate",                 "(JIII)J",                               (void*)nContextCreate },
2876{"rsnContextCreateGL",               "(JIIIIIIIIIIIIFI)J",                    (void*)nContextCreateGL },
2877{"rsnContextFinish",                 "(J)V",                                  (void*)nContextFinish },
2878{"rsnContextSetPriority",            "(JI)V",                                 (void*)nContextSetPriority },
2879{"rsnContextSetCacheDir",            "(JLjava/lang/String;)V",                (void*)nContextSetCacheDir },
2880{"rsnContextSetSurface",             "(JIILandroid/view/Surface;)V",          (void*)nContextSetSurface },
2881{"rsnContextDestroy",                "(J)V",                                  (void*)nContextDestroy },
2882{"rsnContextDump",                   "(JI)V",                                 (void*)nContextDump },
2883{"rsnContextPause",                  "(J)V",                                  (void*)nContextPause },
2884{"rsnContextResume",                 "(J)V",                                  (void*)nContextResume },
2885{"rsnContextSendMessage",            "(JI[I)V",                               (void*)nContextSendMessage },
2886{"rsnClosureCreate",                 "(JJJ[J[J[I[J[J)J",                      (void*)nClosureCreate },
2887{"rsnInvokeClosureCreate",           "(JJ[B[J[J[I)J",                         (void*)nInvokeClosureCreate },
2888{"rsnClosureSetArg",                 "(JJIJI)V",                              (void*)nClosureSetArg },
2889{"rsnClosureSetGlobal",              "(JJJJI)V",                              (void*)nClosureSetGlobal },
2890{"rsnAssignName",                    "(JJ[B)V",                               (void*)nAssignName },
2891{"rsnGetName",                       "(JJ)Ljava/lang/String;",                (void*)nGetName },
2892{"rsnObjDestroy",                    "(JJ)V",                                 (void*)nObjDestroy },
2893
2894{"rsnFileA3DCreateFromFile",         "(JLjava/lang/String;)J",                (void*)nFileA3DCreateFromFile },
2895{"rsnFileA3DCreateFromAssetStream",  "(JJ)J",                                 (void*)nFileA3DCreateFromAssetStream },
2896{"rsnFileA3DCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;)J",            (void*)nFileA3DCreateFromAsset },
2897{"rsnFileA3DGetNumIndexEntries",     "(JJ)I",                                 (void*)nFileA3DGetNumIndexEntries },
2898{"rsnFileA3DGetIndexEntries",        "(JJI[I[Ljava/lang/String;)V",           (void*)nFileA3DGetIndexEntries },
2899{"rsnFileA3DGetEntryByIndex",        "(JJI)J",                                (void*)nFileA3DGetEntryByIndex },
2900
2901{"rsnFontCreateFromFile",            "(JLjava/lang/String;FI)J",              (void*)nFontCreateFromFile },
2902{"rsnFontCreateFromAssetStream",     "(JLjava/lang/String;FIJ)J",             (void*)nFontCreateFromAssetStream },
2903{"rsnFontCreateFromAsset",        "(JLandroid/content/res/AssetManager;Ljava/lang/String;FI)J",            (void*)nFontCreateFromAsset },
2904
2905{"rsnElementCreate",                 "(JJIZI)J",                              (void*)nElementCreate },
2906{"rsnElementCreate2",                "(J[J[Ljava/lang/String;[I)J",           (void*)nElementCreate2 },
2907{"rsnElementGetNativeData",          "(JJ[I)V",                               (void*)nElementGetNativeData },
2908{"rsnElementGetSubElements",         "(JJ[J[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
2909
2910{"rsnTypeCreate",                    "(JJIIIZZI)J",                           (void*)nTypeCreate },
2911{"rsnTypeGetNativeData",             "(JJ[J)V",                               (void*)nTypeGetNativeData },
2912
2913{"rsnAllocationCreateTyped",         "(JJIIJ)J",                               (void*)nAllocationCreateTyped },
2914{"rsnAllocationCreateFromBitmap",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateFromBitmap },
2915{"rsnAllocationCreateBitmapBackedAllocation",    "(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCreateBitmapBackedAllocation },
2916{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J",      (void*)nAllocationCubeCreateFromBitmap },
2917
2918{"rsnAllocationCopyFromBitmap",      "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyFromBitmap },
2919{"rsnAllocationCopyToBitmap",        "(JJLandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
2920
2921{"rsnAllocationSyncAll",             "(JJI)V",                                (void*)nAllocationSyncAll },
2922{"rsnAllocationSetupBufferQueue",    "(JJI)V",                                (void*)nAllocationSetupBufferQueue },
2923{"rsnAllocationShareBufferQueue",    "(JJJ)V",                                (void*)nAllocationShareBufferQueue },
2924{"rsnAllocationGetSurface",          "(JJ)Landroid/view/Surface;",            (void*)nAllocationGetSurface },
2925{"rsnAllocationSetSurface",          "(JJLandroid/view/Surface;)V",           (void*)nAllocationSetSurface },
2926{"rsnAllocationIoSend",              "(JJ)V",                                 (void*)nAllocationIoSend },
2927{"rsnAllocationIoReceive",           "(JJ)J",                                 (void*)nAllocationIoReceive },
2928{"rsnAllocationData1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationData1D },
2929{"rsnAllocationElementData",         "(JJIIIII[BI)V",                         (void*)nAllocationElementData },
2930{"rsnAllocationData2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationData2D },
2931{"rsnAllocationData2D",              "(JJIIIIIIJIIII)V",                      (void*)nAllocationData2D_alloc },
2932{"rsnAllocationData3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationData3D },
2933{"rsnAllocationData3D",              "(JJIIIIIIIJIIII)V",                     (void*)nAllocationData3D_alloc },
2934{"rsnAllocationRead",                "(JJLjava/lang/Object;IIZ)V",            (void*)nAllocationRead },
2935{"rsnAllocationRead1D",              "(JJIIILjava/lang/Object;IIIZ)V",        (void*)nAllocationRead1D },
2936{"rsnAllocationElementRead",         "(JJIIIII[BI)V",                         (void*)nAllocationElementRead },
2937{"rsnAllocationRead2D",              "(JJIIIIIILjava/lang/Object;IIIZ)V",     (void*)nAllocationRead2D },
2938{"rsnAllocationRead3D",              "(JJIIIIIIILjava/lang/Object;IIIZ)V",    (void*)nAllocationRead3D },
2939{"rsnAllocationGetType",             "(JJ)J",                                 (void*)nAllocationGetType},
2940{"rsnAllocationResize1D",            "(JJI)V",                                (void*)nAllocationResize1D },
2941{"rsnAllocationGenerateMipmaps",     "(JJ)V",                                 (void*)nAllocationGenerateMipmaps },
2942
2943{"rsnAllocationAdapterCreate",       "(JJJ)J",                                (void*)nAllocationAdapterCreate },
2944{"rsnAllocationAdapterOffset",       "(JJIIIIIIIII)V",                        (void*)nAllocationAdapterOffset },
2945
2946{"rsnScriptBindAllocation",          "(JJJI)V",                               (void*)nScriptBindAllocation },
2947{"rsnScriptSetTimeZone",             "(JJ[B)V",                               (void*)nScriptSetTimeZone },
2948{"rsnScriptInvoke",                  "(JJI)V",                                (void*)nScriptInvoke },
2949{"rsnScriptInvokeV",                 "(JJI[B)V",                              (void*)nScriptInvokeV },
2950
2951{"rsnScriptForEach",                 "(JJI[JJ[B[I)V",                         (void*)nScriptForEach },
2952{"rsnScriptReduce",                  "(JJIJJ[I)V",                            (void*)nScriptReduce },
2953{"rsnScriptReduceNew",               "(JJI[JJ[I)V",                           (void*)nScriptReduceNew },
2954
2955{"rsnScriptSetVarI",                 "(JJII)V",                               (void*)nScriptSetVarI },
2956{"rsnScriptGetVarI",                 "(JJI)I",                                (void*)nScriptGetVarI },
2957{"rsnScriptSetVarJ",                 "(JJIJ)V",                               (void*)nScriptSetVarJ },
2958{"rsnScriptGetVarJ",                 "(JJI)J",                                (void*)nScriptGetVarJ },
2959{"rsnScriptSetVarF",                 "(JJIF)V",                               (void*)nScriptSetVarF },
2960{"rsnScriptGetVarF",                 "(JJI)F",                                (void*)nScriptGetVarF },
2961{"rsnScriptSetVarD",                 "(JJID)V",                               (void*)nScriptSetVarD },
2962{"rsnScriptGetVarD",                 "(JJI)D",                                (void*)nScriptGetVarD },
2963{"rsnScriptSetVarV",                 "(JJI[B)V",                              (void*)nScriptSetVarV },
2964{"rsnScriptGetVarV",                 "(JJI[B)V",                              (void*)nScriptGetVarV },
2965{"rsnScriptSetVarVE",                "(JJI[BJ[I)V",                           (void*)nScriptSetVarVE },
2966{"rsnScriptSetVarObj",               "(JJIJ)V",                               (void*)nScriptSetVarObj },
2967
2968{"rsnScriptCCreate",                 "(JLjava/lang/String;Ljava/lang/String;[BI)J",  (void*)nScriptCCreate },
2969{"rsnScriptIntrinsicCreate",         "(JIJ)J",                                (void*)nScriptIntrinsicCreate },
2970{"rsnScriptKernelIDCreate",          "(JJII)J",                               (void*)nScriptKernelIDCreate },
2971{"rsnScriptInvokeIDCreate",          "(JJI)J",                                (void*)nScriptInvokeIDCreate },
2972{"rsnScriptFieldIDCreate",           "(JJI)J",                                (void*)nScriptFieldIDCreate },
2973{"rsnScriptGroupCreate",             "(J[J[J[J[J[J)J",                        (void*)nScriptGroupCreate },
2974{"rsnScriptGroup2Create",            "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create },
2975{"rsnScriptGroupSetInput",           "(JJJJ)V",                               (void*)nScriptGroupSetInput },
2976{"rsnScriptGroupSetOutput",          "(JJJJ)V",                               (void*)nScriptGroupSetOutput },
2977{"rsnScriptGroupExecute",            "(JJ)V",                                 (void*)nScriptGroupExecute },
2978{"rsnScriptGroup2Execute",           "(JJ)V",                                 (void*)nScriptGroup2Execute },
2979
2980{"rsnScriptIntrinsicBLAS_Single",    "(JJIIIIIIIIIFJJFJIIII)V",               (void*)nScriptIntrinsicBLAS_Single },
2981{"rsnScriptIntrinsicBLAS_Double",    "(JJIIIIIIIIIDJJDJIIII)V",               (void*)nScriptIntrinsicBLAS_Double },
2982{"rsnScriptIntrinsicBLAS_Complex",   "(JJIIIIIIIIIFFJJFFJIIII)V",             (void*)nScriptIntrinsicBLAS_Complex },
2983{"rsnScriptIntrinsicBLAS_Z",         "(JJIIIIIIIIIDDJJDDJIIII)V",             (void*)nScriptIntrinsicBLAS_Z },
2984
2985{"rsnScriptIntrinsicBLAS_BNNM",      "(JJIIIJIJIJII)V",                       (void*)nScriptIntrinsicBLAS_BNNM },
2986
2987{"rsnProgramStoreCreate",            "(JZZZZZZIII)J",                         (void*)nProgramStoreCreate },
2988
2989{"rsnProgramBindConstants",          "(JJIJ)V",                               (void*)nProgramBindConstants },
2990{"rsnProgramBindTexture",            "(JJIJ)V",                               (void*)nProgramBindTexture },
2991{"rsnProgramBindSampler",            "(JJIJ)V",                               (void*)nProgramBindSampler },
2992
2993{"rsnProgramFragmentCreate",         "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramFragmentCreate },
2994{"rsnProgramRasterCreate",           "(JZI)J",                                (void*)nProgramRasterCreate },
2995{"rsnProgramVertexCreate",           "(JLjava/lang/String;[Ljava/lang/String;[J)J",              (void*)nProgramVertexCreate },
2996
2997{"rsnContextBindRootScript",         "(JJ)V",                                 (void*)nContextBindRootScript },
2998{"rsnContextBindProgramStore",       "(JJ)V",                                 (void*)nContextBindProgramStore },
2999{"rsnContextBindProgramFragment",    "(JJ)V",                                 (void*)nContextBindProgramFragment },
3000{"rsnContextBindProgramVertex",      "(JJ)V",                                 (void*)nContextBindProgramVertex },
3001{"rsnContextBindProgramRaster",      "(JJ)V",                                 (void*)nContextBindProgramRaster },
3002
3003{"rsnSamplerCreate",                 "(JIIIIIF)J",                            (void*)nSamplerCreate },
3004
3005{"rsnMeshCreate",                    "(J[J[J[I)J",                            (void*)nMeshCreate },
3006
3007{"rsnMeshGetVertexBufferCount",      "(JJ)I",                                 (void*)nMeshGetVertexBufferCount },
3008{"rsnMeshGetIndexCount",             "(JJ)I",                                 (void*)nMeshGetIndexCount },
3009{"rsnMeshGetVertices",               "(JJ[JI)V",                              (void*)nMeshGetVertices },
3010{"rsnMeshGetIndices",                "(JJ[J[II)V",                            (void*)nMeshGetIndices },
3011
3012{"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
3013{"rsnAllocationGetByteBuffer",       "(JJ[JIII)Ljava/nio/ByteBuffer;",        (void*)nAllocationGetByteBuffer },
3014};
3015
3016static int registerFuncs(JNIEnv *_env)
3017{
3018    return android::AndroidRuntime::registerNativeMethods(
3019            _env, classPathName, methods, NELEM(methods));
3020}
3021
3022// ---------------------------------------------------------------------------
3023
3024jint JNI_OnLoad(JavaVM* vm, void* reserved)
3025{
3026    JNIEnv* env = nullptr;
3027    jint result = -1;
3028
3029    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
3030        ALOGE("ERROR: GetEnv failed\n");
3031        goto bail;
3032    }
3033    assert(env != nullptr);
3034
3035    if (registerFuncs(env) < 0) {
3036        ALOGE("ERROR: Renderscript native registration failed\n");
3037        goto bail;
3038    }
3039
3040    /* success -- return valid version number */
3041    result = JNI_VERSION_1_4;
3042
3043bail:
3044    return result;
3045}
3046