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