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