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