rsCpuScript.cpp revision 0b575de8ed0b628d84d256f5846500b0385979bd
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 18 19#include "rsCpuCore.h" 20 21#include "rsCpuScript.h" 22//#include "rsdRuntime.h" 23//#include "rsdAllocation.h" 24//#include "rsCpuIntrinsics.h" 25 26#ifndef RS_SERVER 27#include "utils/Vector.h" 28#include "utils/Timers.h" 29#include "utils/StopWatch.h" 30#endif 31 32#ifdef RS_COMPATIBILITY_LIB 33 #include <dlfcn.h> 34 #include <stdio.h> 35 #include <string.h> 36#else 37 #include <bcc/BCCContext.h> 38 #include <bcc/Renderscript/RSCompilerDriver.h> 39 #include <bcc/Renderscript/RSExecutable.h> 40 #include <bcc/Renderscript/RSInfo.h> 41#endif 42 43namespace android { 44namespace renderscript { 45 46 47#ifdef RS_COMPATIBILITY_LIB 48#define MAXLINE 500 49#define MAKE_STR_HELPER(S) #S 50#define MAKE_STR(S) MAKE_STR_HELPER(S) 51#define EXPORT_VAR_STR "exportVarCount: " 52#define EXPORT_VAR_STR_LEN strlen(EXPORT_VAR_STR) 53#define EXPORT_FUNC_STR "exportFuncCount: " 54#define EXPORT_FUNC_STR_LEN strlen(EXPORT_FUNC_STR) 55#define EXPORT_FOREACH_STR "exportForEachCount: " 56#define EXPORT_FOREACH_STR_LEN strlen(EXPORT_FOREACH_STR) 57#define OBJECT_SLOT_STR "objectSlotCount: " 58#define OBJECT_SLOT_STR_LEN strlen(OBJECT_SLOT_STR) 59 60// Copy up to a newline or size chars from str -> s, updating str 61// Returns s when successful and NULL when '\0' is finally reached. 62static char* strgets(char *s, int size, const char **ppstr) { 63 if (!ppstr || !*ppstr || **ppstr == '\0' || size < 1) { 64 return NULL; 65 } 66 67 int i; 68 for (i = 0; i < (size - 1); i++) { 69 s[i] = **ppstr; 70 (*ppstr)++; 71 if (s[i] == '\0') { 72 return s; 73 } else if (s[i] == '\n') { 74 s[i+1] = '\0'; 75 return s; 76 } 77 } 78 79 // size has been exceeded. 80 s[i] = '\0'; 81 82 return s; 83} 84#endif 85 86RsdCpuScriptImpl::RsdCpuScriptImpl(RsdCpuReferenceImpl *ctx, const Script *s) { 87 mCtx = ctx; 88 mScript = s; 89 90#ifdef RS_COMPATIBILITY_LIB 91 mScriptSO = NULL; 92 mInvokeFunctions = NULL; 93 mForEachFunctions = NULL; 94 mFieldAddress = NULL; 95 mFieldIsObject = NULL; 96 mForEachSignatures = NULL; 97#else 98 mCompilerContext = NULL; 99 mCompilerDriver = NULL; 100 mExecutable = NULL; 101#endif 102 103 mRoot = NULL; 104 mRootExpand = NULL; 105 mInit = NULL; 106 mFreeChildren = NULL; 107 108 109 mBoundAllocs = NULL; 110 mIntrinsicData = NULL; 111 mIsThreadable = true; 112} 113 114 115bool RsdCpuScriptImpl::init(char const *resName, char const *cacheDir, 116 uint8_t const *bitcode, size_t bitcodeSize, 117 uint32_t flags) { 118 //ALOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc); 119 //ALOGE("rsdScriptInit %p %p", rsc, script); 120 121 mCtx->lockMutex(); 122 123#ifndef RS_COMPATIBILITY_LIB 124 bcc::RSExecutable *exec; 125 const bcc::RSInfo *info; 126 127 mCompilerContext = NULL; 128 mCompilerDriver = NULL; 129 mExecutable = NULL; 130 131 mCompilerContext = new bcc::BCCContext(); 132 if (mCompilerContext == NULL) { 133 ALOGE("bcc: FAILS to create compiler context (out of memory)"); 134 mCtx->unlockMutex(); 135 return false; 136 } 137 138 mCompilerDriver = new bcc::RSCompilerDriver(); 139 if (mCompilerDriver == NULL) { 140 ALOGE("bcc: FAILS to create compiler driver (out of memory)"); 141 mCtx->unlockMutex(); 142 return false; 143 } 144 145 mCompilerDriver->setRSRuntimeLookupFunction(lookupRuntimeStub); 146 mCompilerDriver->setRSRuntimeLookupContext(this); 147 148 exec = mCompilerDriver->build(*mCompilerContext, cacheDir, resName, 149 (const char *)bitcode, bitcodeSize, NULL, 150 mCtx->getLinkRuntimeCallback()); 151 152 if (exec == NULL) { 153 ALOGE("bcc: FAILS to prepare executable for '%s'", resName); 154 mCtx->unlockMutex(); 155 return false; 156 } 157 158 mExecutable = exec; 159 160 exec->setThreadable(mIsThreadable); 161 if (!exec->syncInfo()) { 162 ALOGW("bcc: FAILS to synchronize the RS info file to the disk"); 163 } 164 165 mRoot = reinterpret_cast<int (*)()>(exec->getSymbolAddress("root")); 166 mRootExpand = 167 reinterpret_cast<int (*)()>(exec->getSymbolAddress("root.expand")); 168 mInit = reinterpret_cast<void (*)()>(exec->getSymbolAddress("init")); 169 mFreeChildren = 170 reinterpret_cast<void (*)()>(exec->getSymbolAddress(".rs.dtor")); 171 172 173 info = &mExecutable->getInfo(); 174 if (info->getExportVarNames().size()) { 175 mBoundAllocs = new Allocation *[info->getExportVarNames().size()]; 176 memset(mBoundAllocs, 0, sizeof(void *) * info->getExportVarNames().size()); 177 } 178 179#else 180 181#ifndef RS_SERVER 182 String8 scriptSOName(cacheDir); 183 scriptSOName = scriptSOName.getPathDir(); 184 scriptSOName.appendPath("lib"); 185 scriptSOName.append("/librs."); 186#else 187 String8 scriptSOName("lib"); 188#endif 189 scriptSOName.append(resName); 190 scriptSOName.append(".so"); 191 192 //script->mHal.drv = drv; 193 194 //ALOGV("Opening up shared object: %s", scriptSOName.string()); 195 mScriptSO = dlopen(scriptSOName.string(), RTLD_NOW | RTLD_LOCAL); 196 if (mScriptSO == NULL) { 197 ALOGE("Unable to open shared library (%s): %s", 198 scriptSOName.string(), dlerror()); 199 200 // One final attempt to find the library in "/system/lib". 201 // We do this to allow bundled applications to use the compatibility 202 // library fallback path. Those applications don't have a private 203 // library path, so they need to install to the system directly. 204 String8 scriptSONameSystem("/system/lib/librs."); 205 scriptSONameSystem.append(resName); 206 scriptSONameSystem.append(".so"); 207 mScriptSO = dlopen(scriptSONameSystem.string(), RTLD_NOW | RTLD_LOCAL); 208 if (mScriptSO == NULL) { 209 ALOGE("Unable to open system shared library (%s): %s", 210 scriptSONameSystem.string(), dlerror()); 211 goto error; 212 } 213 } 214 215 if (mScriptSO) { 216 char line[MAXLINE]; 217 mRoot = (RootFunc_t) dlsym(mScriptSO, "root"); 218 if (mRoot) { 219 //ALOGE("Found root(): %p", mRoot); 220 } 221 mRootExpand = (RootFunc_t) dlsym(mScriptSO, "root.expand"); 222 if (mRootExpand) { 223 //ALOGE("Found root.expand(): %p", mRootExpand); 224 } 225 mInit = (InvokeFunc_t) dlsym(mScriptSO, "init"); 226 if (mInit) { 227 //ALOGE("Found init(): %p", mInit); 228 } 229 mFreeChildren = (InvokeFunc_t) dlsym(mScriptSO, ".rs.dtor"); 230 if (mFreeChildren) { 231 //ALOGE("Found .rs.dtor(): %p", mFreeChildren); 232 } 233 234 const char *rsInfo = (const char *) dlsym(mScriptSO, ".rs.info"); 235 if (rsInfo) { 236 //ALOGE("Found .rs.info(): %p - %s", rsInfo, rsInfo); 237 } 238 239 size_t varCount = 0; 240 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 241 goto error; 242 } 243 if (sscanf(line, EXPORT_VAR_STR "%zu", &varCount) != 1) { 244 ALOGE("Invalid export var count!: %s", line); 245 goto error; 246 } 247 248 mExportedVariableCount = varCount; 249 //ALOGE("varCount: %zu", varCount); 250 if (varCount > 0) { 251 // Start by creating/zeroing this member, since we don't want to 252 // accidentally clean up invalid pointers later (if we error out). 253 mFieldIsObject = new bool[varCount]; 254 if (mFieldIsObject == NULL) { 255 goto error; 256 } 257 memset(mFieldIsObject, 0, varCount * sizeof(*mFieldIsObject)); 258 mFieldAddress = new void*[varCount]; 259 if (mFieldAddress == NULL) { 260 goto error; 261 } 262 for (size_t i = 0; i < varCount; ++i) { 263 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 264 goto error; 265 } 266 char *c = strrchr(line, '\n'); 267 if (c) { 268 *c = '\0'; 269 } 270 mFieldAddress[i] = dlsym(mScriptSO, line); 271 if (mFieldAddress[i] == NULL) { 272 ALOGE("Failed to find variable address for %s: %s", 273 line, dlerror()); 274 // Not a critical error if we don't find a global variable. 275 } 276 else { 277 //ALOGE("Found variable %s at %p", line, 278 //mFieldAddress[i]); 279 } 280 } 281 } 282 283 size_t funcCount = 0; 284 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 285 goto error; 286 } 287 if (sscanf(line, EXPORT_FUNC_STR "%zu", &funcCount) != 1) { 288 ALOGE("Invalid export func count!: %s", line); 289 goto error; 290 } 291 292 mExportedFunctionCount = funcCount; 293 //ALOGE("funcCount: %zu", funcCount); 294 295 if (funcCount > 0) { 296 mInvokeFunctions = new InvokeFunc_t[funcCount]; 297 if (mInvokeFunctions == NULL) { 298 goto error; 299 } 300 for (size_t i = 0; i < funcCount; ++i) { 301 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 302 goto error; 303 } 304 char *c = strrchr(line, '\n'); 305 if (c) { 306 *c = '\0'; 307 } 308 309 mInvokeFunctions[i] = (InvokeFunc_t) dlsym(mScriptSO, line); 310 if (mInvokeFunctions[i] == NULL) { 311 ALOGE("Failed to get function address for %s(): %s", 312 line, dlerror()); 313 goto error; 314 } 315 else { 316 //ALOGE("Found InvokeFunc_t %s at %p", line, mInvokeFunctions[i]); 317 } 318 } 319 } 320 321 size_t forEachCount = 0; 322 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 323 goto error; 324 } 325 if (sscanf(line, EXPORT_FOREACH_STR "%zu", &forEachCount) != 1) { 326 ALOGE("Invalid export forEach count!: %s", line); 327 goto error; 328 } 329 330 if (forEachCount > 0) { 331 332 mForEachSignatures = new uint32_t[forEachCount]; 333 if (mForEachSignatures == NULL) { 334 goto error; 335 } 336 mForEachFunctions = new ForEachFunc_t[forEachCount]; 337 if (mForEachFunctions == NULL) { 338 goto error; 339 } 340 for (size_t i = 0; i < forEachCount; ++i) { 341 unsigned int tmpSig = 0; 342 char tmpName[MAXLINE]; 343 344 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 345 goto error; 346 } 347 if (sscanf(line, "%u - %" MAKE_STR(MAXLINE) "s", 348 &tmpSig, tmpName) != 2) { 349 ALOGE("Invalid export forEach!: %s", line); 350 goto error; 351 } 352 353 // Lookup the expanded ForEach kernel. 354 strncat(tmpName, ".expand", MAXLINE-1-strlen(tmpName)); 355 mForEachSignatures[i] = tmpSig; 356 mForEachFunctions[i] = 357 (ForEachFunc_t) dlsym(mScriptSO, tmpName); 358 if (mForEachFunctions[i] == NULL) { 359 ALOGE("Failed to find forEach function address for %s: %s", 360 tmpName, dlerror()); 361 // Ignore missing root.expand functions. 362 // root() is always specified at location 0. 363 if (i != 0) { 364 goto error; 365 } 366 } 367 else { 368 //ALOGE("Found forEach %s at %p", tmpName, mForEachFunctions[i]); 369 } 370 } 371 } 372 373 size_t objectSlotCount = 0; 374 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 375 goto error; 376 } 377 if (sscanf(line, OBJECT_SLOT_STR "%zu", &objectSlotCount) != 1) { 378 ALOGE("Invalid object slot count!: %s", line); 379 goto error; 380 } 381 382 if (objectSlotCount > 0) { 383 rsAssert(varCount > 0); 384 for (size_t i = 0; i < objectSlotCount; ++i) { 385 uint32_t varNum = 0; 386 if (strgets(line, MAXLINE, &rsInfo) == NULL) { 387 goto error; 388 } 389 if (sscanf(line, "%u", &varNum) != 1) { 390 ALOGE("Invalid object slot!: %s", line); 391 goto error; 392 } 393 394 if (varNum < varCount) { 395 mFieldIsObject[varNum] = true; 396 } 397 } 398 } 399 400 if (varCount > 0) { 401 mBoundAllocs = new Allocation *[varCount]; 402 memset(mBoundAllocs, 0, varCount * sizeof(*mBoundAllocs)); 403 } 404 405 if (mScriptSO == (void*)1) { 406 //rsdLookupRuntimeStub(script, "acos"); 407 } 408 } 409#endif 410 411 mCtx->unlockMutex(); 412 return true; 413 414#ifdef RS_COMPATIBILITY_LIB 415error: 416 417 mCtx->unlockMutex(); 418 delete[] mInvokeFunctions; 419 delete[] mForEachFunctions; 420 delete[] mFieldAddress; 421 delete[] mFieldIsObject; 422 delete[] mForEachSignatures; 423 delete[] mBoundAllocs; 424 if (mScriptSO) { 425 dlclose(mScriptSO); 426 } 427 return false; 428#endif 429} 430 431void RsdCpuScriptImpl::populateScript(Script *script) { 432#ifndef RS_COMPATIBILITY_LIB 433 const bcc::RSInfo *info = &mExecutable->getInfo(); 434 435 // Copy info over to runtime 436 script->mHal.info.exportedFunctionCount = info->getExportFuncNames().size(); 437 script->mHal.info.exportedVariableCount = info->getExportVarNames().size(); 438 script->mHal.info.exportedPragmaCount = info->getPragmas().size(); 439 script->mHal.info.exportedPragmaKeyList = 440 const_cast<const char**>(mExecutable->getPragmaKeys().array()); 441 script->mHal.info.exportedPragmaValueList = 442 const_cast<const char**>(mExecutable->getPragmaValues().array()); 443 444 if (mRootExpand) { 445 script->mHal.info.root = mRootExpand; 446 } else { 447 script->mHal.info.root = mRoot; 448 } 449#else 450 // Copy info over to runtime 451 script->mHal.info.exportedFunctionCount = mExportedFunctionCount; 452 script->mHal.info.exportedVariableCount = mExportedVariableCount; 453 script->mHal.info.exportedPragmaCount = 0; 454 script->mHal.info.exportedPragmaKeyList = 0; 455 script->mHal.info.exportedPragmaValueList = 0; 456 457 // Bug, need to stash in metadata 458 if (mRootExpand) { 459 script->mHal.info.root = mRootExpand; 460 } else { 461 script->mHal.info.root = mRoot; 462 } 463#endif 464} 465 466 467typedef void (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t); 468 469void RsdCpuScriptImpl::forEachMtlsSetup(const Allocation * ain, Allocation * aout, 470 const void * usr, uint32_t usrLen, 471 const RsScriptCall *sc, 472 MTLaunchStruct *mtls) { 473 474 memset(mtls, 0, sizeof(MTLaunchStruct)); 475 476 // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface 477 if (ain && (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == NULL) { 478 mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations"); 479 return; 480 } 481 if (aout && (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == NULL) { 482 mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations"); 483 return; 484 } 485 486 if (ain) { 487 mtls->fep.dimX = ain->getType()->getDimX(); 488 mtls->fep.dimY = ain->getType()->getDimY(); 489 mtls->fep.dimZ = ain->getType()->getDimZ(); 490 //mtls->dimArray = ain->getType()->getDimArray(); 491 } else if (aout) { 492 mtls->fep.dimX = aout->getType()->getDimX(); 493 mtls->fep.dimY = aout->getType()->getDimY(); 494 mtls->fep.dimZ = aout->getType()->getDimZ(); 495 //mtls->dimArray = aout->getType()->getDimArray(); 496 } else { 497 mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations"); 498 return; 499 } 500 501 if (!sc || (sc->xEnd == 0)) { 502 mtls->xEnd = mtls->fep.dimX; 503 } else { 504 rsAssert(sc->xStart < mtls->fep.dimX); 505 rsAssert(sc->xEnd <= mtls->fep.dimX); 506 rsAssert(sc->xStart < sc->xEnd); 507 mtls->xStart = rsMin(mtls->fep.dimX, sc->xStart); 508 mtls->xEnd = rsMin(mtls->fep.dimX, sc->xEnd); 509 if (mtls->xStart >= mtls->xEnd) return; 510 } 511 512 if (!sc || (sc->yEnd == 0)) { 513 mtls->yEnd = mtls->fep.dimY; 514 } else { 515 rsAssert(sc->yStart < mtls->fep.dimY); 516 rsAssert(sc->yEnd <= mtls->fep.dimY); 517 rsAssert(sc->yStart < sc->yEnd); 518 mtls->yStart = rsMin(mtls->fep.dimY, sc->yStart); 519 mtls->yEnd = rsMin(mtls->fep.dimY, sc->yEnd); 520 if (mtls->yStart >= mtls->yEnd) return; 521 } 522 523 if (!sc || (sc->zEnd == 0)) { 524 mtls->zEnd = mtls->fep.dimZ; 525 } else { 526 rsAssert(sc->zStart < mtls->fep.dimZ); 527 rsAssert(sc->zEnd <= mtls->fep.dimZ); 528 rsAssert(sc->zStart < sc->zEnd); 529 mtls->zStart = rsMin(mtls->fep.dimZ, sc->zStart); 530 mtls->zEnd = rsMin(mtls->fep.dimZ, sc->zEnd); 531 if (mtls->zStart >= mtls->zEnd) return; 532 } 533 534 mtls->xEnd = rsMax((uint32_t)1, mtls->xEnd); 535 mtls->yEnd = rsMax((uint32_t)1, mtls->yEnd); 536 mtls->zEnd = rsMax((uint32_t)1, mtls->zEnd); 537 mtls->arrayEnd = rsMax((uint32_t)1, mtls->arrayEnd); 538 539 rsAssert(!ain || (ain->getType()->getDimZ() == 0)); 540 541 mtls->rsc = mCtx; 542 mtls->ain = ain; 543 mtls->aout = aout; 544 mtls->fep.usr = usr; 545 mtls->fep.usrLen = usrLen; 546 mtls->mSliceSize = 1; 547 mtls->mSliceNum = 0; 548 549 mtls->fep.ptrIn = NULL; 550 mtls->fep.eStrideIn = 0; 551 mtls->isThreadable = mIsThreadable; 552 553 if (ain) { 554 mtls->fep.ptrIn = (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr; 555 mtls->fep.eStrideIn = ain->getType()->getElementSizeBytes(); 556 mtls->fep.yStrideIn = ain->mHal.drvState.lod[0].stride; 557 } 558 559 mtls->fep.ptrOut = NULL; 560 mtls->fep.eStrideOut = 0; 561 if (aout) { 562 mtls->fep.ptrOut = (uint8_t *)aout->mHal.drvState.lod[0].mallocPtr; 563 mtls->fep.eStrideOut = aout->getType()->getElementSizeBytes(); 564 mtls->fep.yStrideOut = aout->mHal.drvState.lod[0].stride; 565 } 566} 567 568 569void RsdCpuScriptImpl::invokeForEach(uint32_t slot, 570 const Allocation * ain, 571 Allocation * aout, 572 const void * usr, 573 uint32_t usrLen, 574 const RsScriptCall *sc) { 575 576 MTLaunchStruct mtls; 577 forEachMtlsSetup(ain, aout, usr, usrLen, sc, &mtls); 578 forEachKernelSetup(slot, &mtls); 579 580 RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this); 581 mCtx->launchThreads(ain, aout, sc, &mtls); 582 mCtx->setTLS(oldTLS); 583} 584 585void RsdCpuScriptImpl::forEachKernelSetup(uint32_t slot, MTLaunchStruct *mtls) { 586 mtls->script = this; 587 mtls->fep.slot = slot; 588#ifndef RS_COMPATIBILITY_LIB 589 rsAssert(slot < mExecutable->getExportForeachFuncAddrs().size()); 590 mtls->kernel = reinterpret_cast<ForEachFunc_t>( 591 mExecutable->getExportForeachFuncAddrs()[slot]); 592 rsAssert(mtls->kernel != NULL); 593 mtls->sig = mExecutable->getInfo().getExportForeachFuncs()[slot].second; 594#else 595 mtls->kernel = reinterpret_cast<ForEachFunc_t>(mForEachFunctions[slot]); 596 rsAssert(mtls->kernel != NULL); 597 mtls->sig = mForEachSignatures[slot]; 598#endif 599} 600 601int RsdCpuScriptImpl::invokeRoot() { 602 RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this); 603 int ret = mRoot(); 604 mCtx->setTLS(oldTLS); 605 return ret; 606} 607 608void RsdCpuScriptImpl::invokeInit() { 609 if (mInit) { 610 mInit(); 611 } 612} 613 614void RsdCpuScriptImpl::invokeFreeChildren() { 615 if (mFreeChildren) { 616 mFreeChildren(); 617 } 618} 619 620void RsdCpuScriptImpl::invokeFunction(uint32_t slot, const void *params, 621 size_t paramLength) { 622 //ALOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength); 623 624 RsdCpuScriptImpl * oldTLS = mCtx->setTLS(this); 625 reinterpret_cast<void (*)(const void *, uint32_t)>( 626#ifndef RS_COMPATIBILITY_LIB 627 mExecutable->getExportFuncAddrs()[slot])(params, paramLength); 628#else 629 mInvokeFunctions[slot])(params, paramLength); 630#endif 631 mCtx->setTLS(oldTLS); 632} 633 634void RsdCpuScriptImpl::setGlobalVar(uint32_t slot, const void *data, size_t dataLength) { 635 //rsAssert(!script->mFieldIsObject[slot]); 636 //ALOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength); 637 638 //if (mIntrinsicID) { 639 //mIntrinsicFuncs.setVar(dc, script, drv->mIntrinsicData, slot, data, dataLength); 640 //return; 641 //} 642 643#ifndef RS_COMPATIBILITY_LIB 644 int32_t *destPtr = reinterpret_cast<int32_t *>( 645 mExecutable->getExportVarAddrs()[slot]); 646#else 647 int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]); 648#endif 649 if (!destPtr) { 650 //ALOGV("Calling setVar on slot = %i which is null", slot); 651 return; 652 } 653 654 memcpy(destPtr, data, dataLength); 655} 656 657void RsdCpuScriptImpl::setGlobalVarWithElemDims(uint32_t slot, const void *data, size_t dataLength, 658 const Element *elem, 659 const size_t *dims, size_t dimLength) { 660 661#ifndef RS_COMPATIBILITY_LIB 662 int32_t *destPtr = reinterpret_cast<int32_t *>( 663 mExecutable->getExportVarAddrs()[slot]); 664#else 665 int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]); 666#endif 667 if (!destPtr) { 668 //ALOGV("Calling setVar on slot = %i which is null", slot); 669 return; 670 } 671 672 // We want to look at dimension in terms of integer components, 673 // but dimLength is given in terms of bytes. 674 dimLength /= sizeof(int); 675 676 // Only a single dimension is currently supported. 677 rsAssert(dimLength == 1); 678 if (dimLength == 1) { 679 // First do the increment loop. 680 size_t stride = elem->getSizeBytes(); 681 const char *cVal = reinterpret_cast<const char *>(data); 682 for (size_t i = 0; i < dims[0]; i++) { 683 elem->incRefs(cVal); 684 cVal += stride; 685 } 686 687 // Decrement loop comes after (to prevent race conditions). 688 char *oldVal = reinterpret_cast<char *>(destPtr); 689 for (size_t i = 0; i < dims[0]; i++) { 690 elem->decRefs(oldVal); 691 oldVal += stride; 692 } 693 } 694 695 memcpy(destPtr, data, dataLength); 696} 697 698void RsdCpuScriptImpl::setGlobalBind(uint32_t slot, Allocation *data) { 699 700 //rsAssert(!script->mFieldIsObject[slot]); 701 //ALOGE("setGlobalBind %p %p %i %p", dc, script, slot, data); 702 703#ifndef RS_COMPATIBILITY_LIB 704 int32_t *destPtr = reinterpret_cast<int32_t *>( 705 mExecutable->getExportVarAddrs()[slot]); 706#else 707 int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]); 708#endif 709 if (!destPtr) { 710 //ALOGV("Calling setVar on slot = %i which is null", slot); 711 return; 712 } 713 714 void *ptr = NULL; 715 mBoundAllocs[slot] = data; 716 if(data) { 717 ptr = data->mHal.drvState.lod[0].mallocPtr; 718 } 719 memcpy(destPtr, &ptr, sizeof(void *)); 720} 721 722void RsdCpuScriptImpl::setGlobalObj(uint32_t slot, ObjectBase *data) { 723 724 //rsAssert(script->mFieldIsObject[slot]); 725 //ALOGE("setGlobalObj %p %p %i %p", dc, script, slot, data); 726 727 //if (mIntrinsicID) { 728 //mIntrinsicFuncs.setVarObj(dc, script, drv->mIntrinsicData, slot, alloc); 729 //return; 730 //} 731 732#ifndef RS_COMPATIBILITY_LIB 733 int32_t *destPtr = reinterpret_cast<int32_t *>( 734 mExecutable->getExportVarAddrs()[slot]); 735#else 736 int32_t *destPtr = reinterpret_cast<int32_t *>(mFieldAddress[slot]); 737#endif 738 if (!destPtr) { 739 //ALOGV("Calling setVar on slot = %i which is null", slot); 740 return; 741 } 742 743 rsrSetObject(mCtx->getContext(), (ObjectBase **)destPtr, data); 744} 745 746RsdCpuScriptImpl::~RsdCpuScriptImpl() { 747#ifndef RS_COMPATIBILITY_LIB 748 if (mExecutable) { 749 Vector<void *>::const_iterator var_addr_iter = 750 mExecutable->getExportVarAddrs().begin(); 751 Vector<void *>::const_iterator var_addr_end = 752 mExecutable->getExportVarAddrs().end(); 753 754 bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_iter = 755 mExecutable->getInfo().getObjectSlots().begin(); 756 bcc::RSInfo::ObjectSlotListTy::const_iterator is_object_end = 757 mExecutable->getInfo().getObjectSlots().end(); 758 759 while ((var_addr_iter != var_addr_end) && 760 (is_object_iter != is_object_end)) { 761 // The field address can be NULL if the script-side has optimized 762 // the corresponding global variable away. 763 ObjectBase **obj_addr = 764 reinterpret_cast<ObjectBase **>(*var_addr_iter); 765 if (*is_object_iter) { 766 if (*var_addr_iter != NULL) { 767 rsrClearObject(mCtx->getContext(), obj_addr); 768 } 769 } 770 var_addr_iter++; 771 is_object_iter++; 772 } 773 } 774 775 if (mCompilerContext) { 776 delete mCompilerContext; 777 } 778 if (mCompilerDriver) { 779 delete mCompilerDriver; 780 } 781 if (mExecutable) { 782 delete mExecutable; 783 } 784 if (mBoundAllocs) { 785 delete[] mBoundAllocs; 786 } 787#else 788 if (mFieldIsObject) { 789 for (size_t i = 0; i < mExportedVariableCount; ++i) { 790 if (mFieldIsObject[i]) { 791 if (mFieldAddress[i] != NULL) { 792 ObjectBase **obj_addr = 793 reinterpret_cast<ObjectBase **>(mFieldAddress[i]); 794 rsrClearObject(mCtx->getContext(), obj_addr); 795 } 796 } 797 } 798 } 799 800 if (mInvokeFunctions) delete[] mInvokeFunctions; 801 if (mForEachFunctions) delete[] mForEachFunctions; 802 if (mFieldAddress) delete[] mFieldAddress; 803 if (mFieldIsObject) delete[] mFieldIsObject; 804 if (mForEachSignatures) delete[] mForEachSignatures; 805 if (mBoundAllocs) delete[] mBoundAllocs; 806 if (mScriptSO) { 807 dlclose(mScriptSO); 808 } 809#endif 810} 811 812Allocation * RsdCpuScriptImpl::getAllocationForPointer(const void *ptr) const { 813 if (!ptr) { 814 return NULL; 815 } 816 817 for (uint32_t ct=0; ct < mScript->mHal.info.exportedVariableCount; ct++) { 818 Allocation *a = mBoundAllocs[ct]; 819 if (!a) continue; 820 if (a->mHal.drvState.lod[0].mallocPtr == ptr) { 821 return a; 822 } 823 } 824 ALOGE("rsGetAllocation, failed to find %p", ptr); 825 return NULL; 826} 827 828 829} 830} 831