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