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