1 /* 2 * Copyright (C) 2011 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 #include "rs.h" 18 #include "rsDevice.h" 19 #include "rsContext.h" 20 #include "rsThreadIO.h" 21 22 #ifndef RS_COMPATIBILITY_LIB 23 #include "rsMesh.h" 24 #include <ui/FramebufferNativeWindow.h> 25 #include <gui/DisplayEventReceiver.h> 26 #endif 27 28 #include <sys/types.h> 29 #include <sys/resource.h> 30 #include <sched.h> 31 32 #include <sys/syscall.h> 33 #include <string.h> 34 #include <dlfcn.h> 35 #include <unistd.h> 36 37 #if !defined(RS_SERVER) 38 #include <cutils/properties.h> 39 #endif 40 41 #ifdef RS_SERVER 42 // Android exposes gettid(), standard Linux does not 43 static pid_t gettid() { 44 return syscall(SYS_gettid); 45 } 46 #endif 47 48 using namespace android; 49 using namespace android::renderscript; 50 51 pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER; 52 pthread_mutex_t Context::gMessageMutex = PTHREAD_MUTEX_INITIALIZER; 53 pthread_mutex_t Context::gLibMutex = PTHREAD_MUTEX_INITIALIZER; 54 55 bool Context::initGLThread() { 56 pthread_mutex_lock(&gInitMutex); 57 58 if (!mHal.funcs.initGraphics(this)) { 59 pthread_mutex_unlock(&gInitMutex); 60 ALOGE("%p initGraphics failed", this); 61 return false; 62 } 63 64 pthread_mutex_unlock(&gInitMutex); 65 return true; 66 } 67 68 void Context::deinitEGL() { 69 #ifndef RS_COMPATIBILITY_LIB 70 mHal.funcs.shutdownGraphics(this); 71 #endif 72 } 73 74 Context::PushState::PushState(Context *con) { 75 mRsc = con; 76 #ifndef RS_COMPATIBILITY_LIB 77 if (con->mIsGraphicsContext) { 78 mFragment.set(con->getProgramFragment()); 79 mVertex.set(con->getProgramVertex()); 80 mStore.set(con->getProgramStore()); 81 mRaster.set(con->getProgramRaster()); 82 mFont.set(con->getFont()); 83 } 84 #endif 85 } 86 87 Context::PushState::~PushState() { 88 #ifndef RS_COMPATIBILITY_LIB 89 if (mRsc->mIsGraphicsContext) { 90 mRsc->setProgramFragment(mFragment.get()); 91 mRsc->setProgramVertex(mVertex.get()); 92 mRsc->setProgramStore(mStore.get()); 93 mRsc->setProgramRaster(mRaster.get()); 94 mRsc->setFont(mFont.get()); 95 } 96 #endif 97 } 98 99 100 uint32_t Context::runScript(Script *s) { 101 PushState ps(this); 102 103 uint32_t ret = s->run(this); 104 return ret; 105 } 106 107 uint32_t Context::runRootScript() { 108 timerSet(RS_TIMER_SCRIPT); 109 #ifndef RS_COMPATIBILITY_LIB 110 mStateFragmentStore.mLast.clear(); 111 #endif 112 watchdog.inRoot = true; 113 uint32_t ret = runScript(mRootScript.get()); 114 watchdog.inRoot = false; 115 116 return ret; 117 } 118 119 uint64_t Context::getTime() const { 120 #ifndef ANDROID_RS_SERIALIZE 121 struct timespec t; 122 clock_gettime(CLOCK_MONOTONIC, &t); 123 return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); 124 #else 125 return 0; 126 #endif //ANDROID_RS_SERIALIZE 127 } 128 129 void Context::timerReset() { 130 for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) { 131 mTimers[ct] = 0; 132 } 133 } 134 135 void Context::timerInit() { 136 mTimeLast = getTime(); 137 mTimeFrame = mTimeLast; 138 mTimeLastFrame = mTimeLast; 139 mTimerActive = RS_TIMER_INTERNAL; 140 mAverageFPSFrameCount = 0; 141 mAverageFPSStartTime = mTimeLast; 142 mAverageFPS = 0; 143 timerReset(); 144 } 145 146 void Context::timerFrame() { 147 mTimeLastFrame = mTimeFrame; 148 mTimeFrame = getTime(); 149 // Update average fps 150 const uint64_t averageFramerateInterval = 1000 * 1000000; 151 mAverageFPSFrameCount ++; 152 uint64_t inverval = mTimeFrame - mAverageFPSStartTime; 153 if (inverval >= averageFramerateInterval) { 154 inverval = inverval / 1000000; 155 mAverageFPS = (mAverageFPSFrameCount * 1000) / inverval; 156 mAverageFPSFrameCount = 0; 157 mAverageFPSStartTime = mTimeFrame; 158 } 159 } 160 161 void Context::timerSet(Timers tm) { 162 uint64_t last = mTimeLast; 163 mTimeLast = getTime(); 164 mTimers[mTimerActive] += mTimeLast - last; 165 mTimerActive = tm; 166 } 167 168 void Context::timerPrint() { 169 double total = 0; 170 for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) { 171 total += mTimers[ct]; 172 } 173 uint64_t frame = mTimeFrame - mTimeLastFrame; 174 mTimeMSLastFrame = frame / 1000000; 175 mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000; 176 mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000; 177 178 179 if (props.mLogTimes) { 180 ALOGV("RS: Frame (%i), Script %2.1f%% (%i), Swap %2.1f%% (%i), Idle %2.1f%% (%lli), Internal %2.1f%% (%lli), Avg fps: %u", 181 mTimeMSLastFrame, 182 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript, 183 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap, 184 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000, 185 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000, 186 mAverageFPS); 187 } 188 } 189 190 bool Context::setupCheck() { 191 #ifndef RS_COMPATIBILITY_LIB 192 mFragmentStore->setup(this, &mStateFragmentStore); 193 mFragment->setup(this, &mStateFragment); 194 mRaster->setup(this, &mStateRaster); 195 mVertex->setup(this, &mStateVertex); 196 mFBOCache.setup(this); 197 #endif 198 return true; 199 } 200 201 #ifndef RS_COMPATIBILITY_LIB 202 void Context::setupProgramStore() { 203 mFragmentStore->setup(this, &mStateFragmentStore); 204 } 205 #endif 206 207 static uint32_t getProp(const char *str) { 208 #ifndef RS_SERVER 209 char buf[PROPERTY_VALUE_MAX]; 210 property_get(str, buf, "0"); 211 return atoi(buf); 212 #else 213 return 0; 214 #endif 215 } 216 217 void Context::displayDebugStats() { 218 #ifndef RS_COMPATIBILITY_LIB 219 char buffer[128]; 220 sprintf(buffer, "Avg fps %u, Frame %i ms, Script %i ms", mAverageFPS, mTimeMSLastFrame, mTimeMSLastScript); 221 float oldR, oldG, oldB, oldA; 222 mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA); 223 uint32_t bufferLen = strlen(buffer); 224 225 ObjectBaseRef<Font> lastFont(getFont()); 226 setFont(NULL); 227 float shadowCol = 0.1f; 228 mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f); 229 mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 6); 230 231 mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f); 232 mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 7); 233 234 setFont(lastFont.get()); 235 mStateFont.setFontColor(oldR, oldG, oldB, oldA); 236 #endif 237 } 238 239 bool Context::loadRuntime(const char* filename, Context* rsc) { 240 241 // TODO: store the driverSO somewhere so we can dlclose later 242 void *driverSO = NULL; 243 244 driverSO = dlopen(filename, RTLD_LAZY); 245 if (driverSO == NULL) { 246 ALOGE("Failed loading RS driver: %s", dlerror()); 247 return false; 248 } 249 250 // Need to call dlerror() to clear buffer before using it for dlsym(). 251 (void) dlerror(); 252 typedef bool (*HalSig)(Context*, uint32_t, uint32_t); 253 HalSig halInit = (HalSig) dlsym(driverSO, "rsdHalInit"); 254 255 // If we can't find the C variant, we go looking for the C++ version. 256 if (halInit == NULL) { 257 ALOGW("Falling back to find C++ rsdHalInit: %s", dlerror()); 258 halInit = (HalSig) dlsym(driverSO, 259 "_Z10rsdHalInitPN7android12renderscript7ContextEjj"); 260 } 261 262 if (halInit == NULL) { 263 dlclose(driverSO); 264 ALOGE("Failed to find rsdHalInit: %s", dlerror()); 265 return false; 266 } 267 268 if (!(*halInit)(rsc, 0, 0)) { 269 dlclose(driverSO); 270 ALOGE("Hal init failed"); 271 return false; 272 } 273 274 //validate HAL struct 275 276 277 return true; 278 } 279 280 extern "C" bool rsdHalInit(RsContext c, uint32_t version_major, uint32_t version_minor); 281 282 void * Context::threadProc(void *vrsc) { 283 Context *rsc = static_cast<Context *>(vrsc); 284 #ifndef ANDROID_RS_SERIALIZE 285 rsc->mNativeThreadId = gettid(); 286 #ifndef RS_COMPATIBILITY_LIB 287 if (!rsc->isSynchronous()) { 288 setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY); 289 } 290 rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY; 291 #else 292 if (!rsc->isSynchronous()) { 293 setpriority(PRIO_PROCESS, rsc->mNativeThreadId, -4); 294 } 295 rsc->mThreadPriority = -4; 296 #endif 297 #endif //ANDROID_RS_SERIALIZE 298 rsc->props.mLogTimes = getProp("debug.rs.profile") != 0; 299 rsc->props.mLogScripts = getProp("debug.rs.script") != 0; 300 rsc->props.mLogObjects = getProp("debug.rs.object") != 0; 301 rsc->props.mLogShaders = getProp("debug.rs.shader") != 0; 302 rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes") != 0; 303 rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms") != 0; 304 rsc->props.mLogVisual = getProp("debug.rs.visual") != 0; 305 rsc->props.mDebugMaxThreads = getProp("debug.rs.max-threads"); 306 307 bool loadDefault = true; 308 309 // Provide a mechanism for dropping in a different RS driver. 310 #ifndef RS_COMPATIBILITY_LIB 311 #ifdef OVERRIDE_RS_DRIVER 312 #define XSTR(S) #S 313 #define STR(S) XSTR(S) 314 #define OVERRIDE_RS_DRIVER_STRING STR(OVERRIDE_RS_DRIVER) 315 316 if (getProp("debug.rs.default-CPU-driver") != 0) { 317 ALOGE("Skipping override driver and loading default CPU driver"); 318 } else if (rsc->mForceCpu) { 319 ALOGV("Application requested CPU execution"); 320 } else if (rsc->getContextType() == RS_CONTEXT_TYPE_DEBUG) { 321 ALOGV("Application requested debug context"); 322 } else { 323 if (loadRuntime(OVERRIDE_RS_DRIVER_STRING, rsc)) { 324 ALOGE("Successfully loaded runtime: %s", OVERRIDE_RS_DRIVER_STRING); 325 loadDefault = false; 326 } else { 327 ALOGE("Failed to load runtime %s, loading default", OVERRIDE_RS_DRIVER_STRING); 328 } 329 } 330 331 #undef XSTR 332 #undef STR 333 #endif // OVERRIDE_RS_DRIVER 334 335 if (loadDefault) { 336 if (!loadRuntime("libRSDriver.so", rsc)) { 337 ALOGE("Failed to load default runtime!"); 338 rsc->setError(RS_ERROR_FATAL_DRIVER, "Failed loading RS driver"); 339 return NULL; 340 } 341 } 342 #else // RS_COMPATIBILITY_LIB 343 if (rsdHalInit(rsc, 0, 0) != true) { 344 return NULL; 345 } 346 #endif 347 348 349 rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority); 350 351 #ifndef RS_COMPATIBILITY_LIB 352 if (rsc->mIsGraphicsContext) { 353 if (!rsc->initGLThread()) { 354 rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL"); 355 return NULL; 356 } 357 358 rsc->mStateRaster.init(rsc); 359 rsc->setProgramRaster(NULL); 360 rsc->mStateVertex.init(rsc); 361 rsc->setProgramVertex(NULL); 362 rsc->mStateFragment.init(rsc); 363 rsc->setProgramFragment(NULL); 364 rsc->mStateFragmentStore.init(rsc); 365 rsc->setProgramStore(NULL); 366 rsc->mStateFont.init(rsc); 367 rsc->setFont(NULL); 368 rsc->mStateSampler.init(rsc); 369 rsc->mFBOCache.init(rsc); 370 } 371 #endif 372 373 rsc->mRunning = true; 374 375 if (rsc->isSynchronous()) { 376 return NULL; 377 } 378 379 if (!rsc->mIsGraphicsContext) { 380 while (!rsc->mExit) { 381 rsc->mIO.playCoreCommands(rsc, -1); 382 } 383 #ifndef RS_COMPATIBILITY_LIB 384 } else { 385 #ifndef ANDROID_RS_SERIALIZE 386 DisplayEventReceiver displayEvent; 387 DisplayEventReceiver::Event eventBuffer[1]; 388 #endif 389 int vsyncRate = 0; 390 int targetRate = 0; 391 392 bool drawOnce = false; 393 while (!rsc->mExit) { 394 rsc->timerSet(RS_TIMER_IDLE); 395 396 #ifndef ANDROID_RS_SERIALIZE 397 if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused) { 398 targetRate = 0; 399 } 400 401 if (vsyncRate != targetRate) { 402 displayEvent.setVsyncRate(targetRate); 403 vsyncRate = targetRate; 404 } 405 if (targetRate) { 406 drawOnce |= rsc->mIO.playCoreCommands(rsc, displayEvent.getFd()); 407 while (displayEvent.getEvents(eventBuffer, 1) != 0) { 408 //ALOGE("vs2 time past %lld", (rsc->getTime() - eventBuffer[0].header.timestamp) / 1000000); 409 } 410 } else 411 #endif 412 { 413 drawOnce |= rsc->mIO.playCoreCommands(rsc, -1); 414 } 415 416 if ((rsc->mRootScript.get() != NULL) && rsc->mHasSurface && 417 (targetRate || drawOnce) && !rsc->mPaused) { 418 419 drawOnce = false; 420 targetRate = ((rsc->runRootScript() + 15) / 16); 421 422 if (rsc->props.mLogVisual) { 423 rsc->displayDebugStats(); 424 } 425 426 rsc->timerSet(RS_TIMER_CLEAR_SWAP); 427 rsc->mHal.funcs.swap(rsc); 428 rsc->timerFrame(); 429 rsc->timerSet(RS_TIMER_INTERNAL); 430 rsc->timerPrint(); 431 rsc->timerReset(); 432 } 433 } 434 #endif 435 } 436 437 //ALOGV("%p RS Thread exiting", rsc); 438 439 #ifndef RS_COMPATIBILITY_LIB 440 if (rsc->mIsGraphicsContext) { 441 pthread_mutex_lock(&gInitMutex); 442 rsc->deinitEGL(); 443 pthread_mutex_unlock(&gInitMutex); 444 } 445 #endif 446 447 //ALOGV("%p RS Thread exited", rsc); 448 return NULL; 449 } 450 451 void Context::destroyWorkerThreadResources() { 452 //ALOGV("destroyWorkerThreadResources 1"); 453 ObjectBase::zeroAllUserRef(this); 454 #ifndef RS_COMPATIBILITY_LIB 455 if (mIsGraphicsContext) { 456 mRaster.clear(); 457 mFragment.clear(); 458 mVertex.clear(); 459 mFragmentStore.clear(); 460 mFont.clear(); 461 mRootScript.clear(); 462 mStateRaster.deinit(this); 463 mStateVertex.deinit(this); 464 mStateFragment.deinit(this); 465 mStateFragmentStore.deinit(this); 466 mStateFont.deinit(this); 467 mStateSampler.deinit(this); 468 mFBOCache.deinit(this); 469 } 470 #endif 471 ObjectBase::freeAllChildren(this); 472 mExit = true; 473 //ALOGV("destroyWorkerThreadResources 2"); 474 } 475 476 void Context::printWatchdogInfo(void *ctx) { 477 Context *rsc = (Context *)ctx; 478 if (rsc->watchdog.command && rsc->watchdog.file) { 479 ALOGE("RS watchdog timeout: %i %s line %i %s", rsc->watchdog.inRoot, 480 rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file); 481 } else { 482 ALOGE("RS watchdog timeout: %i", rsc->watchdog.inRoot); 483 } 484 } 485 486 487 void Context::setPriority(int32_t p) { 488 // Note: If we put this in the proper "background" policy 489 // the wallpapers can become completly unresponsive at times. 490 // This is probably not what we want for something the user is actively 491 // looking at. 492 mThreadPriority = p; 493 setpriority(PRIO_PROCESS, mNativeThreadId, p); 494 mHal.funcs.setPriority(this, mThreadPriority); 495 } 496 497 Context::Context() { 498 mDev = NULL; 499 mRunning = false; 500 mExit = false; 501 mPaused = false; 502 mObjHead = NULL; 503 mError = RS_ERROR_NONE; 504 mTargetSdkVersion = 14; 505 mDPI = 96; 506 mIsContextLite = false; 507 memset(&watchdog, 0, sizeof(watchdog)); 508 mForceCpu = false; 509 mContextType = RS_CONTEXT_TYPE_NORMAL; 510 mSynchronous = false; 511 } 512 513 Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc, 514 RsContextType ct, bool forceCpu, 515 bool synchronous) { 516 Context * rsc = new Context(); 517 518 rsc->mForceCpu = forceCpu; 519 rsc->mSynchronous = synchronous; 520 rsc->mContextType = ct; 521 522 if (!rsc->initContext(dev, sc)) { 523 delete rsc; 524 return NULL; 525 } 526 return rsc; 527 } 528 529 Context * Context::createContextLite() { 530 Context * rsc = new Context(); 531 rsc->mIsContextLite = true; 532 return rsc; 533 } 534 535 bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) { 536 pthread_mutex_lock(&gInitMutex); 537 538 mIO.init(); 539 mIO.setTimeoutCallback(printWatchdogInfo, this, 2e9); 540 541 dev->addContext(this); 542 mDev = dev; 543 if (sc) { 544 mUserSurfaceConfig = *sc; 545 } else { 546 memset(&mUserSurfaceConfig, 0, sizeof(mUserSurfaceConfig)); 547 } 548 549 mIsGraphicsContext = sc != NULL; 550 551 int status; 552 pthread_attr_t threadAttr; 553 554 pthread_mutex_unlock(&gInitMutex); 555 556 // Global init done at this point. 557 558 status = pthread_attr_init(&threadAttr); 559 if (status) { 560 ALOGE("Failed to init thread attribute."); 561 return false; 562 } 563 564 mHasSurface = false; 565 566 timerInit(); 567 timerSet(RS_TIMER_INTERNAL); 568 if (mSynchronous) { 569 threadProc(this); 570 } else { 571 status = pthread_create(&mThreadId, &threadAttr, threadProc, this); 572 if (status) { 573 ALOGE("Failed to start rs context thread."); 574 return false; 575 } 576 while (!mRunning && (mError == RS_ERROR_NONE)) { 577 usleep(100); 578 } 579 580 if (mError != RS_ERROR_NONE) { 581 ALOGE("Errors during thread init"); 582 return false; 583 } 584 585 pthread_attr_destroy(&threadAttr); 586 } 587 return true; 588 } 589 590 Context::~Context() { 591 //ALOGV("%p Context::~Context", this); 592 593 if (!mIsContextLite) { 594 mPaused = false; 595 void *res; 596 597 mIO.shutdown(); 598 int status = pthread_join(mThreadId, &res); 599 rsAssert(mExit); 600 601 if (mHal.funcs.shutdownDriver) { 602 mHal.funcs.shutdownDriver(this); 603 } 604 605 // Global structure cleanup. 606 pthread_mutex_lock(&gInitMutex); 607 if (mDev) { 608 mDev->removeContext(this); 609 mDev = NULL; 610 } 611 pthread_mutex_unlock(&gInitMutex); 612 } 613 //ALOGV("%p Context::~Context done", this); 614 } 615 616 #ifndef RS_COMPATIBILITY_LIB 617 void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) { 618 rsAssert(mIsGraphicsContext); 619 mHal.funcs.setSurface(this, w, h, sur); 620 621 mHasSurface = sur != NULL; 622 mWidth = w; 623 mHeight = h; 624 625 if (mWidth && mHeight) { 626 mStateVertex.updateSize(this); 627 mFBOCache.updateSize(); 628 } 629 } 630 631 uint32_t Context::getCurrentSurfaceWidth() const { 632 for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) { 633 if (mFBOCache.mHal.state.colorTargets[i] != NULL) { 634 return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimX(); 635 } 636 } 637 if (mFBOCache.mHal.state.depthTarget != NULL) { 638 return mFBOCache.mHal.state.depthTarget->getType()->getDimX(); 639 } 640 return mWidth; 641 } 642 643 uint32_t Context::getCurrentSurfaceHeight() const { 644 for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) { 645 if (mFBOCache.mHal.state.colorTargets[i] != NULL) { 646 return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimY(); 647 } 648 } 649 if (mFBOCache.mHal.state.depthTarget != NULL) { 650 return mFBOCache.mHal.state.depthTarget->getType()->getDimY(); 651 } 652 return mHeight; 653 } 654 655 void Context::pause() { 656 rsAssert(mIsGraphicsContext); 657 mPaused = true; 658 } 659 660 void Context::resume() { 661 rsAssert(mIsGraphicsContext); 662 mPaused = false; 663 } 664 665 void Context::setRootScript(Script *s) { 666 rsAssert(mIsGraphicsContext); 667 mRootScript.set(s); 668 } 669 670 void Context::setProgramStore(ProgramStore *pfs) { 671 rsAssert(mIsGraphicsContext); 672 if (pfs == NULL) { 673 mFragmentStore.set(mStateFragmentStore.mDefault); 674 } else { 675 mFragmentStore.set(pfs); 676 } 677 } 678 679 void Context::setProgramFragment(ProgramFragment *pf) { 680 rsAssert(mIsGraphicsContext); 681 if (pf == NULL) { 682 mFragment.set(mStateFragment.mDefault); 683 } else { 684 mFragment.set(pf); 685 } 686 } 687 688 void Context::setProgramRaster(ProgramRaster *pr) { 689 rsAssert(mIsGraphicsContext); 690 if (pr == NULL) { 691 mRaster.set(mStateRaster.mDefault); 692 } else { 693 mRaster.set(pr); 694 } 695 } 696 697 void Context::setProgramVertex(ProgramVertex *pv) { 698 rsAssert(mIsGraphicsContext); 699 if (pv == NULL) { 700 mVertex.set(mStateVertex.mDefault); 701 } else { 702 mVertex.set(pv); 703 } 704 } 705 706 void Context::setFont(Font *f) { 707 rsAssert(mIsGraphicsContext); 708 if (f == NULL) { 709 mFont.set(mStateFont.mDefault); 710 } else { 711 mFont.set(f); 712 } 713 } 714 #endif 715 716 void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) { 717 rsAssert(!obj->getName()); 718 obj->setName(name, len); 719 mNames.add(obj); 720 } 721 722 void Context::removeName(ObjectBase *obj) { 723 for (size_t ct=0; ct < mNames.size(); ct++) { 724 if (obj == mNames[ct]) { 725 mNames.removeAt(ct); 726 return; 727 } 728 } 729 } 730 731 RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID) { 732 return (RsMessageToClientType)mIO.getClientHeader(receiveLen, subID); 733 } 734 735 RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen) { 736 return (RsMessageToClientType)mIO.getClientPayload(data, receiveLen, subID, bufferLen); 737 } 738 739 bool Context::sendMessageToClient(const void *data, RsMessageToClientType cmdID, 740 uint32_t subID, size_t len, bool waitForSpace) const { 741 742 pthread_mutex_lock(&gMessageMutex); 743 bool ret = mIO.sendToClient(cmdID, subID, data, len, waitForSpace); 744 pthread_mutex_unlock(&gMessageMutex); 745 return ret; 746 } 747 748 void Context::initToClient() { 749 while (!mRunning) { 750 usleep(100); 751 } 752 } 753 754 void Context::deinitToClient() { 755 mIO.clientShutdown(); 756 } 757 758 void Context::setError(RsError e, const char *msg) const { 759 mError = e; 760 sendMessageToClient(msg, RS_MESSAGE_TO_CLIENT_ERROR, e, strlen(msg) + 1, true); 761 } 762 763 764 void Context::dumpDebug() const { 765 ALOGE("RS Context debug %p", this); 766 ALOGE("RS Context debug"); 767 768 ALOGE(" RS width %i, height %i", mWidth, mHeight); 769 ALOGE(" RS running %i, exit %i, paused %i", mRunning, mExit, mPaused); 770 ALOGE(" RS pThreadID %li, nativeThreadID %i", (long int)mThreadId, mNativeThreadId); 771 } 772 773 /////////////////////////////////////////////////////////////////////////////////////////// 774 // 775 776 namespace android { 777 namespace renderscript { 778 779 void rsi_ContextFinish(Context *rsc) { 780 } 781 782 void rsi_ContextBindRootScript(Context *rsc, RsScript vs) { 783 #ifndef RS_COMPATIBILITY_LIB 784 Script *s = static_cast<Script *>(vs); 785 rsc->setRootScript(s); 786 #endif 787 } 788 789 void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) { 790 Sampler *s = static_cast<Sampler *>(vs); 791 792 if (slot > RS_MAX_SAMPLER_SLOT) { 793 ALOGE("Invalid sampler slot"); 794 return; 795 } 796 797 s->bindToContext(&rsc->mStateSampler, slot); 798 } 799 800 #ifndef RS_COMPATIBILITY_LIB 801 void rsi_ContextBindProgramStore(Context *rsc, RsProgramStore vpfs) { 802 ProgramStore *pfs = static_cast<ProgramStore *>(vpfs); 803 rsc->setProgramStore(pfs); 804 } 805 806 void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) { 807 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 808 rsc->setProgramFragment(pf); 809 } 810 811 void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr) { 812 ProgramRaster *pr = static_cast<ProgramRaster *>(vpr); 813 rsc->setProgramRaster(pr); 814 } 815 816 void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) { 817 ProgramVertex *pv = static_cast<ProgramVertex *>(vpv); 818 rsc->setProgramVertex(pv); 819 } 820 821 void rsi_ContextBindFont(Context *rsc, RsFont vfont) { 822 Font *font = static_cast<Font *>(vfont); 823 rsc->setFont(font); 824 } 825 #endif 826 827 void rsi_AssignName(Context *rsc, RsObjectBase obj, const char *name, size_t name_length) { 828 ObjectBase *ob = static_cast<ObjectBase *>(obj); 829 rsc->assignName(ob, name, name_length); 830 } 831 832 void rsi_ObjDestroy(Context *rsc, void *optr) { 833 ObjectBase *ob = static_cast<ObjectBase *>(optr); 834 rsc->removeName(ob); 835 ob->decUserRef(); 836 } 837 838 #ifndef RS_COMPATIBILITY_LIB 839 void rsi_ContextPause(Context *rsc) { 840 rsc->pause(); 841 } 842 843 void rsi_ContextResume(Context *rsc) { 844 rsc->resume(); 845 } 846 847 void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) { 848 rsc->setSurface(w, h, sur); 849 } 850 #endif 851 852 void rsi_ContextSetPriority(Context *rsc, int32_t p) { 853 rsc->setPriority(p); 854 } 855 856 void rsi_ContextDump(Context *rsc, int32_t bits) { 857 ObjectBase::dumpAll(rsc); 858 } 859 860 void rsi_ContextDestroyWorker(Context *rsc) { 861 rsc->destroyWorkerThreadResources(); 862 } 863 864 void rsi_ContextDestroy(Context *rsc) { 865 //ALOGV("%p rsContextDestroy", rsc); 866 rsContextDestroyWorker(rsc); 867 delete rsc; 868 //ALOGV("%p rsContextDestroy done", rsc); 869 } 870 871 872 RsMessageToClientType rsi_ContextPeekMessage(Context *rsc, 873 size_t * receiveLen, size_t receiveLen_length, 874 uint32_t * subID, size_t subID_length) { 875 return rsc->peekMessageToClient(receiveLen, subID); 876 } 877 878 RsMessageToClientType rsi_ContextGetMessage(Context *rsc, void * data, size_t data_length, 879 size_t * receiveLen, size_t receiveLen_length, 880 uint32_t * subID, size_t subID_length) { 881 rsAssert(subID_length == sizeof(uint32_t)); 882 rsAssert(receiveLen_length == sizeof(size_t)); 883 return rsc->getMessageToClient(data, receiveLen, subID, data_length); 884 } 885 886 void rsi_ContextInitToClient(Context *rsc) { 887 rsc->initToClient(); 888 } 889 890 void rsi_ContextDeinitToClient(Context *rsc) { 891 rsc->deinitToClient(); 892 } 893 894 void rsi_ContextSendMessage(Context *rsc, uint32_t id, const uint8_t *data, size_t len) { 895 rsc->sendMessageToClient(data, RS_MESSAGE_TO_CLIENT_USER, id, len, true); 896 } 897 898 } 899 } 900 901 RsContext rsContextCreate(RsDevice vdev, uint32_t version, uint32_t sdkVersion, 902 RsContextType ct, bool forceCpu, bool synchronous) { 903 //ALOGV("rsContextCreate dev=%p", vdev); 904 Device * dev = static_cast<Device *>(vdev); 905 Context *rsc = Context::createContext(dev, NULL, ct, forceCpu, synchronous); 906 if (rsc) { 907 rsc->setTargetSdkVersion(sdkVersion); 908 } 909 return rsc; 910 } 911 912 #ifndef RS_COMPATIBILITY_LIB 913 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, 914 uint32_t sdkVersion, RsSurfaceConfig sc, 915 uint32_t dpi) { 916 //ALOGV("rsContextCreateGL dev=%p", vdev); 917 Device * dev = static_cast<Device *>(vdev); 918 Context *rsc = Context::createContext(dev, &sc); 919 if (rsc) { 920 rsc->setTargetSdkVersion(sdkVersion); 921 rsc->setDPI(dpi); 922 } 923 //ALOGV("%p rsContextCreateGL ret", rsc); 924 return rsc; 925 } 926 #endif 927 928 // Only to be called at a3d load time, before object is visible to user 929 // not thread safe 930 void rsaGetName(RsContext con, void * obj, const char **name) { 931 ObjectBase *ob = static_cast<ObjectBase *>(obj); 932 (*name) = ob->getName(); 933 } 934