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