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