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