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