android_renderscript_RenderScript.cpp revision e4a401fd3e2f777365c2ee9ee277c68065d5b178
1/* 2 * Copyright (C) 2011-2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "libRS_jni" 18 19#include <stdlib.h> 20#include <stdio.h> 21#include <fcntl.h> 22#include <unistd.h> 23#include <math.h> 24#include <android/bitmap.h> 25#include <android/log.h> 26 27#include <rsEnv.h> 28#include "rsDispatch.h" 29#include <dlfcn.h> 30 31//#define LOG_API ALOG 32#define LOG_API(...) 33#define LOG_ERR(...) __android_log_print(ANDROID_LOG_ERROR, "RenderScript JNI", __VA_ARGS__); 34#define RS_JNI_VERSION 2301 35 36#define NELEM(m) (sizeof(m) / sizeof((m)[0])) 37 38template <typename... T> 39void UNUSED(T... t) {} 40#define PER_ARRAY_TYPE(flag, fnc, readonly, ...) { \ 41 jint len = 0; \ 42 void *ptr = nullptr; \ 43 void *srcPtr = nullptr; \ 44 size_t typeBytes = 0; \ 45 jint relFlag = 0; \ 46 if (readonly) { \ 47 /* The on-release mode should only be JNI_ABORT for read-only accesses. */ \ 48 /* readonly = true, also indicates we are copying to the allocation . */ \ 49 relFlag = JNI_ABORT; \ 50 } \ 51 switch(dataType) { \ 52 case RS_TYPE_FLOAT_32: \ 53 len = _env->GetArrayLength((jfloatArray)data); \ 54 ptr = _env->GetFloatArrayElements((jfloatArray)data, flag); \ 55 typeBytes = 4; \ 56 if (usePadding) { \ 57 srcPtr = ptr; \ 58 len = len / 3 * 4; \ 59 if (count == 0) { \ 60 count = len / 4; \ 61 } \ 62 ptr = malloc (len * typeBytes); \ 63 if (readonly) { \ 64 copyWithPadding(ptr, srcPtr, mSize, count); \ 65 fnc(__VA_ARGS__); \ 66 } else { \ 67 fnc(__VA_ARGS__); \ 68 copyWithUnPadding(srcPtr, ptr, mSize, count); \ 69 } \ 70 free(ptr); \ 71 ptr = srcPtr; \ 72 } else { \ 73 fnc(__VA_ARGS__); \ 74 } \ 75 _env->ReleaseFloatArrayElements((jfloatArray)data, (jfloat *)ptr, relFlag); \ 76 return; \ 77 case RS_TYPE_FLOAT_64: \ 78 len = _env->GetArrayLength((jdoubleArray)data); \ 79 ptr = _env->GetDoubleArrayElements((jdoubleArray)data, flag); \ 80 typeBytes = 8; \ 81 if (usePadding) { \ 82 srcPtr = ptr; \ 83 len = len / 3 * 4; \ 84 if (count == 0) { \ 85 count = len / 4; \ 86 } \ 87 ptr = malloc (len * typeBytes); \ 88 if (readonly) { \ 89 copyWithPadding(ptr, srcPtr, mSize, count); \ 90 fnc(__VA_ARGS__); \ 91 } else { \ 92 fnc(__VA_ARGS__); \ 93 copyWithUnPadding(srcPtr, ptr, mSize, count); \ 94 } \ 95 free(ptr); \ 96 ptr = srcPtr; \ 97 } else { \ 98 fnc(__VA_ARGS__); \ 99 } \ 100 _env->ReleaseDoubleArrayElements((jdoubleArray)data, (jdouble *)ptr, relFlag); \ 101 return; \ 102 case RS_TYPE_SIGNED_8: \ 103 case RS_TYPE_UNSIGNED_8: \ 104 len = _env->GetArrayLength((jbyteArray)data); \ 105 ptr = _env->GetByteArrayElements((jbyteArray)data, flag); \ 106 typeBytes = 1; \ 107 if (usePadding) { \ 108 srcPtr = ptr; \ 109 len = len / 3 * 4; \ 110 if (count == 0) { \ 111 count = len / 4; \ 112 } \ 113 ptr = malloc (len * typeBytes); \ 114 if (readonly) { \ 115 copyWithPadding(ptr, srcPtr, mSize, count); \ 116 fnc(__VA_ARGS__); \ 117 } else { \ 118 fnc(__VA_ARGS__); \ 119 copyWithUnPadding(srcPtr, ptr, mSize, count); \ 120 } \ 121 free(ptr); \ 122 ptr = srcPtr; \ 123 } else { \ 124 fnc(__VA_ARGS__); \ 125 } \ 126 _env->ReleaseByteArrayElements((jbyteArray)data, (jbyte*)ptr, relFlag); \ 127 return; \ 128 case RS_TYPE_SIGNED_16: \ 129 case RS_TYPE_UNSIGNED_16: \ 130 len = _env->GetArrayLength((jshortArray)data); \ 131 ptr = _env->GetShortArrayElements((jshortArray)data, flag); \ 132 typeBytes = 2; \ 133 if (usePadding) { \ 134 srcPtr = ptr; \ 135 len = len / 3 * 4; \ 136 if (count == 0) { \ 137 count = len / 4; \ 138 } \ 139 ptr = malloc (len * typeBytes); \ 140 if (readonly) { \ 141 copyWithPadding(ptr, srcPtr, mSize, count); \ 142 fnc(__VA_ARGS__); \ 143 } else { \ 144 fnc(__VA_ARGS__); \ 145 copyWithUnPadding(srcPtr, ptr, mSize, count); \ 146 } \ 147 free(ptr); \ 148 ptr = srcPtr; \ 149 } else { \ 150 fnc(__VA_ARGS__); \ 151 } \ 152 _env->ReleaseShortArrayElements((jshortArray)data, (jshort *)ptr, relFlag); \ 153 return; \ 154 case RS_TYPE_SIGNED_32: \ 155 case RS_TYPE_UNSIGNED_32: \ 156 len = _env->GetArrayLength((jintArray)data); \ 157 ptr = _env->GetIntArrayElements((jintArray)data, flag); \ 158 typeBytes = 4; \ 159 if (usePadding) { \ 160 srcPtr = ptr; \ 161 len = len / 3 * 4; \ 162 if (count == 0) { \ 163 count = len / 4; \ 164 } \ 165 ptr = malloc (len * typeBytes); \ 166 if (readonly) { \ 167 copyWithPadding(ptr, srcPtr, mSize, count); \ 168 fnc(__VA_ARGS__); \ 169 } else { \ 170 fnc(__VA_ARGS__); \ 171 copyWithUnPadding(srcPtr, ptr, mSize, count); \ 172 } \ 173 free(ptr); \ 174 ptr = srcPtr; \ 175 } else { \ 176 fnc(__VA_ARGS__); \ 177 } \ 178 _env->ReleaseIntArrayElements((jintArray)data, (jint *)ptr, relFlag); \ 179 return; \ 180 case RS_TYPE_SIGNED_64: \ 181 case RS_TYPE_UNSIGNED_64: \ 182 len = _env->GetArrayLength((jlongArray)data); \ 183 ptr = _env->GetLongArrayElements((jlongArray)data, flag); \ 184 typeBytes = 8; \ 185 if (usePadding) { \ 186 srcPtr = ptr; \ 187 len = len / 3 * 4; \ 188 if (count == 0) { \ 189 count = len / 4; \ 190 } \ 191 ptr = malloc (len * typeBytes); \ 192 if (readonly) { \ 193 copyWithPadding(ptr, srcPtr, mSize, count); \ 194 fnc(__VA_ARGS__); \ 195 } else { \ 196 fnc(__VA_ARGS__); \ 197 copyWithUnPadding(srcPtr, ptr, mSize, count); \ 198 } \ 199 free(ptr); \ 200 ptr = srcPtr; \ 201 } else { \ 202 fnc(__VA_ARGS__); \ 203 } \ 204 _env->ReleaseLongArrayElements((jlongArray)data, (jlong *)ptr, relFlag); \ 205 return; \ 206 default: \ 207 break; \ 208 } \ 209 UNUSED(len, ptr, srcPtr, typeBytes, relFlag); \ 210} 211 212 213class AutoJavaStringToUTF8 { 214public: 215 AutoJavaStringToUTF8(JNIEnv* env, jstring str) : fEnv(env), fJStr(str) { 216 fCStr = env->GetStringUTFChars(str, NULL); 217 fLength = env->GetStringUTFLength(str); 218 } 219 ~AutoJavaStringToUTF8() { 220 fEnv->ReleaseStringUTFChars(fJStr, fCStr); 221 } 222 const char* c_str() const { return fCStr; } 223 jsize length() const { return fLength; } 224 225private: 226 JNIEnv* fEnv; 227 jstring fJStr; 228 const char* fCStr; 229 jsize fLength; 230}; 231 232class AutoJavaStringArrayToUTF8 { 233public: 234 AutoJavaStringArrayToUTF8(JNIEnv* env, jobjectArray strings, jsize stringsLength) 235 : mEnv(env), mStrings(strings), mStringsLength(stringsLength) { 236 mCStrings = NULL; 237 mSizeArray = NULL; 238 if (stringsLength > 0) { 239 mCStrings = (const char **)calloc(stringsLength, sizeof(char *)); 240 mSizeArray = (size_t*)calloc(stringsLength, sizeof(size_t)); 241 for (jsize ct = 0; ct < stringsLength; ct ++) { 242 jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct); 243 mCStrings[ct] = mEnv->GetStringUTFChars(s, NULL); 244 mSizeArray[ct] = mEnv->GetStringUTFLength(s); 245 } 246 } 247 } 248 ~AutoJavaStringArrayToUTF8() { 249 for (jsize ct=0; ct < mStringsLength; ct++) { 250 jstring s = (jstring)mEnv->GetObjectArrayElement(mStrings, ct); 251 mEnv->ReleaseStringUTFChars(s, mCStrings[ct]); 252 } 253 free(mCStrings); 254 free(mSizeArray); 255 } 256 const char **c_str() const { return mCStrings; } 257 size_t *c_str_len() const { return mSizeArray; } 258 jsize length() const { return mStringsLength; } 259 260private: 261 JNIEnv *mEnv; 262 jobjectArray mStrings; 263 const char **mCStrings; 264 size_t *mSizeArray; 265 jsize mStringsLength; 266}; 267 268 269// --------------------------------------------------------------------------- 270static dispatchTable dispatchTab; 271// Incremental Support lib 272static dispatchTable dispatchTabInc; 273 274static jboolean nLoadSO(JNIEnv *_env, jobject _this, jboolean useNative, jint targetApi, jstring libPath) { 275 void* handle = NULL; 276 if (useNative) { 277 handle = dlopen("libRS.so", RTLD_LAZY | RTLD_LOCAL); 278 } else { 279 // For API 9+, dlopen the full path of libRSSupport. 280 if (libPath != NULL) { 281 const char * libPathJni = _env->GetStringUTFChars(libPath, JNI_FALSE); 282 handle = dlopen(libPathJni, RTLD_LAZY | RTLD_LOCAL); 283 _env->ReleaseStringUTFChars(libPath, libPathJni); 284 } else { 285 handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL); 286 } 287 } 288 if (handle == NULL) { 289 LOG_ERR("couldn't dlopen %s; librsjni version: %d", dlerror(), RS_JNI_VERSION); 290 return false; 291 } 292 293 if (loadSymbols(handle, dispatchTab, targetApi) == false) { 294 LOG_ERR("Dispatch table init failed! librsjni version: %d", RS_JNI_VERSION); 295 dlclose(handle); 296 return false; 297 } 298 LOG_API("Successfully loaded runtime"); 299 return true; 300} 301 302static ioSuppDT ioDispatch; 303static jboolean nLoadIOSO(JNIEnv *_env, jobject _this) { 304 void* handleIO = NULL; 305 handleIO = dlopen("libRSSupportIO.so", RTLD_LAZY | RTLD_LOCAL); 306 if (handleIO == NULL) { 307 LOG_ERR("Couldn't load libRSSupportIO.so, librsjni version: %d", RS_JNI_VERSION); 308 return false; 309 } 310 if (loadIOSuppSyms(handleIO, ioDispatch) == false) { 311 LOG_ERR("libRSSupportIO init failed! librsjni version: %d", RS_JNI_VERSION); 312 return false; 313 } 314 return true; 315} 316 317// --------------------------------------------------------------------------- 318 319static void copyWithPadding(void* ptr, void* srcPtr, int mSize, int count) { 320 int sizeBytesPad = mSize * 4; 321 int sizeBytes = mSize * 3; 322 uint8_t *dst = static_cast<uint8_t *>(ptr); 323 uint8_t *src = static_cast<uint8_t *>(srcPtr); 324 for (int i = 0; i < count; i++) { 325 memcpy(dst, src, sizeBytes); 326 dst += sizeBytesPad; 327 src += sizeBytes; 328 } 329} 330 331static void copyWithUnPadding(void* ptr, void* srcPtr, int mSize, int count) { 332 int sizeBytesPad = mSize * 4; 333 int sizeBytes = mSize * 3; 334 uint8_t *dst = static_cast<uint8_t *>(ptr); 335 uint8_t *src = static_cast<uint8_t *>(srcPtr); 336 for (int i = 0; i < count; i++) { 337 memcpy(dst, src, sizeBytes); 338 dst += sizeBytes; 339 src += sizeBytesPad; 340 } 341} 342 343 344// --------------------------------------------------------------------------- 345 346static void 347nContextFinish(JNIEnv *_env, jobject _this, jlong con) 348{ 349 LOG_API("nContextFinish, con(%p)", (RsContext)con); 350 dispatchTab.ContextFinish((RsContext)con); 351} 352 353static jlong 354nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID, 355 jlong returnValue, jlongArray fieldIDArray, 356 jlongArray valueArray, jintArray sizeArray, 357 jlongArray depClosureArray, jlongArray depFieldIDArray) { 358 jlong ret = 0; 359 360 jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); 361 jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); 362 jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); 363 jsize values_length = _env->GetArrayLength(valueArray); 364 jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr); 365 jsize sizes_length = _env->GetArrayLength(sizeArray); 366 jlong* jDepClosures = 367 _env->GetLongArrayElements(depClosureArray, nullptr); 368 jsize depClosures_length = _env->GetArrayLength(depClosureArray); 369 jlong* jDepFieldIDs = 370 _env->GetLongArrayElements(depFieldIDArray, nullptr); 371 jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray); 372 373 size_t numValues, numDependencies; 374 RsScriptFieldID* fieldIDs; 375 RsClosure* depClosures; 376 RsScriptFieldID* depFieldIDs; 377 378 if (fieldIDs_length != values_length || values_length != sizes_length) { 379 LOG_ERR("Unmatched field IDs, values, and sizes in closure creation."); 380 goto exit; 381 } 382 383 numValues = (size_t)fieldIDs_length; 384 385 if (depClosures_length != depFieldIDs_length) { 386 LOG_ERR("Unmatched closures and field IDs for dependencies in closure creation."); 387 goto exit; 388 } 389 390 numDependencies = (size_t)depClosures_length; 391 392 if (numDependencies > numValues) { 393 LOG_ERR("Unexpected number of dependencies in closure creation"); 394 goto exit; 395 } 396 397 if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) { 398 LOG_ERR("Too many arguments or globals in closure creation"); 399 goto exit; 400 } 401 402 fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues); 403 if (fieldIDs == nullptr) { 404 goto exit; 405 } 406 407 for (size_t i = 0; i < numValues; i++) { 408 fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; 409 } 410 411 depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies); 412 if (depClosures == nullptr) { 413 goto exit; 414 } 415 416 for (size_t i = 0; i < numDependencies; i++) { 417 depClosures[i] = (RsClosure)jDepClosures[i]; 418 } 419 420 depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies); 421 if (depFieldIDs == nullptr) { 422 goto exit; 423 } 424 425 for (size_t i = 0; i < numDependencies; i++) { 426 depFieldIDs[i] = (RsClosure)jDepFieldIDs[i]; 427 } 428 429 ret = (jlong)(uintptr_t)dispatchTab.ClosureCreate( 430 (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue, 431 fieldIDs, numValues, jValues, numValues, 432 (int*)jSizes, numValues, 433 depClosures, numDependencies, 434 depFieldIDs, numDependencies); 435 436exit: 437 438 _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT); 439 _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT); 440 _env->ReleaseIntArrayElements (sizeArray, jSizes, JNI_ABORT); 441 _env->ReleaseLongArrayElements(valueArray, jValues, JNI_ABORT); 442 _env->ReleaseLongArrayElements(fieldIDArray, jFieldIDs, JNI_ABORT); 443 444 return ret; 445} 446 447static jlong 448nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID, 449 jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray, 450 jintArray sizeArray) { 451 jlong ret = 0; 452 453 jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr); 454 jsize jParamLength = _env->GetArrayLength(paramArray); 455 jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); 456 jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); 457 jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); 458 jsize values_length = _env->GetArrayLength(valueArray); 459 jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr); 460 jsize sizes_length = _env->GetArrayLength(sizeArray); 461 462 size_t numValues; 463 RsScriptFieldID* fieldIDs; 464 465 if (fieldIDs_length != values_length || values_length != sizes_length) { 466 LOG_ERR("Unmatched field IDs, values, and sizes in closure creation."); 467 goto exit; 468 } 469 470 numValues = (size_t) fieldIDs_length; 471 472 if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) { 473 LOG_ERR("Too many arguments or globals in closure creation"); 474 goto exit; 475 } 476 477 fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues); 478 if (fieldIDs == nullptr) { 479 goto exit; 480 } 481 482 for (size_t i = 0; i < numValues; i++) { 483 fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; 484 } 485 486 ret = (jlong)(uintptr_t)dispatchTab.InvokeClosureCreate( 487 (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength, 488 fieldIDs, numValues, jValues, numValues, 489 (int*)jSizes, numValues); 490 491exit: 492 493 _env->ReleaseIntArrayElements (sizeArray, jSizes, JNI_ABORT); 494 _env->ReleaseLongArrayElements(valueArray, jValues, JNI_ABORT); 495 _env->ReleaseLongArrayElements(fieldIDArray, jFieldIDs, JNI_ABORT); 496 _env->ReleaseByteArrayElements(paramArray, jParams, JNI_ABORT); 497 498 return ret; 499} 500 501static void 502nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID, 503 jint index, jlong value, jint size) { 504 // Size is signed with -1 indicating the values is an Allocation 505 dispatchTab.ClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index, 506 (uintptr_t)value, size); 507} 508 509static void 510nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID, 511 jlong fieldID, jlong value, jint size) { 512 // Size is signed with -1 indicating the values is an Allocation 513 dispatchTab.ClosureSetGlobal((RsContext)con, (RsClosure)closureID, 514 (RsScriptFieldID)fieldID, (int64_t)value, size); 515} 516 517static long 518nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name, 519 jstring cacheDir, jlongArray closureArray) { 520 jlong ret = 0; 521 522 AutoJavaStringToUTF8 nameUTF(_env, name); 523 AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir); 524 525 jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr); 526 jsize numClosures = _env->GetArrayLength(closureArray); 527 528 RsClosure* closures; 529 530 if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) { 531 LOG_ERR("Too many closures in script group"); 532 goto exit; 533 } 534 535 closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures); 536 if (closures == nullptr) { 537 goto exit; 538 } 539 540 for (int i = 0; i < numClosures; i++) { 541 closures[i] = (RsClosure)jClosures[i]; 542 } 543 544 ret = (jlong)(uintptr_t)dispatchTab.ScriptGroup2Create( 545 (RsContext)con, nameUTF.c_str(), nameUTF.length(), 546 cacheDirUTF.c_str(), cacheDirUTF.length(), 547 closures, numClosures); 548 549exit: 550 551 _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT); 552 553 return ret; 554} 555 556static void 557nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) { 558 dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID); 559} 560 561static void 562nObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj) 563{ 564 LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj); 565 dispatchTab.ObjDestroy((RsContext)con, (void *)obj); 566} 567 568 569static void 570nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA, 571 jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, 572 jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY, 573 jint KL, jint KU, jboolean mUseInc) { 574 RsBlasCall call; 575 memset(&call, 0, sizeof(call)); 576 call.func = (RsBlasFunction)func; 577 call.transA = (RsBlasTranspose)TransA; 578 call.transB = (RsBlasTranspose)TransB; 579 call.side = (RsBlasSide)Side; 580 call.uplo = (RsBlasUplo)Uplo; 581 call.diag = (RsBlasDiag)Diag; 582 call.M = M; 583 call.N = N; 584 call.K = K; 585 call.alpha.f = alpha; 586 call.beta.f = beta; 587 call.incX = incX; 588 call.incY = incY; 589 call.KL = KL; 590 call.KU = KU; 591 592 RsAllocation in_allocs[3]; 593 in_allocs[0] = (RsAllocation)A; 594 in_allocs[1] = (RsAllocation)B; 595 in_allocs[2] = (RsAllocation)C; 596 597 if (mUseInc) { 598 dispatchTab.ContextFinish((RsContext)con); 599 dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0, 600 in_allocs, NELEM(in_allocs), nullptr, 601 &call, sizeof(call), nullptr, 0); 602 } else { 603 dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0, 604 in_allocs, NELEM(in_allocs), nullptr, 605 &call, sizeof(call), nullptr, 0); 606 } 607} 608 609static void 610nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA, 611 jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, 612 jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY, 613 jint KL, jint KU, jboolean mUseInc) { 614 RsBlasCall call; 615 memset(&call, 0, sizeof(call)); 616 call.func = (RsBlasFunction)func; 617 call.transA = (RsBlasTranspose)TransA; 618 call.transB = (RsBlasTranspose)TransB; 619 call.side = (RsBlasSide)Side; 620 call.uplo = (RsBlasUplo)Uplo; 621 call.diag = (RsBlasDiag)Diag; 622 call.M = M; 623 call.N = N; 624 call.K = K; 625 call.alpha.d = alpha; 626 call.beta.d = beta; 627 call.incX = incX; 628 call.incY = incY; 629 call.KL = KL; 630 call.KU = KU; 631 632 RsAllocation in_allocs[3]; 633 in_allocs[0] = (RsAllocation)A; 634 in_allocs[1] = (RsAllocation)B; 635 in_allocs[2] = (RsAllocation)C; 636 637 if (mUseInc) { 638 dispatchTab.ContextFinish((RsContext)con); 639 dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0, 640 in_allocs, NELEM(in_allocs), nullptr, 641 &call, sizeof(call), nullptr, 0); 642 } else { 643 dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0, 644 in_allocs, NELEM(in_allocs), nullptr, 645 &call, sizeof(call), nullptr, 0); 646 } 647} 648 649static void 650nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA, 651 jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, 652 jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX, 653 jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) { 654 RsBlasCall call; 655 memset(&call, 0, sizeof(call)); 656 call.func = (RsBlasFunction)func; 657 call.transA = (RsBlasTranspose)TransA; 658 call.transB = (RsBlasTranspose)TransB; 659 call.side = (RsBlasSide)Side; 660 call.uplo = (RsBlasUplo)Uplo; 661 call.diag = (RsBlasDiag)Diag; 662 call.M = M; 663 call.N = N; 664 call.K = K; 665 call.alpha.c.r = alphaX; 666 call.alpha.c.i = alphaY; 667 call.beta.c.r = betaX; 668 call.beta.c.i = betaY; 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 680 if (mUseInc) { 681 dispatchTab.ContextFinish((RsContext)con); 682 dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0, 683 in_allocs, NELEM(in_allocs), nullptr, 684 &call, sizeof(call), nullptr, 0); 685 } else { 686 dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0, 687 in_allocs, NELEM(in_allocs), nullptr, 688 &call, sizeof(call), nullptr, 0); 689 } 690} 691 692static void 693nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint func, jint TransA, 694 jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, 695 jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX, 696 jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU, jboolean mUseInc) { 697 RsBlasCall call; 698 memset(&call, 0, sizeof(call)); 699 call.func = (RsBlasFunction)func; 700 call.transA = (RsBlasTranspose)TransA; 701 call.transB = (RsBlasTranspose)TransB; 702 call.side = (RsBlasSide)Side; 703 call.uplo = (RsBlasUplo)Uplo; 704 call.diag = (RsBlasDiag)Diag; 705 call.M = M; 706 call.N = N; 707 call.K = K; 708 call.alpha.z.r = alphaX; 709 call.alpha.z.i = alphaY; 710 call.beta.z.r = betaX; 711 call.beta.z.i = betaY; 712 call.incX = incX; 713 call.incY = incY; 714 call.KL = KL; 715 call.KU = KU; 716 717 RsAllocation in_allocs[3]; 718 in_allocs[0] = (RsAllocation)A; 719 in_allocs[1] = (RsAllocation)B; 720 in_allocs[2] = (RsAllocation)C; 721 722 723 if (mUseInc) { 724 dispatchTab.ContextFinish((RsContext)con); 725 dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0, 726 in_allocs, NELEM(in_allocs), nullptr, 727 &call, sizeof(call), nullptr, 0); 728 } else { 729 dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0, 730 in_allocs, NELEM(in_allocs), nullptr, 731 &call, sizeof(call), nullptr, 0); 732 } 733} 734 735 736static void 737nScriptIntrinsicBLAS_BNNM(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong id, jint M, jint N, jint K, 738 jlong A, jint a_offset, jlong B, jint b_offset, jlong C, jint c_offset, 739 jint c_mult_int, jboolean mUseInc) { 740 RsBlasCall call; 741 memset(&call, 0, sizeof(call)); 742 call.func = RsBlas_bnnm; 743 call.M = M; 744 call.N = N; 745 call.K = K; 746 call.a_offset = a_offset & 0xFF; 747 call.b_offset = b_offset & 0xFF; 748 call.c_offset = c_offset; 749 call.c_mult_int = c_mult_int; 750 751 RsAllocation in_allocs[3]; 752 in_allocs[0] = (RsAllocation)A; 753 in_allocs[1] = (RsAllocation)B; 754 in_allocs[2] = (RsAllocation)C; 755 756 if (mUseInc) { 757 dispatchTab.ContextFinish((RsContext)con); 758 dispatchTabInc.ScriptForEachMulti((RsContext)incCon, (RsScript)id, 0, 759 in_allocs, NELEM(in_allocs), nullptr, 760 &call, sizeof(call), nullptr, 0); 761 } else { 762 dispatchTab.ScriptForEachMulti((RsContext)con, (RsScript)id, 0, 763 in_allocs, NELEM(in_allocs), nullptr, 764 &call, sizeof(call), nullptr, 0); 765 } 766} 767// --------------------------------------------------------------------------- 768static jlong 769nDeviceCreate(JNIEnv *_env, jobject _this) 770{ 771 LOG_API("nDeviceCreate"); 772 return (jlong)(uintptr_t)dispatchTab.DeviceCreate(); 773} 774 775static void 776nDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev) 777{ 778 LOG_API("nDeviceDestroy"); 779 return dispatchTab.DeviceDestroy((RsDevice)dev); 780} 781 782static void 783nDeviceSetConfig(JNIEnv *_env, jobject _this, jlong dev, jint p, jint value) 784{ 785 LOG_API("nDeviceSetConfig dev(%p), param(%i), value(%i)", (void *)dev, p, value); 786 return dispatchTab.DeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value); 787} 788 789static jlong 790nContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, 791 jint ct, jstring nativeLibDirJava) 792{ 793 LOG_API("nContextCreate"); 794 // Access the NativeLibDir in the Java Context. 795 const char * nativeLibDir = _env->GetStringUTFChars(nativeLibDirJava, JNI_FALSE); 796 size_t length = (size_t)_env->GetStringUTFLength(nativeLibDirJava); 797 798 jlong id = (jlong)(uintptr_t)dispatchTab.ContextCreate((RsDevice)dev, ver, 799 sdkVer, 800 (RsContextType)ct, 0); 801 if (dispatchTab.SetNativeLibDir) { 802 dispatchTab.SetNativeLibDir((RsContext)id, nativeLibDir, length); 803 } 804 805 _env->ReleaseStringUTFChars(nativeLibDirJava, nativeLibDir); 806 return id; 807} 808 809 810static void 811nContextSetPriority(JNIEnv *_env, jobject _this, jlong con, jint p) 812{ 813 LOG_API("ContextSetPriority, con(%p), priority(%i)", (RsContext)con, p); 814 dispatchTab.ContextSetPriority((RsContext)con, p); 815} 816 817 818 819static void 820nContextDestroy(JNIEnv *_env, jobject _this, jlong con) 821{ 822 LOG_API("nContextDestroy, con(%p)", (RsContext)con); 823 dispatchTab.ContextDestroy((RsContext)con); 824} 825 826static void 827nContextDump(JNIEnv *_env, jobject _this, jlong con, jint bits) 828{ 829 LOG_API("nContextDump, con(%p) bits(%i)", (RsContext)con, bits); 830 dispatchTab.ContextDump((RsContext)con, bits); 831} 832 833 834static jstring 835nContextGetErrorMessage(JNIEnv *_env, jobject _this, jlong con) 836{ 837 LOG_API("nContextGetErrorMessage, con(%p)", (RsContext)con); 838 char buf[1024]; 839 840 size_t receiveLen; 841 uint32_t subID; 842 int id = dispatchTab.ContextGetMessage((RsContext)con, 843 buf, sizeof(buf), 844 &receiveLen, sizeof(receiveLen), 845 &subID, sizeof(subID)); 846 if (!id && receiveLen) { 847 // __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, 848 // "message receive buffer too small. %zu", receiveLen); 849 } 850 return _env->NewStringUTF(buf); 851} 852 853static jint 854nContextGetUserMessage(JNIEnv *_env, jobject _this, jlong con, jintArray data) 855{ 856 jint len = _env->GetArrayLength(data); 857 LOG_API("nContextGetMessage, con(%p), len(%i)", (RsContext)con, len); 858 jint *ptr = _env->GetIntArrayElements(data, NULL); 859 size_t receiveLen; 860 uint32_t subID; 861 int id = dispatchTab.ContextGetMessage((RsContext)con, 862 ptr, len * 4, 863 &receiveLen, sizeof(receiveLen), 864 &subID, sizeof(subID)); 865 if (!id && receiveLen) { 866 // __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, 867 // "message receive buffer too small. %zu", receiveLen); 868 } 869 _env->ReleaseIntArrayElements(data, ptr, 0); 870 return (jint)id; 871} 872 873static jint 874nContextPeekMessage(JNIEnv *_env, jobject _this, jlong con, jintArray auxData) 875{ 876 LOG_API("nContextPeekMessage, con(%p)", (RsContext)con); 877 jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL); 878 size_t receiveLen; 879 uint32_t subID; 880 int id = dispatchTab.ContextPeekMessage((RsContext)con, &receiveLen, sizeof(receiveLen), 881 &subID, sizeof(subID)); 882 auxDataPtr[0] = (jint)subID; 883 auxDataPtr[1] = (jint)receiveLen; 884 _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0); 885 return (jint)id; 886} 887 888static void nContextInitToClient(JNIEnv *_env, jobject _this, jlong con) 889{ 890 LOG_API("nContextInitToClient, con(%p)", (RsContext)con); 891 dispatchTab.ContextInitToClient((RsContext)con); 892} 893 894static void nContextDeinitToClient(JNIEnv *_env, jobject _this, jlong con) 895{ 896 LOG_API("nContextDeinitToClient, con(%p)", (RsContext)con); 897 dispatchTab.ContextDeinitToClient((RsContext)con); 898} 899 900static void 901nContextSendMessage(JNIEnv *_env, jobject _this, jlong con, jint id, jintArray data) 902{ 903 jint *ptr = NULL; 904 jint len = 0; 905 if (data) { 906 len = _env->GetArrayLength(data); 907 ptr = _env->GetIntArrayElements(data, NULL); 908 } 909 LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len); 910 dispatchTab.ContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int)); 911 if (data) { 912 _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); 913 } 914} 915 916 917 918static jlong 919nElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, 920 jboolean norm, jint size) 921{ 922 LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con, 923 type, kind, norm, size); 924 return (jlong)(uintptr_t)dispatchTab.ElementCreate((RsContext)con, 925 (RsDataType)type, 926 (RsDataKind)kind, 927 norm, size); 928} 929 930static jlong 931nElementCreate2(JNIEnv *_env, jobject _this, jlong con, 932 jlongArray _ids, jobjectArray _names, jintArray _arraySizes) 933{ 934 int fieldCount = _env->GetArrayLength(_ids); 935 LOG_API("nElementCreate2, con(%p)", (RsContext)con); 936 937 jlong *jIds = _env->GetLongArrayElements(_ids, NULL); 938 jint *jArraySizes = _env->GetIntArrayElements(_arraySizes, NULL); 939 940 RsElement *ids = (RsElement*)malloc(fieldCount * sizeof(RsElement)); 941 uint32_t *arraySizes = (uint32_t *)malloc(fieldCount * sizeof(uint32_t)); 942 943 for(int i = 0; i < fieldCount; i ++) { 944 ids[i] = (RsElement)jIds[i]; 945 arraySizes[i] = (uint32_t)jArraySizes[i]; 946 } 947 948 AutoJavaStringArrayToUTF8 names(_env, _names, fieldCount); 949 950 const char **nameArray = names.c_str(); 951 size_t *sizeArray = names.c_str_len(); 952 953 jlong id = (jlong)(uintptr_t)dispatchTab.ElementCreate2((RsContext)con, (RsElement *)ids, 954 fieldCount, nameArray, 955 fieldCount * sizeof(size_t), sizeArray, 956 (const uint32_t *)arraySizes, fieldCount); 957 958 free(ids); 959 free(arraySizes); 960 _env->ReleaseLongArrayElements(_ids, jIds, JNI_ABORT); 961 _env->ReleaseIntArrayElements(_arraySizes, jArraySizes, JNI_ABORT); 962 return id; 963} 964 965 966 967 968static void 969nElementGetSubElements(JNIEnv *_env, jobject _this, jlong con, jlong id, 970 jlongArray _IDs, 971 jobjectArray _names, 972 jintArray _arraySizes) 973{ 974 uint32_t dataSize = _env->GetArrayLength(_IDs); 975 LOG_API("nElementGetSubElements, con(%p)", (RsContext)con); 976 977 uintptr_t *ids = (uintptr_t *)malloc(dataSize * sizeof(uintptr_t)); 978 const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *)); 979 uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t)); 980 981 dispatchTab.ElementGetSubElements((RsContext)con, (RsElement)id, ids, names, arraySizes, 982 (uint32_t)dataSize); 983 984 for(uint32_t i = 0; i < dataSize; i++) { 985 const jlong id = (jlong)(uintptr_t)ids[i]; 986 const jint arraySize = (jint)arraySizes[i]; 987 _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i])); 988 _env->SetLongArrayRegion(_IDs, i, 1, &id); 989 _env->SetIntArrayRegion(_arraySizes, i, 1, &arraySize); 990 } 991 992 free(ids); 993 free(names); 994 free(arraySizes); 995} 996 997// ----------------------------------- 998 999static jlong 1000nTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid, 1001 jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv) 1002{ 1003 LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)", 1004 (RsContext)con, eid, dimx, dimy, dimz, mips, faces, yuv); 1005 1006 return (jlong)(uintptr_t)dispatchTab.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, 1007 dimz, mips, faces, yuv); 1008} 1009 1010// ----------------------------------- 1011 1012static jlong 1013nAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mips, jint usage, 1014 jlong pointer) 1015{ 1016 LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", 1017 (RsContext)con, (RsElement)type, mips, usage, (void *)pointer); 1018 return (jlong)(uintptr_t) dispatchTab.AllocationCreateTyped((RsContext)con, (RsType)type, 1019 (RsAllocationMipmapControl)mips, 1020 (uint32_t)usage, (uintptr_t)pointer); 1021} 1022 1023static void 1024nAllocationSyncAll(JNIEnv *_env, jobject _this, jlong con, jlong a, jint bits) 1025{ 1026 LOG_API("nAllocationSyncAll, con(%p), a(%p), bits(0x%08x)", (RsContext)con, (RsAllocation)a, bits); 1027 dispatchTab.AllocationSyncAll((RsContext)con, (RsAllocation)a, (RsAllocationUsageType)bits); 1028} 1029 1030static void 1031nAllocationSetSurface(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject sur) 1032{ 1033 ioDispatch.sAllocationSetSurface(_env, _this, (RsContext)con, (RsAllocation)alloc, sur, dispatchTab); 1034} 1035 1036static void 1037nAllocationIoSend(JNIEnv *_env, jobject _this, jlong con, jlong alloc) 1038{ 1039 dispatchTab.AllocationIoSend((RsContext)con, (RsAllocation)alloc); 1040} 1041 1042static void 1043nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, jlong con, jlong alloc) 1044{ 1045 LOG_API("nAllocationGenerateMipmaps, con(%p), a(%p)", (RsContext)con, (RsAllocation)alloc); 1046 dispatchTab.AllocationGenerateMipmaps((RsContext)con, (RsAllocation)alloc); 1047} 1048 1049static size_t GetBitmapSize(JNIEnv *env, jobject jbitmap) { 1050 AndroidBitmapInfo info; 1051 memset(&info, 0, sizeof(info)); 1052 AndroidBitmap_getInfo(env, jbitmap, &info); 1053 size_t s = info.width * info.height; 1054 switch (info.format) { 1055 case ANDROID_BITMAP_FORMAT_RGBA_8888: s *= 4; break; 1056 case ANDROID_BITMAP_FORMAT_RGB_565: s *= 2; break; 1057 case ANDROID_BITMAP_FORMAT_RGBA_4444: s *= 2; break; 1058 } 1059 return s; 1060} 1061 1062static jlong 1063nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, jint mip, 1064 jobject jbitmap, jint usage) 1065{ 1066 jlong id = 0; 1067 void *pixels = NULL; 1068 AndroidBitmap_lockPixels(_env, jbitmap, &pixels); 1069 1070 if (pixels != NULL) { 1071 id = (jlong)(uintptr_t)dispatchTab.AllocationCreateFromBitmap((RsContext)con, 1072 (RsType)type, 1073 (RsAllocationMipmapControl)mip, 1074 pixels, 1075 GetBitmapSize(_env, jbitmap), 1076 usage); 1077 AndroidBitmap_unlockPixels(_env, jbitmap); 1078 } 1079 return id; 1080} 1081 1082static jlong 1083nAllocationCreateBitmapBackedAllocation(JNIEnv *_env, jobject _this, jlong con, jlong type, 1084 jint mip, jobject jbitmap, jint usage) 1085{ 1086 jlong id = 0; 1087 void *pixels = NULL; 1088 AndroidBitmap_lockPixels(_env, jbitmap, &pixels); 1089 1090 if (pixels != NULL) { 1091 id = (jlong)(uintptr_t)dispatchTab.AllocationCreateTyped((RsContext)con, 1092 (RsType)type, 1093 (RsAllocationMipmapControl)mip, 1094 (uint32_t)usage, 1095 (uintptr_t)pixels); 1096 AndroidBitmap_unlockPixels(_env, jbitmap); 1097 } 1098 return id; 1099} 1100 1101static jlong 1102nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong type, 1103 jint mip, jobject jbitmap, jint usage) 1104{ 1105 void *pixels = NULL; 1106 AndroidBitmap_lockPixels(_env, jbitmap, &pixels); 1107 1108 jlong id = 0; 1109 if (pixels != NULL) { 1110 id = (jlong)(uintptr_t)dispatchTab.AllocationCubeCreateFromBitmap((RsContext)con, 1111 (RsType)type, 1112 (RsAllocationMipmapControl)mip, 1113 pixels, 1114 GetBitmapSize(_env, jbitmap), 1115 usage); 1116 AndroidBitmap_unlockPixels(_env, jbitmap); 1117 } 1118 return id; 1119} 1120 1121static void 1122nAllocationCopyFromBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap) 1123{ 1124 AndroidBitmapInfo info; 1125 memset(&info, 0, sizeof(info)); 1126 AndroidBitmap_getInfo(_env, jbitmap, &info); 1127 1128 void *pixels = NULL; 1129 AndroidBitmap_lockPixels(_env, jbitmap, &pixels); 1130 1131 if (pixels != NULL) { 1132 dispatchTab.Allocation2DData((RsContext)con, (RsAllocation)alloc, 0, 0, 0, 1133 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, info.width, 1134 info.height, pixels, GetBitmapSize(_env, jbitmap), 0); 1135 AndroidBitmap_unlockPixels(_env, jbitmap); 1136 } 1137} 1138 1139static void 1140nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jobject jbitmap) 1141{ 1142 AndroidBitmapInfo info; 1143 memset(&info, 0, sizeof(info)); 1144 AndroidBitmap_getInfo(_env, jbitmap, &info); 1145 1146 void *pixels = NULL; 1147 AndroidBitmap_lockPixels(_env, jbitmap, &pixels); 1148 1149 if (pixels != NULL) { 1150 dispatchTab.AllocationCopyToBitmap((RsContext)con, (RsAllocation)alloc, pixels, 1151 GetBitmapSize(_env, jbitmap)); 1152 AndroidBitmap_unlockPixels(_env, jbitmap); 1153 } 1154 //bitmap.notifyPixelsChanged(); 1155} 1156 1157// Copies from the Java object data into the Allocation pointed to by _alloc. 1158static void 1159nAllocationData1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod, 1160 jint count, jobject data, jint sizeBytes, jint dataType, jint mSize, 1161 jboolean usePadding) 1162{ 1163 RsAllocation *alloc = (RsAllocation *)_alloc; 1164 LOG_API("nAllocation1DData, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), " 1165 "dataType(%i)", (RsContext)con, (RsAllocation)alloc, offset, count, sizeBytes, 1166 dataType); 1167 PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation1DData, true, 1168 (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes); 1169} 1170 1171 1172static void 1173nAllocationElementData1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint xoff, 1174 jint lod, jint compIdx, jbyteArray data, jint sizeBytes) 1175{ 1176 jint len = _env->GetArrayLength(data); 1177 LOG_API("nAllocationElementData1D, con(%p), alloc(%p), xoff(%i), comp(%i), len(%i), " 1178 "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, compIdx, len, 1179 sizeBytes); 1180 jbyte *ptr = _env->GetByteArrayElements(data, nullptr); 1181 dispatchTab.Allocation1DElementData((RsContext)con, (RsAllocation)alloc, xoff, 1182 lod, ptr, sizeBytes, compIdx); 1183 _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); 1184} 1185 1186/* 1187static void 1188nAllocationElementData(JNIEnv *_env, jobject _this, jlong con, jlong alloc, 1189 jint xoff, jint yoff, jint zoff, 1190 jint lod, jint compIdx, jbyteArray data, jint sizeBytes) 1191{ 1192 jint len = _env->GetArrayLength(data); 1193 LOG_API("nAllocationElementData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), " 1194 "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len, 1195 sizeBytes); 1196 jbyte *ptr = _env->GetByteArrayElements(data, nullptr); 1197 dispatchTab.AllocationElementData((RsContext)con, (RsAllocation)alloc, 1198 xoff, yoff, zoff, 1199 lod, ptr, sizeBytes, compIdx); 1200 _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); 1201} 1202*/ 1203 1204// Copies from the Java object data into the Allocation pointed to by _alloc. 1205static void 1206nAllocationData2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face, 1207 jint w, jint h, jobject data, jint sizeBytes, jint dataType, jint mSize, 1208 jboolean usePadding) 1209{ 1210 RsAllocation *alloc = (RsAllocation *)_alloc; 1211 RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face; 1212 LOG_API("nAllocation2DData, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) " 1213 "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType); 1214 int count = w * h; 1215 PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation2DData, true, 1216 (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0); 1217} 1218 1219static void 1220nAllocationData2D_alloc(JNIEnv *_env, jobject _this, jlong con, 1221 jlong dstAlloc, jint dstXoff, jint dstYoff, 1222 jint dstMip, jint dstFace, 1223 jint width, jint height, 1224 jlong srcAlloc, jint srcXoff, jint srcYoff, 1225 jint srcMip, jint srcFace) 1226{ 1227 LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i)," 1228 " dstMip(%i), dstFace(%i), width(%i), height(%i)," 1229 " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)", 1230 (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace, 1231 width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace); 1232 1233 dispatchTab.AllocationCopy2DRange((RsContext)con, 1234 (RsAllocation)dstAlloc, 1235 dstXoff, dstYoff, 1236 dstMip, dstFace, 1237 width, height, 1238 (RsAllocation)srcAlloc, 1239 srcXoff, srcYoff, 1240 srcMip, srcFace); 1241} 1242 1243// Copies from the Java object data into the Allocation pointed to by _alloc. 1244static void 1245nAllocationData3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod, 1246 jint w, jint h, jint d, jobject data, jint sizeBytes, jint dataType, 1247 jint mSize, jboolean usePadding) 1248{ 1249 RsAllocation *alloc = (RsAllocation *)_alloc; 1250 LOG_API("nAllocation3DData, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i)," 1251 " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, 1252 lod, w, h, d, sizeBytes); 1253 int count = w * h * d; 1254 PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DData, true, 1255 (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0); 1256} 1257 1258static void 1259nAllocationData3D_alloc(JNIEnv *_env, jobject _this, jlong con, 1260 jlong dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff, 1261 jint dstMip, 1262 jint width, jint height, jint depth, 1263 jlong srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff, 1264 jint srcMip) 1265{ 1266 LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i)," 1267 " dstMip(%i), width(%i), height(%i)," 1268 " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)", 1269 (RsContext)con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace, 1270 width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace); 1271 1272 dispatchTab.AllocationCopy3DRange((RsContext)con, 1273 (RsAllocation)dstAlloc, 1274 dstXoff, dstYoff, dstZoff, dstMip, 1275 width, height, depth, 1276 (RsAllocation)srcAlloc, 1277 srcXoff, srcYoff, srcZoff, srcMip); 1278} 1279 1280// Copies from the Allocation pointed to by _alloc into the Java object data. 1281static void 1282nAllocationRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jobject data, jint dataType, 1283 jint mSize, jboolean usePadding) 1284{ 1285 RsAllocation *alloc = (RsAllocation *)_alloc; 1286 LOG_API("nAllocationRead, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc); 1287 int count = 0; 1288 PER_ARRAY_TYPE(0, dispatchTab.AllocationRead, false, 1289 (RsContext)con, alloc, ptr, len * typeBytes); 1290} 1291 1292// Copies from the Allocation pointed to by _alloc into the Java object data. 1293static void 1294nAllocationRead1D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint offset, jint lod, 1295 jint count, jobject data, jint sizeBytes, jint dataType, 1296 jint mSize, jboolean usePadding) 1297{ 1298 RsAllocation *alloc = (RsAllocation *)_alloc; 1299 LOG_API("nAllocation1DRead, con(%p), adapter(%p), offset(%i), count(%i), sizeBytes(%i), " 1300 "dataType(%i)", (RsContext)con, alloc, offset, count, sizeBytes, dataType); 1301 PER_ARRAY_TYPE(0, dispatchTab.Allocation1DRead, false, 1302 (RsContext)con, alloc, offset, lod, count, ptr, sizeBytes); 1303} 1304 1305// Copies from the Element in the Allocation pointed to by _alloc into the Java array data. 1306/* 1307static void 1308nAllocationElementRead(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, 1309 jint xoff, jint yoff, jint zoff, 1310 jint lod, jint compIdx, jobject data, jint sizeBytes) 1311{ 1312 jint len = _env->GetArrayLength(data); 1313 LOG_API("nAllocationElementRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), comp(%i), len(%i), " 1314 "sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, compIdx, len, 1315 sizeBytes); 1316 jbyte *ptr = _env->GetByteArrayElements(data, nullptr); 1317 dispatchTab.AllocationElementRead((RsContext)con, (RsAllocation)alloc, 1318 xoff, yoff, zoff, 1319 lod, ptr, sizeBytes, compIdx); 1320 _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); 1321} 1322*/ 1323 1324// Copies from the Allocation pointed to by _alloc into the Java object data. 1325static void 1326nAllocationRead2D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint lod, jint _face, 1327 jint w, jint h, jobject data, jint sizeBytes, jint dataType, 1328 jint mSize, jboolean usePadding) 1329{ 1330 RsAllocation *alloc = (RsAllocation *)_alloc; 1331 RsAllocationCubemapFace face = (RsAllocationCubemapFace)_face; 1332 LOG_API("nAllocation2DRead, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i) " 1333 "type(%i)", (RsContext)con, alloc, xoff, yoff, w, h, sizeBytes, dataType); 1334 int count = w * h; 1335 PER_ARRAY_TYPE(0, dispatchTab.Allocation2DRead, false, 1336 (RsContext)con, alloc, xoff, yoff, lod, face, w, h, ptr, sizeBytes, 0); 1337} 1338 1339// Copies from the Allocation pointed to by _alloc into the Java object data. 1340/* 1341static void 1342nAllocationRead3D(JNIEnv *_env, jobject _this, jlong con, jlong _alloc, jint xoff, jint yoff, jint zoff, jint lod, 1343 jint w, jint h, jint d, jobject data, int sizeBytes, int dataType, 1344 jint mSize, jboolean usePadding) 1345{ 1346 RsAllocation *alloc = (RsAllocation *)_alloc; 1347 LOG_API("nAllocation3DRead, con(%p), alloc(%p), xoff(%i), yoff(%i), zoff(%i), lod(%i), w(%i)," 1348 " h(%i), d(%i), sizeBytes(%i)", (RsContext)con, (RsAllocation)alloc, xoff, yoff, zoff, 1349 lod, w, h, d, sizeBytes); 1350 int count = w * h * d; 1351 PER_ARRAY_TYPE(nullptr, dispatchTab.Allocation3DRead, false, 1352 (RsContext)con, alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0); 1353} 1354*/ 1355 1356static jlong 1357nAllocationGetType(JNIEnv *_env, jobject _this, jlong con, jlong a) 1358{ 1359 LOG_API("nAllocationGetType, con(%p), a(%p)", (RsContext)con, (RsAllocation)a); 1360 return (jlong)(uintptr_t) dispatchTab.AllocationGetType((RsContext)con, (RsAllocation)a); 1361} 1362 1363static void 1364nAllocationResize1D(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint dimX) 1365{ 1366 LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", (RsContext)con, 1367 (RsAllocation)alloc, dimX); 1368 dispatchTab.AllocationResize1D((RsContext)con, (RsAllocation)alloc, dimX); 1369} 1370 1371// ----------------------------------- 1372 1373static void 1374nScriptBindAllocation(JNIEnv *_env, jobject _this, jlong con, jlong script, jlong alloc, jint slot, jboolean mUseInc) 1375{ 1376 LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", 1377 (RsContext)con, (RsScript)script, (RsAllocation)alloc, slot); 1378 if (mUseInc) { 1379 dispatchTabInc.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot); 1380 } else { 1381 dispatchTab.ScriptBindAllocation((RsContext)con, (RsScript)script, (RsAllocation)alloc, slot); 1382 } 1383} 1384 1385static void 1386nScriptSetVarI(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jint val, jboolean mUseInc) 1387{ 1388 LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, 1389 (void *)script, slot, val); 1390 if (mUseInc) { 1391 dispatchTabInc.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val); 1392 } else { 1393 dispatchTab.ScriptSetVarI((RsContext)con, (RsScript)script, slot, val); 1394 } 1395} 1396 1397static void 1398nScriptSetVarObj(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc) 1399{ 1400 LOG_API("nScriptSetVarObj, con(%p), s(%p), slot(%i), val(%i)", (RsContext)con, 1401 (void *)script, slot, val); 1402 if (mUseInc) { 1403 dispatchTabInc.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val); 1404 } else { 1405 dispatchTab.ScriptSetVarObj((RsContext)con, (RsScript)script, slot, (RsObjectBase)val); 1406 } 1407} 1408 1409static void 1410nScriptSetVarJ(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jlong val, jboolean mUseInc) 1411{ 1412 LOG_API("nScriptSetVarJ, con(%p), s(%p), slot(%i), val(%lli)", (RsContext)con, 1413 (void *)script, slot, val); 1414 if (mUseInc) { 1415 dispatchTabInc.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val); 1416 } else { 1417 dispatchTab.ScriptSetVarJ((RsContext)con, (RsScript)script, slot, val); 1418 } 1419} 1420 1421static void 1422nScriptSetVarF(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, float val, jboolean mUseInc) 1423{ 1424 LOG_API("nScriptSetVarF, con(%p), s(%p), slot(%i), val(%f)", (RsContext)con, 1425 (void *)script, slot, val); 1426 if (mUseInc) { 1427 dispatchTabInc.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val); 1428 } else { 1429 dispatchTab.ScriptSetVarF((RsContext)con, (RsScript)script, slot, val); 1430 } 1431} 1432 1433static void 1434nScriptSetVarD(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, double val, jboolean mUseInc) 1435{ 1436 LOG_API("nScriptSetVarD, con(%p), s(%p), slot(%i), val(%lf)", (RsContext)con, 1437 (void *)script, slot, val); 1438 if (mUseInc) { 1439 dispatchTabInc.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val); 1440 } else { 1441 dispatchTab.ScriptSetVarD((RsContext)con, (RsScript)script, slot, val); 1442 } 1443} 1444 1445static void 1446nScriptSetVarV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc) 1447{ 1448 LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot); 1449 jint len = _env->GetArrayLength(data); 1450 jbyte *ptr = _env->GetByteArrayElements(data, NULL); 1451 if (mUseInc) { 1452 dispatchTabInc.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len); 1453 } else { 1454 dispatchTab.ScriptSetVarV((RsContext)con, (RsScript)script, slot, ptr, len); 1455 } 1456 _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); 1457} 1458 1459static void 1460nScriptSetVarVE(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, 1461 jlong elem, jintArray dims, jboolean mUseInc) 1462{ 1463 LOG_API("nScriptSetVarVE, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot); 1464 jint len = _env->GetArrayLength(data); 1465 jbyte *ptr = _env->GetByteArrayElements(data, NULL); 1466 jint dimsLen = _env->GetArrayLength(dims) * sizeof(int); 1467 jint *dimsPtr = _env->GetIntArrayElements(dims, NULL); 1468 if (mUseInc) { 1469 dispatchTabInc.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem, 1470 (const uint32_t *)dimsPtr, dimsLen); 1471 } else { 1472 dispatchTab.ScriptSetVarVE((RsContext)con, (RsScript)script, slot, ptr, len, (RsElement)elem, 1473 (const uint32_t *)dimsPtr, dimsLen); 1474 } 1475 _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); 1476 _env->ReleaseIntArrayElements(dims, dimsPtr, JNI_ABORT); 1477} 1478 1479 1480static void 1481nScriptSetTimeZone(JNIEnv *_env, jobject _this, jlong con, jlong script, jbyteArray timeZone, jboolean mUseInc) 1482{ 1483 LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", (RsContext)con, 1484 (void *)script, (const char *)timeZone); 1485 1486 jint length = _env->GetArrayLength(timeZone); 1487 jbyte* timeZone_ptr; 1488 timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0); 1489 if (mUseInc) { 1490 dispatchTabInc.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length); 1491 } else { 1492 dispatchTab.ScriptSetTimeZone((RsContext)con, (RsScript)script, (const char *)timeZone_ptr, length); 1493 } 1494 1495 if (timeZone_ptr) { 1496 _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0); 1497 } 1498} 1499 1500static void 1501nScriptInvoke(JNIEnv *_env, jobject _this, jlong con, jlong obj, jint slot, jboolean mUseInc) 1502{ 1503 LOG_API("nScriptInvoke, con(%p), script(%p)", (RsContext)con, (void *)obj); 1504 if (mUseInc) { 1505 dispatchTabInc.ScriptInvoke((RsContext)con, (RsScript)obj, slot); 1506 } else { 1507 dispatchTab.ScriptInvoke((RsContext)con, (RsScript)obj, slot); 1508 } 1509} 1510 1511static void 1512nScriptInvokeV(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, jbyteArray data, jboolean mUseInc) 1513{ 1514 LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot); 1515 jint len = _env->GetArrayLength(data); 1516 jbyte *ptr = _env->GetByteArrayElements(data, NULL); 1517 if (mUseInc) { 1518 dispatchTabInc.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len); 1519 } else { 1520 dispatchTab.ScriptInvokeV((RsContext)con, (RsScript)script, slot, ptr, len); 1521 } 1522 _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); 1523} 1524 1525static void 1526nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong incCon, 1527 jlong script, jint slot, jlong ain, jlong aout, jboolean mUseInc) 1528{ 1529 LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot); 1530 if (mUseInc) { 1531 dispatchTab.ContextFinish((RsContext)con); 1532 dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot, 1533 (RsAllocation)ain, (RsAllocation)aout, 1534 NULL, 0, NULL, 0); 1535 } else { 1536 dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot, 1537 (RsAllocation)ain, (RsAllocation)aout, 1538 NULL, 0, NULL, 0); 1539 } 1540} 1541 1542static void 1543nScriptForEachV(JNIEnv *_env, jobject _this, jlong con, jlong incCon, 1544 jlong script, jint slot, jlong ain, jlong aout, jbyteArray params, jboolean mUseInc) 1545{ 1546 LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot); 1547 jint len = _env->GetArrayLength(params); 1548 jbyte *ptr = _env->GetByteArrayElements(params, NULL); 1549 if (mUseInc) { 1550 dispatchTab.ContextFinish((RsContext)con); 1551 dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot, 1552 (RsAllocation)ain, (RsAllocation)aout, 1553 ptr, len, NULL, 0); 1554 } else { 1555 dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot, 1556 (RsAllocation)ain, (RsAllocation)aout, 1557 ptr, len, NULL, 0); 1558 } 1559 _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT); 1560} 1561 1562static void 1563nScriptForEachClipped(JNIEnv *_env, jobject _this, jlong con, jlong incCon, 1564 jlong script, jint slot, jlong ain, jlong aout, 1565 jint xstart, jint xend, 1566 jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc) 1567{ 1568 LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot); 1569 RsScriptCall sc; 1570 sc.xStart = xstart; 1571 sc.xEnd = xend; 1572 sc.yStart = ystart; 1573 sc.yEnd = yend; 1574 sc.zStart = zstart; 1575 sc.zEnd = zend; 1576 sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; 1577 sc.arrayStart = 0; 1578 sc.arrayEnd = 0; 1579 if (mUseInc) { 1580 dispatchTab.ContextFinish((RsContext)con); 1581 dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot, 1582 (RsAllocation)ain, (RsAllocation)aout, 1583 NULL, 0, &sc, sizeof(sc)); 1584 } else { 1585 dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot, 1586 (RsAllocation)ain, (RsAllocation)aout, 1587 NULL, 0, &sc, sizeof(sc)); 1588 } 1589} 1590 1591static void 1592nScriptForEachClippedV(JNIEnv *_env, jobject _this, jlong con, jlong incCon, 1593 jlong script, jint slot, jlong ain, jlong aout, 1594 jbyteArray params, jint xstart, jint xend, 1595 jint ystart, jint yend, jint zstart, jint zend, jboolean mUseInc) 1596{ 1597 LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", (RsContext)con, (void *)script, slot); 1598 jint len = _env->GetArrayLength(params); 1599 jbyte *ptr = _env->GetByteArrayElements(params, NULL); 1600 RsScriptCall sc; 1601 sc.xStart = xstart; 1602 sc.xEnd = xend; 1603 sc.yStart = ystart; 1604 sc.yEnd = yend; 1605 sc.zStart = zstart; 1606 sc.zEnd = zend; 1607 sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; 1608 sc.arrayStart = 0; 1609 sc.arrayEnd = 0; 1610 if (mUseInc) { 1611 dispatchTab.ContextFinish((RsContext)con); 1612 dispatchTabInc.ScriptForEach((RsContext)incCon, (RsScript)script, slot, 1613 (RsAllocation)ain, (RsAllocation)aout, 1614 ptr, len, &sc, sizeof(sc)); 1615 } else { 1616 dispatchTab.ScriptForEach((RsContext)con, (RsScript)script, slot, 1617 (RsAllocation)ain, (RsAllocation)aout, 1618 ptr, len, &sc, sizeof(sc)); 1619 } 1620 _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT); 1621} 1622 1623static void 1624nScriptForEachMulti(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, 1625 jlongArray ains, jlong aout, jbyteArray params, 1626 jintArray limits) 1627{ 1628 LOG_API("nScriptForEach, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout); 1629 1630 jint in_len = 0; 1631 jlong *in_ptr = nullptr; 1632 1633 RsAllocation *in_allocs = nullptr; 1634 1635 if (ains != nullptr) { 1636 in_len = _env->GetArrayLength(ains); 1637 if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) { 1638 LOG_ERR("Too many arguments in kernel launch."); 1639 // TODO (b/20758983): Report back to Java and throw an exception 1640 return; 1641 } 1642 1643 // TODO (b/20760800): Check in_ptr is not null 1644 in_ptr = _env->GetLongArrayElements(ains, nullptr); 1645 if (sizeof(RsAllocation) == sizeof(jlong)) { 1646 in_allocs = (RsAllocation*)in_ptr; 1647 1648 } else { 1649 // Convert from 64-bit jlong types to the native pointer type. 1650 1651 in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation)); 1652 if (in_allocs == nullptr) { 1653 LOG_ERR("Failed launching kernel for lack of memory."); 1654 _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); 1655 return; 1656 } 1657 1658 for (int index = in_len; --index >= 0;) { 1659 in_allocs[index] = (RsAllocation)in_ptr[index]; 1660 } 1661 } 1662 } 1663 1664 jint param_len = 0; 1665 jbyte *param_ptr = nullptr; 1666 1667 if (params != nullptr) { 1668 param_len = _env->GetArrayLength(params); 1669 param_ptr = _env->GetByteArrayElements(params, nullptr); 1670 } 1671 1672 RsScriptCall sc, *sca = nullptr; 1673 uint32_t sc_size = 0; 1674 1675 jint limit_len = 0; 1676 jint *limit_ptr = nullptr; 1677 1678 if (limits != nullptr) { 1679 limit_len = _env->GetArrayLength(limits); 1680 limit_ptr = _env->GetIntArrayElements(limits, nullptr); 1681 1682 if (limit_len != 6) { 1683 LOG_ERR("LaunchOptions cannot be recognized."); 1684 goto exit; 1685 } 1686 1687 sc.xStart = limit_ptr[0]; 1688 sc.xEnd = limit_ptr[1]; 1689 sc.yStart = limit_ptr[2]; 1690 sc.yEnd = limit_ptr[3]; 1691 sc.zStart = limit_ptr[4]; 1692 sc.zEnd = limit_ptr[5]; 1693 sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; 1694 sc.arrayStart = 0; 1695 sc.arrayEnd = 0; 1696 sc.array2Start = 0; 1697 sc.array2End = 0; 1698 sc.array3Start = 0; 1699 sc.array3End = 0; 1700 sc.array4Start = 0; 1701 sc.array4End = 0; 1702 1703 sca = ≻ 1704 } 1705 1706 dispatchTabInc.ScriptForEachMulti((RsContext)con, (RsScript)script, slot, 1707 in_allocs, in_len, (RsAllocation)aout, 1708 param_ptr, param_len, sca, sc_size); 1709 1710exit: 1711 1712 if (ains != nullptr) { 1713 _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); 1714 } 1715 1716 if (params != nullptr) { 1717 _env->ReleaseByteArrayElements(params, param_ptr, JNI_ABORT); 1718 } 1719 1720 if (limits != nullptr) { 1721 _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT); 1722 } 1723} 1724 1725static void 1726nScriptReduce(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, 1727 jlong ain, jlong aout, jintArray limits) 1728{ 1729 LOG_API("nScriptReduce, con(%p), s(%p), slot(%i) ain(%" PRId64 ") aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ain, aout); 1730 1731 RsScriptCall sc, *sca = nullptr; 1732 uint32_t sc_size = 0; 1733 1734 jint limit_len = 0; 1735 jint *limit_ptr = nullptr; 1736 1737 bool limitLengthValid = true; 1738 1739 // If the caller passed limits, reflect them in the RsScriptCall. 1740 if (limits != nullptr) { 1741 limit_len = _env->GetArrayLength(limits); 1742 limit_ptr = _env->GetIntArrayElements(limits, nullptr); 1743 1744 // We expect to be passed an array [x1, x2] which specifies 1745 // the sub-range for a 1-dimensional reduction. 1746 if (limit_len == 2) { 1747 sc.xStart = limit_ptr[0]; 1748 sc.xEnd = limit_ptr[1]; 1749 sc.yStart = 0; 1750 sc.yEnd = 0; 1751 sc.zStart = 0; 1752 sc.zEnd = 0; 1753 sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; 1754 sc.arrayStart = 0; 1755 sc.arrayEnd = 0; 1756 sc.array2Start = 0; 1757 sc.array2End = 0; 1758 sc.array3Start = 0; 1759 sc.array3End = 0; 1760 sc.array4Start = 0; 1761 sc.array4End = 0; 1762 1763 sca = ≻ 1764 sc_size = sizeof(sc); 1765 } else { 1766 LOG_ERR("LaunchOptions cannot be recognized."); 1767 limitLengthValid = false; 1768 } 1769 } 1770 1771 if (limitLengthValid) { 1772 dispatchTab.ScriptReduce((RsContext)con, (RsScript)script, slot, 1773 (RsAllocation)ain, (RsAllocation)aout, 1774 sca, sc_size); 1775 } 1776 1777 if (limits != nullptr) { 1778 _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT); 1779 } 1780} 1781 1782static void 1783nScriptReduceNew(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, 1784 jlongArray ains, jlong aout, jintArray limits) 1785{ 1786 LOG_API("nScriptReduceNew, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout); 1787 1788 if (ains == nullptr) { 1789 LOG_ERR("At least one input required."); 1790 // TODO (b/20758983): Report back to Java and throw an exception 1791 return; 1792 } 1793 jint in_len = _env->GetArrayLength(ains); 1794 if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) { 1795 LOG_ERR("Too many arguments in kernel launch."); 1796 // TODO (b/20758983): Report back to Java and throw an exception 1797 return; 1798 } 1799 1800 jlong *in_ptr = _env->GetLongArrayElements(ains, nullptr); 1801 if (in_ptr == nullptr) { 1802 LOG_ERR("Failed to get Java array elements"); 1803 // TODO (b/20758983): Report back to Java and throw an exception 1804 return; 1805 } 1806 1807 RsAllocation *in_allocs = nullptr; 1808 if (sizeof(RsAllocation) == sizeof(jlong)) { 1809 in_allocs = (RsAllocation*)in_ptr; 1810 } else { 1811 // Convert from 64-bit jlong types to the native pointer type. 1812 1813 in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation)); 1814 if (in_allocs == nullptr) { 1815 LOG_ERR("Failed launching kernel for lack of memory."); 1816 // TODO (b/20758983): Report back to Java and throw an exception 1817 _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); 1818 return; 1819 } 1820 1821 for (int index = in_len; --index >= 0;) { 1822 in_allocs[index] = (RsAllocation)in_ptr[index]; 1823 } 1824 } 1825 1826 RsScriptCall sc, *sca = nullptr; 1827 uint32_t sc_size = 0; 1828 1829 jint limit_len = 0; 1830 jint *limit_ptr = nullptr; 1831 1832 if (limits != nullptr) { 1833 limit_len = _env->GetArrayLength(limits); 1834 limit_ptr = _env->GetIntArrayElements(limits, nullptr); 1835 if (limit_ptr == nullptr) { 1836 LOG_ERR("Failed to get Java array elements"); 1837 // TODO (b/20758983): Report back to Java and throw an exception 1838 _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); 1839 return; 1840 } 1841 1842 if (limit_len != 6) { 1843 LOG_ERR("LaunchOptions cannot be recognized"); 1844 // TODO (b/20758983): Report back to Java and throw an exception 1845 _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); 1846 return; 1847 } 1848 1849 sc.xStart = limit_ptr[0]; 1850 sc.xEnd = limit_ptr[1]; 1851 sc.yStart = limit_ptr[2]; 1852 sc.yEnd = limit_ptr[3]; 1853 sc.zStart = limit_ptr[4]; 1854 sc.zEnd = limit_ptr[5]; 1855 sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; 1856 sc.arrayStart = 0; 1857 sc.arrayEnd = 0; 1858 sc.array2Start = 0; 1859 sc.array2End = 0; 1860 sc.array3Start = 0; 1861 sc.array3End = 0; 1862 sc.array4Start = 0; 1863 sc.array4End = 0; 1864 1865 sca = ≻ 1866 sc_size = sizeof(sc); 1867 } 1868 1869 dispatchTab.ScriptReduceNew((RsContext)con, (RsScript)script, slot, 1870 in_allocs, in_len, (RsAllocation)aout, 1871 sca, sc_size); 1872 1873 _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); 1874 1875 if (limits != nullptr) { 1876 _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT); 1877 } 1878} 1879 1880// ----------------------------------- 1881 1882static jlong 1883nScriptCCreate(JNIEnv *_env, jobject _this, jlong con, 1884 jstring resName, jstring cacheDir, 1885 jbyteArray scriptRef, jint length) 1886{ 1887 LOG_API("nScriptCCreate, con(%p)", (RsContext)con); 1888 1889 AutoJavaStringToUTF8 resNameUTF(_env, resName); 1890 AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir); 1891 jlong ret = 0; 1892 jbyte* script_ptr = NULL; 1893 jint _exception = 0; 1894 jint remaining; 1895 if (!scriptRef) { 1896 _exception = 1; 1897 //jniThrowException(_env, "java/lang/IllegalArgumentException", "script == null"); 1898 goto exit; 1899 } 1900 if (length < 0) { 1901 _exception = 1; 1902 //jniThrowException(_env, "java/lang/IllegalArgumentException", "length < 0"); 1903 goto exit; 1904 } 1905 remaining = _env->GetArrayLength(scriptRef); 1906 if (remaining < length) { 1907 _exception = 1; 1908 //jniThrowException(_env, "java/lang/IllegalArgumentException", 1909 // "length > script.length - offset"); 1910 goto exit; 1911 } 1912 script_ptr = (jbyte *) 1913 _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0); 1914 1915 //rsScriptCSetText(con, (const char *)script_ptr, length); 1916 1917 ret = (jlong)(uintptr_t)dispatchTab.ScriptCCreate((RsContext)con, 1918 resNameUTF.c_str(), resNameUTF.length(), 1919 cacheDirUTF.c_str(), cacheDirUTF.length(), 1920 (const char *)script_ptr, length); 1921 1922exit: 1923 if (script_ptr) { 1924 _env->ReleasePrimitiveArrayCritical(scriptRef, script_ptr, 1925 _exception ? JNI_ABORT: 0); 1926 } 1927 1928 return (jlong)(uintptr_t)ret; 1929} 1930 1931static jlong 1932nScriptIntrinsicCreate(JNIEnv *_env, jobject _this, jlong con, jint id, jlong eid, jboolean mUseInc) 1933{ 1934 LOG_API("nScriptIntrinsicCreate, con(%p) id(%i) element(%p)", (RsContext)con, id, (void *)eid); 1935 if (mUseInc) { 1936 return (jlong)(uintptr_t)dispatchTabInc.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid); 1937 } else { 1938 return (jlong)(uintptr_t)dispatchTab.ScriptIntrinsicCreate((RsContext)con, id, (RsElement)eid); 1939 } 1940} 1941 1942static jlong 1943nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jint sig, jboolean mUseInc) 1944{ 1945 LOG_API("nScriptKernelIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con, 1946 (void *)sid, slot, sig); 1947 if (mUseInc) { 1948 return (jlong)(uintptr_t)dispatchTabInc.ScriptKernelIDCreate((RsContext)con, (RsScript)sid, 1949 slot, sig); 1950 } else { 1951 return (jlong)(uintptr_t)dispatchTab.ScriptKernelIDCreate((RsContext)con, (RsScript)sid, 1952 slot, sig); 1953 } 1954} 1955 1956static jlong 1957nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot) 1958{ 1959 LOG_API("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", con, 1960 (void *)sid, slot); 1961 return (jlong)dispatchTab.ScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot); 1962} 1963 1964static jlong 1965nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot, jboolean mUseInc) 1966{ 1967 LOG_API("nScriptFieldIDCreate, con(%p) script(%p), slot(%i)", (RsContext)con, (void *)sid, slot); 1968 if (mUseInc) { 1969 return (jlong)(uintptr_t)dispatchTabInc.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot); 1970 } else { 1971 return (jlong)(uintptr_t)dispatchTab.ScriptFieldIDCreate((RsContext)con, (RsScript)sid, slot); 1972 } 1973} 1974 1975static jlong 1976nScriptGroupCreate(JNIEnv *_env, jobject _this, jlong con, jlongArray _kernels, jlongArray _src, 1977 jlongArray _dstk, jlongArray _dstf, jlongArray _types) 1978{ 1979 LOG_API("nScriptGroupCreate, con(%p)", (RsContext)con); 1980 1981 jlong id = 0; 1982 1983 RsScriptKernelID* kernelsPtr; 1984 jint kernelsLen = _env->GetArrayLength(_kernels); 1985 jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr); 1986 1987 RsScriptKernelID* srcPtr; 1988 jint srcLen = _env->GetArrayLength(_src); 1989 jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr); 1990 1991 RsScriptKernelID* dstkPtr; 1992 jint dstkLen = _env->GetArrayLength(_dstk); 1993 jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr); 1994 1995 RsScriptKernelID* dstfPtr; 1996 jint dstfLen = _env->GetArrayLength(_dstf); 1997 jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr); 1998 1999 RsType* typesPtr; 2000 jint typesLen = _env->GetArrayLength(_types); 2001 jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr); 2002 2003 if (jKernelsPtr == nullptr) { 2004 LOG_ERR("Failed to get Java array elements: kernels"); 2005 goto cleanup; 2006 } 2007 if (jSrcPtr == nullptr) { 2008 LOG_ERR("Failed to get Java array elements: src"); 2009 goto cleanup; 2010 } 2011 if (jDstkPtr == nullptr) { 2012 LOG_ERR("Failed to get Java array elements: dstk"); 2013 goto cleanup; 2014 } 2015 if (jDstfPtr == nullptr) { 2016 LOG_ERR("Failed to get Java array elements: dstf"); 2017 goto cleanup; 2018 } 2019 if (jTypesPtr == nullptr) { 2020 LOG_ERR("Failed to get Java array elements: types"); 2021 goto cleanup; 2022 } 2023 2024 kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen); 2025 for(int i = 0; i < kernelsLen; ++i) { 2026 kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i]; 2027 } 2028 2029 srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen); 2030 for(int i = 0; i < srcLen; ++i) { 2031 srcPtr[i] = (RsScriptKernelID)jSrcPtr[i]; 2032 } 2033 2034 dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen); 2035 for(int i = 0; i < dstkLen; ++i) { 2036 dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i]; 2037 } 2038 2039 dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen); 2040 for(int i = 0; i < dstfLen; ++i) { 2041 dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i]; 2042 } 2043 2044 typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen); 2045 for(int i = 0; i < typesLen; ++i) { 2046 typesPtr[i] = (RsType)jTypesPtr[i]; 2047 } 2048 2049 id = (jlong)(uintptr_t) dispatchTab.ScriptGroupCreate((RsContext)con, 2050 (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID), 2051 (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID), 2052 (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID), 2053 (RsScriptFieldID *)dstfPtr, dstfLen * sizeof(RsScriptKernelID), 2054 (RsType *)typesPtr, typesLen * sizeof(RsType)); 2055 2056 free(kernelsPtr); 2057 free(srcPtr); 2058 free(dstkPtr); 2059 free(dstfPtr); 2060 free(typesPtr); 2061 2062cleanup: 2063 if (jKernelsPtr != nullptr) { 2064 _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0); 2065 } 2066 if (jSrcPtr != nullptr) { 2067 _env->ReleaseLongArrayElements(_src, jSrcPtr, 0); 2068 } 2069 if (jDstkPtr != nullptr) { 2070 _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0); 2071 } 2072 if (jDstfPtr != nullptr) { 2073 _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0); 2074 } 2075 if (jTypesPtr != nullptr) { 2076 _env->ReleaseLongArrayElements(_types, jTypesPtr, 0); 2077 } 2078 2079 return id; 2080} 2081 2082static void 2083nScriptGroupSetInput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc) 2084{ 2085 LOG_API("nScriptGroupSetInput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con, 2086 (void *)gid, (void *)kid, (void *)alloc); 2087 dispatchTab.ScriptGroupSetInput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, 2088 (RsAllocation)alloc); 2089} 2090 2091static void 2092nScriptGroupSetOutput(JNIEnv *_env, jobject _this, jlong con, jlong gid, jlong kid, jlong alloc) 2093{ 2094 LOG_API("nScriptGroupSetOutput, con(%p) group(%p), kernelId(%p), alloc(%p)", (RsContext)con, 2095 (void *)gid, (void *)kid, (void *)alloc); 2096 dispatchTab.ScriptGroupSetOutput((RsContext)con, (RsScriptGroup)gid, (RsScriptKernelID)kid, 2097 (RsAllocation)alloc); 2098} 2099 2100static void 2101nScriptGroupExecute(JNIEnv *_env, jobject _this, jlong con, jlong gid) 2102{ 2103 LOG_API("nScriptGroupSetOutput, con(%p) group(%p)", (RsContext)con, (void *)gid); 2104 dispatchTab.ScriptGroupExecute((RsContext)con, (RsScriptGroup)gid); 2105} 2106 2107// --------------------------------------------------------------------------- 2108 2109static jlong 2110nSamplerCreate(JNIEnv *_env, jobject _this, jlong con, jint magFilter, jint minFilter, 2111 jint wrapS, jint wrapT, jint wrapR, jfloat aniso) 2112{ 2113 LOG_API("nSamplerCreate, con(%p)", (RsContext)con); 2114 return (jlong)(uintptr_t)dispatchTab.SamplerCreate((RsContext)con, 2115 (RsSamplerValue)magFilter, 2116 (RsSamplerValue)minFilter, 2117 (RsSamplerValue)wrapS, 2118 (RsSamplerValue)wrapT, 2119 (RsSamplerValue)wrapR, 2120 aniso); 2121} 2122 2123static jint 2124nSystemGetPointerSize(JNIEnv *_env, jobject _this) { 2125 return (jint)sizeof(void*); 2126} 2127 2128// --------------------------------------------------------------------------- 2129// For Incremental Intrinsic Support 2130static jboolean nIncLoadSO(JNIEnv *_env, jobject _this, jint deviceApi, jstring libPath) { 2131 void* handle = NULL; 2132 // For API 9+, dlopen the full path of libRSSupport. 2133 if (libPath != NULL) { 2134 const char * libPathJni = _env->GetStringUTFChars(libPath, JNI_FALSE); 2135 handle = dlopen(libPathJni, RTLD_LAZY | RTLD_LOCAL); 2136 _env->ReleaseStringUTFChars(libPath, libPathJni); 2137 } else { 2138 handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL); 2139 } 2140 2141 if (handle == NULL) { 2142 LOG_ERR("couldn't dlopen %s; librsjni version: %d", dlerror(), RS_JNI_VERSION); 2143 return false; 2144 } 2145 2146 if (loadSymbols(handle, dispatchTabInc, deviceApi) == false) { 2147 LOG_ERR("Dispatch Table init failed! librsjni version: %d", RS_JNI_VERSION); 2148 dlclose(handle); 2149 return false; 2150 } 2151 dispatchTabInc.AllocationCreateStrided = (AllocationCreateStridedFnPtr)dlsym(handle, "rsAllocationCreateStrided"); 2152 if (dispatchTabInc.AllocationCreateStrided == NULL) { 2153 LOG_ERR("Couldn't initialize dispatchTabInc.AllocationCreateStrided"); 2154 dlclose(handle); 2155 return false; 2156 } 2157 LOG_API("Successfully loaded compat runtime"); 2158 return true; 2159} 2160 2161// ----------------------------------- 2162// To create/destroy a dummy context 2163static void 2164nIncObjDestroy(JNIEnv *_env, jobject _this, jlong con, jlong obj) 2165{ 2166 LOG_API("nObjDestroy, con(%p) obj(%p)", (RsContext)con, (void *)obj); 2167 dispatchTabInc.ObjDestroy((RsContext)con, (void *)obj); 2168} 2169 2170 2171static jlong 2172nIncDeviceCreate(JNIEnv *_env, jobject _this) 2173{ 2174 LOG_API("nDeviceCreate"); 2175 return (jlong)(uintptr_t)dispatchTabInc.DeviceCreate(); 2176} 2177 2178static void 2179nIncDeviceDestroy(JNIEnv *_env, jobject _this, jlong dev) 2180{ 2181 LOG_API("nDeviceDestroy"); 2182 return dispatchTabInc.DeviceDestroy((RsDevice)dev); 2183} 2184 2185static jlong 2186nIncContextCreate(JNIEnv *_env, jobject _this, jlong dev, jint ver, jint sdkVer, jint ct) 2187{ 2188 LOG_API("nContextCreate"); 2189 //The compat context for incremental support will be synchronous. 2190 return (jlong)(uintptr_t)dispatchTabInc.ContextCreate((RsDevice)dev, ver, sdkVer, 2191 (RsContextType)ct, 2192 RS_CONTEXT_SYNCHRONOUS); 2193} 2194 2195static void 2196nIncContextFinish(JNIEnv *_env, jobject _this, jlong con) 2197{ 2198 LOG_API("nContextFinish, con(%p)", (RsContext)con); 2199 dispatchTabInc.ContextFinish((RsContext)con); 2200} 2201 2202static void 2203nIncContextDestroy(JNIEnv *_env, jobject _this, jlong con) 2204{ 2205 LOG_API("nContextDestroy, con(%p)", (RsContext)con); 2206 dispatchTabInc.ContextDestroy((RsContext)con); 2207} 2208 2209// ----------------------------------- 2210// Create dummy Element 2211static jlong 2212nIncElementCreate(JNIEnv *_env, jobject _this, jlong con, jlong type, jint kind, jboolean norm, jint size) 2213{ 2214 LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", (RsContext)con, 2215 type, kind, norm, size); 2216 return (jlong)(uintptr_t)dispatchTabInc.ElementCreate((RsContext)con, (RsDataType)type, 2217 (RsDataKind)kind, norm, size); 2218} 2219// ----------------------------------- 2220// Create dummy Type 2221static jlong 2222nIncTypeCreate(JNIEnv *_env, jobject _this, jlong con, jlong eid, 2223 jint dimx, jint dimy, jint dimz, jboolean mips, jboolean faces, jint yuv) 2224{ 2225 LOG_API("nTypeCreate, con(%p) eid(%p), x(%i), y(%i), z(%i), mips(%i), faces(%i), yuv(%i)", 2226 incCon, eid, dimx, dimy, dimz, mips, faces, yuv); 2227 2228 return (jlong)(uintptr_t)dispatchTabInc.TypeCreate((RsContext)con, (RsElement)eid, dimx, dimy, 2229 dimz, mips, faces, yuv); 2230} 2231 2232// ----------------------------------- 2233// Create Allocation from pointer 2234static jlong 2235nIncAllocationCreateTyped(JNIEnv *_env, jobject _this, jlong con, jlong incCon, jlong alloc, jlong type, jint xBytesSize) 2236{ 2237 LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", 2238 incCon, (RsElement)type, mips, usage, (void *)pointer); 2239 size_t strideIn; 2240 void* pIn = NULL; 2241 RsAllocation ainI = NULL; 2242 if (alloc != 0) { 2243 pIn = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0, 2244 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, 2245 &strideIn, sizeof(size_t)); 2246 /* 2247 * By definition stride is a roundup of xBytesSize with requiredAlignment, so requiredAlignment must 2248 * be strictly larger than the difference of (stride - xBytesSize). 2249 * 2250 * We can prove that as long as requiredAlignment satisfies the following two conditions, the 2251 * memory layout will be identical : 2252 * 1. Smaller or equal than stride; 2253 * 2. Larger than minRequiredAlignment. 2254 * 2255 * In this case we can simply choose the first power of 2 that satisfies both conditions. 2256 */ 2257 size_t requiredAlignment = 16; 2258 size_t minRequiredAlignment = strideIn - xBytesSize; 2259 while (requiredAlignment <= minRequiredAlignment) { 2260 requiredAlignment <<= 1; 2261 } 2262 ainI = dispatchTabInc.AllocationCreateStrided((RsContext)incCon, (RsType)type, 2263 RS_ALLOCATION_MIPMAP_NONE, 2264 RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT | RS_ALLOCATION_USAGE_SHARED, 2265 (uintptr_t)pIn, requiredAlignment); 2266 } 2267 return (jlong)(uintptr_t) ainI; 2268} 2269 2270static jobject 2271nAllocationGetByteBuffer(JNIEnv *_env, jobject _this, jlong con, jlong alloc, jint xBytesSize, jint dimY, jint dimZ) 2272{ 2273 LOG_API("nAllocationGetByteBuffer, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc); 2274 size_t strideIn = xBytesSize; 2275 void* ptr = NULL; 2276 if (alloc != 0 && dispatchTab.AllocationGetPointer != nullptr) { 2277 ptr = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0, 2278 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, dimZ, 0, 2279 &strideIn, sizeof(size_t)); 2280 } 2281 if (ptr != NULL) { 2282 size_t bufferSize = strideIn; 2283 if (dimY > 0) { 2284 bufferSize *= dimY; 2285 } 2286 if (dimZ > 0) { 2287 bufferSize *= dimZ; 2288 } 2289 jobject byteBuffer = _env->NewDirectByteBuffer(ptr, (jlong) bufferSize); 2290 return byteBuffer; 2291 } else { 2292 return NULL; 2293 } 2294} 2295 2296static jlong 2297nAllocationGetStride(JNIEnv *_env, jobject _this, jlong con, jlong alloc) 2298{ 2299 LOG_API("nAllocationGetStride, con(%p), alloc(%p)", (RsContext)con, (RsAllocation)alloc); 2300 size_t strideIn; 2301 void* ptr = NULL; 2302 if (alloc != 0 && dispatchTab.AllocationGetPointer != nullptr) { 2303 ptr = dispatchTab.AllocationGetPointer((RsContext)con, (RsAllocation)alloc, 0, 2304 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, 2305 &strideIn, sizeof(size_t)); 2306 } 2307 return (jlong)strideIn; 2308} 2309 2310// --------------------------------------------------------------------------- 2311 2312 2313static const char *classPathName = "android/support/v8/renderscript/RenderScript"; 2314 2315static JNINativeMethod methods[] = { 2316{"nLoadSO", "(ZILjava/lang/String;)Z", (bool*)nLoadSO }, 2317{"nLoadIOSO", "()Z", (bool*)nLoadIOSO }, 2318{"nDeviceCreate", "()J", (void*)nDeviceCreate }, 2319{"nDeviceDestroy", "(J)V", (void*)nDeviceDestroy }, 2320{"nDeviceSetConfig", "(JII)V", (void*)nDeviceSetConfig }, 2321{"nContextGetUserMessage", "(J[I)I", (void*)nContextGetUserMessage }, 2322{"nContextGetErrorMessage", "(J)Ljava/lang/String;", (void*)nContextGetErrorMessage }, 2323{"nContextPeekMessage", "(J[I)I", (void*)nContextPeekMessage }, 2324{"nContextInitToClient", "(J)V", (void*)nContextInitToClient }, 2325{"nContextDeinitToClient", "(J)V", (void*)nContextDeinitToClient }, 2326 2327 2328// All methods below are thread protected in java. 2329{"rsnContextCreate", "(JIIILjava/lang/String;)J", (void*)nContextCreate }, 2330{"rsnContextFinish", "(J)V", (void*)nContextFinish }, 2331{"rsnContextSetPriority", "(JI)V", (void*)nContextSetPriority }, 2332{"rsnContextDestroy", "(J)V", (void*)nContextDestroy }, 2333{"rsnContextDump", "(JI)V", (void*)nContextDump }, 2334{"rsnContextSendMessage", "(JI[I)V", (void*)nContextSendMessage }, 2335{"rsnClosureCreate", "(JJJ[J[J[I[J[J)J", (void*)nClosureCreate }, 2336{"rsnInvokeClosureCreate", "(JJ[B[J[J[I)J", (void*)nInvokeClosureCreate }, 2337{"rsnClosureSetArg", "(JJIJI)V", (void*)nClosureSetArg }, 2338{"rsnClosureSetGlobal", "(JJJJI)V", (void*)nClosureSetGlobal }, 2339{"rsnObjDestroy", "(JJ)V", (void*)nObjDestroy }, 2340 2341{"rsnElementCreate", "(JJIZI)J", (void*)nElementCreate }, 2342{"rsnElementCreate2", "(J[J[Ljava/lang/String;[I)J", (void*)nElementCreate2 }, 2343{"rsnElementGetSubElements", "(JJ[J[Ljava/lang/String;[I)V", (void*)nElementGetSubElements }, 2344 2345{"rsnTypeCreate", "(JJIIIZZI)J", (void*)nTypeCreate }, 2346 2347{"rsnAllocationCreateTyped", "(JJIIJ)J", (void*)nAllocationCreateTyped }, 2348{"rsnAllocationCreateFromBitmap", "(JJILandroid/graphics/Bitmap;I)J", (void*)nAllocationCreateFromBitmap }, 2349{"rsnAllocationCreateBitmapBackedAllocation", "(JJILandroid/graphics/Bitmap;I)J", (void*)nAllocationCreateBitmapBackedAllocation }, 2350{"rsnAllocationCubeCreateFromBitmap","(JJILandroid/graphics/Bitmap;I)J", (void*)nAllocationCubeCreateFromBitmap }, 2351 2352{"rsnAllocationCopyFromBitmap", "(JJLandroid/graphics/Bitmap;)V", (void*)nAllocationCopyFromBitmap }, 2353{"rsnAllocationCopyToBitmap", "(JJLandroid/graphics/Bitmap;)V", (void*)nAllocationCopyToBitmap }, 2354 2355{"rsnAllocationSyncAll", "(JJI)V", (void*)nAllocationSyncAll }, 2356{"rsnAllocationSetSurface", "(JJLandroid/view/Surface;)V", (void*)nAllocationSetSurface }, 2357{"rsnAllocationIoSend", "(JJ)V", (void*)nAllocationIoSend }, 2358{"rsnAllocationData1D", "(JJIIILjava/lang/Object;IIIZ)V", (void*)nAllocationData1D }, 2359{"rsnAllocationElementData1D", "(JJIII[BI)V", (void*)nAllocationElementData1D }, 2360//{"rsnAllocationElementData", "(JJIIIII[BI)V", (void*)nAllocationElementData }, 2361{"rsnAllocationData2D", "(JJIIIIIILjava/lang/Object;IIIZ)V", (void*)nAllocationData2D }, 2362{"rsnAllocationData2D", "(JJIIIIIIJIIII)V", (void*)nAllocationData2D_alloc }, 2363{"rsnAllocationData3D", "(JJIIIIIIILjava/lang/Object;IIIZ)V", (void*)nAllocationData3D }, 2364{"rsnAllocationData3D", "(JJIIIIIIIJIIII)V", (void*)nAllocationData3D_alloc }, 2365{"rsnAllocationRead", "(JJLjava/lang/Object;IIZ)V", (void*)nAllocationRead }, 2366{"rsnAllocationRead1D", "(JJIIILjava/lang/Object;IIIZ)V", (void*)nAllocationRead1D }, 2367//{"rsnAllocationElementRead", "(JJIIIII[BI)V", (void*)nAllocationElementRead }, 2368{"rsnAllocationRead2D", "(JJIIIIIILjava/lang/Object;IIIZ)V", (void*)nAllocationRead2D }, 2369//{"rsnAllocationRead3D", "(JJIIIIIIILjava/lang/Object;IIIZ)V", (void*)nAllocationRead3D }, 2370{"rsnAllocationGetType", "(JJ)J", (void*)nAllocationGetType}, 2371{"rsnAllocationResize1D", "(JJI)V", (void*)nAllocationResize1D }, 2372{"rsnAllocationGenerateMipmaps", "(JJ)V", (void*)nAllocationGenerateMipmaps }, 2373 2374{"rsnScriptBindAllocation", "(JJJIZ)V", (void*)nScriptBindAllocation }, 2375{"rsnScriptSetTimeZone", "(JJ[BZ)V", (void*)nScriptSetTimeZone }, 2376{"rsnScriptInvoke", "(JJIZ)V", (void*)nScriptInvoke }, 2377{"rsnScriptInvokeV", "(JJI[BZ)V", (void*)nScriptInvokeV }, 2378{"rsnScriptForEach", "(JJJIJJZ)V", (void*)nScriptForEach }, 2379{"rsnScriptForEach", "(JJJIJJ[BZ)V", (void*)nScriptForEachV }, 2380{"rsnScriptForEach", "(JJI[JJ[B[I)V", (void*)nScriptForEachMulti }, 2381{"rsnScriptForEachClipped", "(JJJIJJIIIIIIZ)V", (void*)nScriptForEachClipped }, 2382{"rsnScriptForEachClipped", "(JJJIJJ[BIIIIIIZ)V", (void*)nScriptForEachClippedV }, 2383{"rsnScriptReduce", "(JJIJJ[I)V", (void*)nScriptReduce }, 2384{"rsnScriptReduceNew", "(JJI[JJ[I)V", (void*)nScriptReduceNew }, 2385{"rsnScriptSetVarI", "(JJIIZ)V", (void*)nScriptSetVarI }, 2386{"rsnScriptSetVarJ", "(JJIJZ)V", (void*)nScriptSetVarJ }, 2387{"rsnScriptSetVarF", "(JJIFZ)V", (void*)nScriptSetVarF }, 2388{"rsnScriptSetVarD", "(JJIDZ)V", (void*)nScriptSetVarD }, 2389{"rsnScriptSetVarV", "(JJI[BZ)V", (void*)nScriptSetVarV }, 2390{"rsnScriptSetVarVE", "(JJI[BJ[IZ)V", (void*)nScriptSetVarVE }, 2391{"rsnScriptSetVarObj", "(JJIJZ)V", (void*)nScriptSetVarObj }, 2392 2393{"rsnScriptCCreate", "(JLjava/lang/String;Ljava/lang/String;[BI)J", (void*)nScriptCCreate }, 2394{"rsnScriptIntrinsicCreate", "(JIJZ)J", (void*)nScriptIntrinsicCreate }, 2395{"rsnScriptKernelIDCreate", "(JJIIZ)J", (void*)nScriptKernelIDCreate }, 2396{"rsnScriptInvokeIDCreate", "(JJI)J", (void*)nScriptInvokeIDCreate }, 2397{"rsnScriptFieldIDCreate", "(JJIZ)J", (void*)nScriptFieldIDCreate }, 2398{"rsnScriptGroupCreate", "(J[J[J[J[J[J)J", (void*)nScriptGroupCreate }, 2399{"rsnScriptGroup2Create", "(JLjava/lang/String;Ljava/lang/String;[J)J", (void*)nScriptGroup2Create }, 2400{"rsnScriptGroupSetInput", "(JJJJ)V", (void*)nScriptGroupSetInput }, 2401{"rsnScriptGroupSetOutput", "(JJJJ)V", (void*)nScriptGroupSetOutput }, 2402{"rsnScriptGroupExecute", "(JJ)V", (void*)nScriptGroupExecute }, 2403{"rsnScriptGroup2Execute", "(JJ)V", (void*)nScriptGroup2Execute }, 2404 2405{"rsnScriptIntrinsicBLAS_Single", "(JJJIIIIIIIIIFJJFJIIIIZ)V", (void*)nScriptIntrinsicBLAS_Single }, 2406{"rsnScriptIntrinsicBLAS_Double", "(JJJIIIIIIIIIDJJDJIIIIZ)V", (void*)nScriptIntrinsicBLAS_Double }, 2407{"rsnScriptIntrinsicBLAS_Complex", "(JJJIIIIIIIIIFFJJFFJIIIIZ)V", (void*)nScriptIntrinsicBLAS_Complex }, 2408{"rsnScriptIntrinsicBLAS_Z", "(JJJIIIIIIIIIDDJJDDJIIIIZ)V", (void*)nScriptIntrinsicBLAS_Z }, 2409 2410{"rsnScriptIntrinsicBLAS_BNNM", "(JJJIIIJIJIJIIZ)V", (void*)nScriptIntrinsicBLAS_BNNM }, 2411 2412{"rsnSamplerCreate", "(JIIIIIF)J", (void*)nSamplerCreate }, 2413 2414{"rsnSystemGetPointerSize", "()I", (void*)nSystemGetPointerSize }, 2415 2416// Entry points for Inc libRSSupport 2417{"nIncLoadSO", "(ILjava/lang/String;)Z", (bool*)nIncLoadSO }, 2418{"nIncDeviceCreate", "()J", (void*)nIncDeviceCreate }, 2419{"nIncDeviceDestroy", "(J)V", (void*)nIncDeviceDestroy }, 2420{"rsnIncContextCreate", "(JIII)J", (void*)nIncContextCreate }, 2421{"rsnIncContextFinish", "(J)V", (void*)nIncContextFinish }, 2422{"rsnIncContextDestroy", "(J)V", (void*)nIncContextDestroy }, 2423{"rsnIncObjDestroy", "(JJ)V", (void*)nIncObjDestroy }, 2424{"rsnIncElementCreate", "(JJIZI)J", (void*)nIncElementCreate }, 2425{"rsnIncTypeCreate", "(JJIIIZZI)J", (void*)nIncTypeCreate }, 2426{"rsnIncAllocationCreateTyped", "(JJJJI)J", (void*)nIncAllocationCreateTyped }, 2427{"rsnAllocationGetByteBuffer", "(JJIII)Ljava/nio/ByteBuffer;", (void*)nAllocationGetByteBuffer }, 2428{"rsnAllocationGetStride", "(JJ)J", (void*)nAllocationGetStride }, 2429}; 2430 2431// --------------------------------------------------------------------------- 2432 2433jint JNI_OnLoad(JavaVM* vm, void* reserved) 2434{ 2435 JNIEnv* env = NULL; 2436 jclass clazz = NULL; 2437 jint result = -1; 2438 2439 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 2440 // __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, 2441 // "ERROR: GetEnv failed\n"); 2442 goto bail; 2443 } 2444 if (env == NULL) { 2445 // __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL"); 2446 goto bail; 2447 } 2448 2449 clazz = env->FindClass(classPathName); 2450 if (clazz == NULL) { 2451 goto bail; 2452 } 2453 2454 if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) { 2455 // __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, 2456 // "ERROR: MediaPlayer native registration failed\n"); 2457 goto bail; 2458 } 2459 2460 /* success -- return valid version number */ 2461 result = JNI_VERSION_1_4; 2462 2463bail: 2464 return result; 2465} 2466