rsContext.cpp revision 5613b91c4f3b9a931ee9282317ea887007e05b86
1/* 2 * Copyright (C) 2009 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 "rsDevice.h" 18#include "rsContext.h" 19#include "rsThreadIO.h" 20#include <ui/FramebufferNativeWindow.h> 21#include <ui/EGLUtils.h> 22 23#include <sys/types.h> 24#include <sys/resource.h> 25 26#include <cutils/properties.h> 27 28#include <GLES/gl.h> 29#include <GLES/glext.h> 30 31#include <cutils/sched_policy.h> 32 33using namespace android; 34using namespace android::renderscript; 35 36pthread_key_t Context::gThreadTLSKey = 0; 37uint32_t Context::gThreadTLSKeyCount = 0; 38uint32_t Context::gGLContextCount = 0; 39pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER; 40 41static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { 42 if (returnVal != EGL_TRUE) { 43 fprintf(stderr, "%s() returned %d\n", op, returnVal); 44 } 45 46 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error 47 = eglGetError()) { 48 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), 49 error); 50 } 51} 52 53void Context::initEGL(bool useGL2) 54{ 55 mEGL.mNumConfigs = -1; 56 EGLint configAttribs[128]; 57 EGLint *configAttribsPtr = configAttribs; 58 EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 59 60 memset(configAttribs, 0, sizeof(configAttribs)); 61 62 configAttribsPtr[0] = EGL_SURFACE_TYPE; 63 configAttribsPtr[1] = EGL_WINDOW_BIT; 64 configAttribsPtr += 2; 65 66 if (useGL2) { 67 configAttribsPtr[0] = EGL_RENDERABLE_TYPE; 68 configAttribsPtr[1] = EGL_OPENGL_ES2_BIT; 69 configAttribsPtr += 2; 70 } 71 72 if (mUseDepth) { 73 configAttribsPtr[0] = EGL_DEPTH_SIZE; 74 configAttribsPtr[1] = 16; 75 configAttribsPtr += 2; 76 } 77 78 if (mDev->mForceSW) { 79 configAttribsPtr[0] = EGL_CONFIG_CAVEAT; 80 configAttribsPtr[1] = EGL_SLOW_CONFIG; 81 configAttribsPtr += 2; 82 } 83 84 configAttribsPtr[0] = EGL_NONE; 85 rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint)))); 86 87 LOGV("initEGL start"); 88 mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 89 checkEglError("eglGetDisplay"); 90 91 eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion); 92 checkEglError("eglInitialize"); 93 94 status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig); 95 if (err) { 96 LOGE("couldn't find an EGLConfig matching the screen format\n"); 97 } 98 //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs); 99 100 101 if (useGL2) { 102 mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, context_attribs2); 103 } else { 104 mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL); 105 } 106 checkEglError("eglCreateContext"); 107 if (mEGL.mContext == EGL_NO_CONTEXT) { 108 LOGE("eglCreateContext returned EGL_NO_CONTEXT"); 109 } 110 gGLContextCount++; 111} 112 113void Context::deinitEGL() 114{ 115 LOGV("deinitEGL"); 116 setSurface(0, 0, NULL); 117 eglDestroyContext(mEGL.mDisplay, mEGL.mContext); 118 checkEglError("eglDestroyContext"); 119 120 gGLContextCount--; 121 if (!gGLContextCount) { 122 eglTerminate(mEGL.mDisplay); 123 } 124} 125 126 127uint32_t Context::runScript(Script *s, uint32_t launchID) 128{ 129 ObjectBaseRef<ProgramFragment> frag(mFragment); 130 ObjectBaseRef<ProgramVertex> vtx(mVertex); 131 ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore); 132 ObjectBaseRef<ProgramRaster> raster(mRaster); 133 134 uint32_t ret = s->run(this, launchID); 135 136 mFragment.set(frag); 137 mVertex.set(vtx); 138 mFragmentStore.set(store); 139 mRaster.set(raster); 140 return ret; 141} 142 143 144uint32_t Context::runRootScript() 145{ 146 timerSet(RS_TIMER_CLEAR_SWAP); 147 rsAssert(mRootScript->mEnviroment.mIsRoot); 148 149 eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); 150 eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight); 151 glViewport(0, 0, mEGL.mWidth, mEGL.mHeight); 152 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 153 154 glClearColor(mRootScript->mEnviroment.mClearColor[0], 155 mRootScript->mEnviroment.mClearColor[1], 156 mRootScript->mEnviroment.mClearColor[2], 157 mRootScript->mEnviroment.mClearColor[3]); 158 if (mUseDepth) { 159 glDepthMask(GL_TRUE); 160 glClearDepthf(mRootScript->mEnviroment.mClearDepth); 161 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 162 } else { 163 glClear(GL_COLOR_BUFFER_BIT); 164 } 165 166 timerSet(RS_TIMER_SCRIPT); 167 mStateFragmentStore.mLast.clear(); 168 uint32_t ret = runScript(mRootScript.get(), 0); 169 170 GLenum err = glGetError(); 171 if (err != GL_NO_ERROR) { 172 LOGE("Pending GL Error, 0x%x", err); 173 } 174 175 return ret; 176} 177 178uint64_t Context::getTime() const 179{ 180 struct timespec t; 181 clock_gettime(CLOCK_MONOTONIC, &t); 182 return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); 183} 184 185void Context::timerReset() 186{ 187 for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) { 188 mTimers[ct] = 0; 189 } 190} 191 192void Context::timerInit() 193{ 194 mTimeLast = getTime(); 195 mTimeFrame = mTimeLast; 196 mTimeLastFrame = mTimeLast; 197 mTimerActive = RS_TIMER_INTERNAL; 198 timerReset(); 199} 200 201void Context::timerFrame() 202{ 203 mTimeLastFrame = mTimeFrame; 204 mTimeFrame = getTime(); 205} 206 207void Context::timerSet(Timers tm) 208{ 209 uint64_t last = mTimeLast; 210 mTimeLast = getTime(); 211 mTimers[mTimerActive] += mTimeLast - last; 212 mTimerActive = tm; 213} 214 215void Context::timerPrint() 216{ 217 double total = 0; 218 for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) { 219 total += mTimers[ct]; 220 } 221 uint64_t frame = mTimeFrame - mTimeLastFrame; 222 mTimeMSLastFrame = frame / 1000000; 223 mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000; 224 mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000; 225 226 227 if (props.mLogTimes) { 228 LOGV("RS: Frame (%i), Script %2.1f (%i), Clear & Swap %2.1f (%i), Idle %2.1f (%lli), Internal %2.1f (%lli)", 229 mTimeMSLastFrame, 230 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript, 231 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap, 232 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000, 233 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000); 234 } 235} 236 237void Context::setupCheck() 238{ 239 if (checkVersion2_0()) { 240 mShaderCache.lookup(mVertex.get(), mFragment.get()); 241 242 mFragmentStore->setupGL2(this, &mStateFragmentStore); 243 mFragment->setupGL2(this, &mStateFragment, &mShaderCache); 244 mRaster->setupGL2(this, &mStateRaster); 245 mVertex->setupGL2(this, &mStateVertex, &mShaderCache); 246 247 } else { 248 mFragmentStore->setupGL(this, &mStateFragmentStore); 249 mFragment->setupGL(this, &mStateFragment); 250 mRaster->setupGL(this, &mStateRaster); 251 mVertex->setupGL(this, &mStateVertex); 252 } 253} 254 255static bool getProp(const char *str) 256{ 257 char buf[PROPERTY_VALUE_MAX]; 258 property_get(str, buf, "0"); 259 return 0 != strcmp(buf, "0"); 260} 261 262void * Context::threadProc(void *vrsc) 263{ 264 Context *rsc = static_cast<Context *>(vrsc); 265 rsc->mNativeThreadId = gettid(); 266 267 setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY); 268 rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY; 269 270 rsc->props.mLogTimes = getProp("debug.rs.profile"); 271 rsc->props.mLogScripts = getProp("debug.rs.script"); 272 rsc->props.mLogObjects = getProp("debug.rs.objects"); 273 274 ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; 275 if (!tlsStruct) { 276 LOGE("Error allocating tls storage"); 277 return NULL; 278 } 279 tlsStruct->mContext = rsc; 280 tlsStruct->mScript = NULL; 281 int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct); 282 if (status) { 283 LOGE("pthread_setspecific %i", status); 284 } 285 286 rsc->mStateRaster.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); 287 rsc->setRaster(NULL); 288 rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); 289 rsc->setVertex(NULL); 290 rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); 291 rsc->setFragment(NULL); 292 rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); 293 rsc->setFragmentStore(NULL); 294 rsc->mStateVertexArray.init(rsc); 295 296 rsc->mRunning = true; 297 bool mDraw = true; 298 while (!rsc->mExit) { 299 mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw); 300 mDraw &= (rsc->mRootScript.get() != NULL); 301 mDraw &= (rsc->mWndSurface != NULL); 302 303 uint32_t targetTime = 0; 304 if (mDraw) { 305 targetTime = rsc->runRootScript(); 306 mDraw = targetTime && !rsc->mPaused; 307 rsc->timerSet(RS_TIMER_CLEAR_SWAP); 308 eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); 309 rsc->timerFrame(); 310 rsc->timerSet(RS_TIMER_INTERNAL); 311 rsc->timerPrint(); 312 rsc->timerReset(); 313 } 314 if (rsc->mObjDestroy.mNeedToEmpty) { 315 rsc->objDestroyOOBRun(); 316 } 317 if (rsc->mThreadPriority > 0 && targetTime) { 318 int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000; 319 if (t > 0) { 320 usleep(t); 321 } 322 } 323 } 324 325 LOGV("RS Thread exiting"); 326 rsc->mRaster.clear(); 327 rsc->mFragment.clear(); 328 rsc->mVertex.clear(); 329 rsc->mFragmentStore.clear(); 330 rsc->mRootScript.clear(); 331 rsc->mStateRaster.deinit(rsc); 332 rsc->mStateVertex.deinit(rsc); 333 rsc->mStateFragment.deinit(rsc); 334 rsc->mStateFragmentStore.deinit(rsc); 335 ObjectBase::zeroAllUserRef(rsc); 336 337 rsc->mObjDestroy.mNeedToEmpty = true; 338 rsc->objDestroyOOBRun(); 339 340 glClearColor(0,0,0,0); 341 glClear(GL_COLOR_BUFFER_BIT); 342 eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); 343 344 pthread_mutex_lock(&gInitMutex); 345 rsc->deinitEGL(); 346 pthread_mutex_unlock(&gInitMutex); 347 348 LOGV("RS Thread exited"); 349 return NULL; 350} 351 352void Context::setPriority(int32_t p) 353{ 354 // Note: If we put this in the proper "background" policy 355 // the wallpapers can become completly unresponsive at times. 356 // This is probably not what we want for something the user is actively 357 // looking at. 358 mThreadPriority = p; 359#if 0 360 SchedPolicy pol = SP_FOREGROUND; 361 if (p > 0) { 362 pol = SP_BACKGROUND; 363 } 364 if (!set_sched_policy(mNativeThreadId, pol)) { 365 // success; reset the priority as well 366 } 367#else 368 setpriority(PRIO_PROCESS, mNativeThreadId, p); 369#endif 370} 371 372Context::Context(Device *dev, bool useDepth) 373{ 374 pthread_mutex_lock(&gInitMutex); 375 376 dev->addContext(this); 377 mDev = dev; 378 mRunning = false; 379 mExit = false; 380 mUseDepth = useDepth; 381 mPaused = false; 382 mObjHead = NULL; 383 memset(&mEGL, 0, sizeof(mEGL)); 384 385 int status; 386 pthread_attr_t threadAttr; 387 388 if (!gThreadTLSKeyCount) { 389 status = pthread_key_create(&gThreadTLSKey, NULL); 390 if (status) { 391 LOGE("Failed to init thread tls key."); 392 pthread_mutex_unlock(&gInitMutex); 393 return; 394 } 395 } 396 gThreadTLSKeyCount++; 397 pthread_mutex_unlock(&gInitMutex); 398 399 // Global init done at this point. 400 401 status = pthread_attr_init(&threadAttr); 402 if (status) { 403 LOGE("Failed to init thread attribute."); 404 return; 405 } 406 407 mWndSurface = NULL; 408 409 objDestroyOOBInit(); 410 timerInit(); 411 timerSet(RS_TIMER_INTERNAL); 412 413 LOGV("RS Launching thread"); 414 status = pthread_create(&mThreadId, &threadAttr, threadProc, this); 415 if (status) { 416 LOGE("Failed to start rs context thread."); 417 } 418 419 while(!mRunning) { 420 usleep(100); 421 } 422 423 pthread_attr_destroy(&threadAttr); 424} 425 426Context::~Context() 427{ 428 LOGV("Context::~Context"); 429 mExit = true; 430 mPaused = false; 431 void *res; 432 433 mIO.shutdown(); 434 int status = pthread_join(mThreadId, &res); 435 mObjDestroy.mNeedToEmpty = true; 436 objDestroyOOBRun(); 437 438 // Global structure cleanup. 439 pthread_mutex_lock(&gInitMutex); 440 if (mDev) { 441 mDev->removeContext(this); 442 --gThreadTLSKeyCount; 443 if (!gThreadTLSKeyCount) { 444 pthread_key_delete(gThreadTLSKey); 445 } 446 mDev = NULL; 447 } 448 pthread_mutex_unlock(&gInitMutex); 449 450 objDestroyOOBDestroy(); 451} 452 453void Context::setSurface(uint32_t w, uint32_t h, Surface *sur) 454{ 455 LOGV("setSurface %i %i %p", w, h, sur); 456 457 EGLBoolean ret; 458 if (mEGL.mSurface != NULL) { 459 ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 460 checkEglError("eglMakeCurrent", ret); 461 462 ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface); 463 checkEglError("eglDestroySurface", ret); 464 465 mEGL.mSurface = NULL; 466 mEGL.mWidth = 0; 467 mEGL.mHeight = 0; 468 mWidth = 0; 469 mHeight = 0; 470 } 471 472 mWndSurface = sur; 473 if (mWndSurface != NULL) { 474 bool first = false; 475 if (!mEGL.mContext) { 476 first = true; 477 pthread_mutex_lock(&gInitMutex); 478 initEGL(true); 479 pthread_mutex_unlock(&gInitMutex); 480 } 481 482 mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL); 483 checkEglError("eglCreateWindowSurface"); 484 if (mEGL.mSurface == EGL_NO_SURFACE) { 485 LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE"); 486 } 487 488 ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext); 489 checkEglError("eglMakeCurrent", ret); 490 491 eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); 492 eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight); 493 mWidth = w; 494 mHeight = h; 495 mStateVertex.updateSize(this, w, h); 496 497 if ((int)mWidth != mEGL.mWidth || (int)mHeight != mEGL.mHeight) { 498 LOGE("EGL/Surface mismatch EGL (%i x %i) SF (%i x %i)", mEGL.mWidth, mEGL.mHeight, mWidth, mHeight); 499 } 500 501 if (first) { 502 mGL.mVersion = glGetString(GL_VERSION); 503 mGL.mVendor = glGetString(GL_VENDOR); 504 mGL.mRenderer = glGetString(GL_RENDERER); 505 mGL.mExtensions = glGetString(GL_EXTENSIONS); 506 507 //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); 508 LOGV("GL Version %s", mGL.mVersion); 509 //LOGV("GL Vendor %s", mGL.mVendor); 510 LOGV("GL Renderer %s", mGL.mRenderer); 511 //LOGV("GL Extensions %s", mGL.mExtensions); 512 513 const char *verptr = NULL; 514 if (strlen((const char *)mGL.mVersion) > 9) { 515 if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { 516 verptr = (const char *)mGL.mVersion + 12; 517 } 518 if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) { 519 verptr = (const char *)mGL.mVersion + 9; 520 } 521 } 522 523 if (!verptr) { 524 LOGE("Error, OpenGL ES Lite not supported"); 525 } else { 526 sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); 527 } 528 } 529 530 } 531} 532 533void Context::pause() 534{ 535 mPaused = true; 536} 537 538void Context::resume() 539{ 540 mPaused = false; 541} 542 543void Context::setRootScript(Script *s) 544{ 545 mRootScript.set(s); 546} 547 548void Context::setFragmentStore(ProgramFragmentStore *pfs) 549{ 550 if (pfs == NULL) { 551 mFragmentStore.set(mStateFragmentStore.mDefault); 552 } else { 553 mFragmentStore.set(pfs); 554 } 555} 556 557void Context::setFragment(ProgramFragment *pf) 558{ 559 if (pf == NULL) { 560 mFragment.set(mStateFragment.mDefault); 561 } else { 562 mFragment.set(pf); 563 } 564} 565 566void Context::setRaster(ProgramRaster *pr) 567{ 568 if (pr == NULL) { 569 mRaster.set(mStateRaster.mDefault); 570 } else { 571 mRaster.set(pr); 572 } 573} 574 575void Context::setVertex(ProgramVertex *pv) 576{ 577 if (pv == NULL) { 578 mVertex.set(mStateVertex.mDefault); 579 } else { 580 mVertex.set(pv); 581 } 582} 583 584void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) 585{ 586 rsAssert(!obj->getName()); 587 obj->setName(name, len); 588 mNames.add(obj); 589} 590 591void Context::removeName(ObjectBase *obj) 592{ 593 for(size_t ct=0; ct < mNames.size(); ct++) { 594 if (obj == mNames[ct]) { 595 mNames.removeAt(ct); 596 return; 597 } 598 } 599} 600 601ObjectBase * Context::lookupName(const char *name) const 602{ 603 for(size_t ct=0; ct < mNames.size(); ct++) { 604 if (!strcmp(name, mNames[ct]->getName())) { 605 return mNames[ct]; 606 } 607 } 608 return NULL; 609} 610 611void Context::appendNameDefines(String8 *str) const 612{ 613 char buf[256]; 614 for (size_t ct=0; ct < mNames.size(); ct++) { 615 str->append("#define NAMED_"); 616 str->append(mNames[ct]->getName()); 617 str->append(" "); 618 sprintf(buf, "%i\n", (int)mNames[ct]); 619 str->append(buf); 620 } 621} 622 623void Context::appendVarDefines(String8 *str) const 624{ 625 char buf[256]; 626 for (size_t ct=0; ct < mInt32Defines.size(); ct++) { 627 str->append("#define "); 628 str->append(mInt32Defines.keyAt(ct)); 629 str->append(" "); 630 sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct)); 631 str->append(buf); 632 633 } 634 for (size_t ct=0; ct < mFloatDefines.size(); ct++) { 635 str->append("#define "); 636 str->append(mFloatDefines.keyAt(ct)); 637 str->append(" "); 638 sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct)); 639 str->append(buf); 640 } 641} 642 643bool Context::objDestroyOOBInit() 644{ 645 int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL); 646 if (status) { 647 LOGE("Context::ObjDestroyOOBInit mutex init failure"); 648 return false; 649 } 650 return true; 651} 652 653void Context::objDestroyOOBRun() 654{ 655 if (mObjDestroy.mNeedToEmpty) { 656 int status = pthread_mutex_lock(&mObjDestroy.mMutex); 657 if (status) { 658 LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status); 659 return; 660 } 661 662 for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) { 663 mObjDestroy.mDestroyList[ct]->decUserRef(); 664 } 665 mObjDestroy.mDestroyList.clear(); 666 mObjDestroy.mNeedToEmpty = false; 667 668 status = pthread_mutex_unlock(&mObjDestroy.mMutex); 669 if (status) { 670 LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status); 671 } 672 } 673} 674 675void Context::objDestroyOOBDestroy() 676{ 677 rsAssert(!mObjDestroy.mNeedToEmpty); 678 pthread_mutex_destroy(&mObjDestroy.mMutex); 679} 680 681void Context::objDestroyAdd(ObjectBase *obj) 682{ 683 int status = pthread_mutex_lock(&mObjDestroy.mMutex); 684 if (status) { 685 LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status); 686 return; 687 } 688 689 mObjDestroy.mNeedToEmpty = true; 690 mObjDestroy.mDestroyList.add(obj); 691 692 status = pthread_mutex_unlock(&mObjDestroy.mMutex); 693 if (status) { 694 LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status); 695 } 696} 697 698uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait) 699{ 700 //LOGE("getMessageToClient %i %i", bufferLen, wait); 701 if (!wait) { 702 if (mIO.mToClient.isEmpty()) { 703 // No message to get and not going to wait for one. 704 receiveLen = 0; 705 return 0; 706 } 707 } 708 709 //LOGE("getMessageToClient 2 con=%p", this); 710 uint32_t bytesData = 0; 711 uint32_t commandID = 0; 712 const void *d = mIO.mToClient.get(&commandID, &bytesData); 713 //LOGE("getMessageToClient 3 %i %i", commandID, bytesData); 714 715 *receiveLen = bytesData; 716 if (bufferLen >= bytesData) { 717 memcpy(data, d, bytesData); 718 mIO.mToClient.next(); 719 return commandID; 720 } 721 return 0; 722} 723 724bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace) 725{ 726 //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace); 727 if (cmdID == 0) { 728 LOGE("Attempting to send invalid command 0 to client."); 729 return false; 730 } 731 if (!waitForSpace) { 732 if (mIO.mToClient.getFreeSpace() < len) { 733 // Not enough room, and not waiting. 734 return false; 735 } 736 } 737 //LOGE("sendMessageToClient 2"); 738 void *p = mIO.mToClient.reserve(len); 739 memcpy(p, data, len); 740 mIO.mToClient.commit(cmdID, len); 741 //LOGE("sendMessageToClient 3"); 742 return true; 743} 744 745void Context::initToClient() 746{ 747 while(!mRunning) { 748 usleep(100); 749 } 750} 751 752void Context::deinitToClient() 753{ 754 mIO.mToClient.shutdown(); 755} 756 757void Context::dumpDebug() const 758{ 759 LOGE("RS Context debug %p", this); 760 LOGE("RS Context debug"); 761 762 LOGE(" EGL ver %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); 763 LOGE(" EGL context %p surface %p, w=%i h=%i Display=%p", mEGL.mContext, 764 mEGL.mSurface, mEGL.mWidth, mEGL.mHeight, mEGL.mDisplay); 765 LOGE(" GL vendor: %s", mGL.mVendor); 766 LOGE(" GL renderer: %s", mGL.mRenderer); 767 LOGE(" GL Version: %s", mGL.mVersion); 768 LOGE(" GL Extensions: %s", mGL.mExtensions); 769 LOGE(" GL int Versions %i %i", mGL.mMajorVersion, mGL.mMinorVersion); 770 LOGE(" RS width %i, height %i", mWidth, mHeight); 771 LOGE(" RS running %i, exit %i, useDepth %i, paused %i", mRunning, mExit, mUseDepth, mPaused); 772 LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId); 773 774} 775 776/////////////////////////////////////////////////////////////////////////////////////////// 777// 778 779namespace android { 780namespace renderscript { 781 782 783void rsi_ContextBindRootScript(Context *rsc, RsScript vs) 784{ 785 Script *s = static_cast<Script *>(vs); 786 rsc->setRootScript(s); 787} 788 789void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) 790{ 791 Sampler *s = static_cast<Sampler *>(vs); 792 793 if (slot > RS_MAX_SAMPLER_SLOT) { 794 LOGE("Invalid sampler slot"); 795 return; 796 } 797 798 s->bindToContext(&rsc->mStateSampler, slot); 799} 800 801void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs) 802{ 803 ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs); 804 rsc->setFragmentStore(pfs); 805} 806 807void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) 808{ 809 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 810 rsc->setFragment(pf); 811} 812 813void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr) 814{ 815 ProgramRaster *pr = static_cast<ProgramRaster *>(vpr); 816 rsc->setRaster(pr); 817} 818 819void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) 820{ 821 ProgramVertex *pv = static_cast<ProgramVertex *>(vpv); 822 rsc->setVertex(pv); 823} 824 825void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len) 826{ 827 ObjectBase *ob = static_cast<ObjectBase *>(obj); 828 rsc->assignName(ob, name, len); 829} 830 831void rsi_ObjDestroy(Context *rsc, void *obj) 832{ 833 ObjectBase *ob = static_cast<ObjectBase *>(obj); 834 rsc->removeName(ob); 835 ob->decUserRef(); 836} 837 838void rsi_ContextSetDefineF(Context *rsc, const char* name, float value) 839{ 840 rsc->addInt32Define(name, value); 841} 842 843void rsi_ContextSetDefineI32(Context *rsc, const char* name, int32_t value) 844{ 845 rsc->addFloatDefine(name, value); 846} 847 848void rsi_ContextPause(Context *rsc) 849{ 850 rsc->pause(); 851} 852 853void rsi_ContextResume(Context *rsc) 854{ 855 rsc->resume(); 856} 857 858void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, void *sur) 859{ 860 rsc->setSurface(w, h, (Surface *)sur); 861} 862 863void rsi_ContextSetPriority(Context *rsc, int32_t p) 864{ 865 rsc->setPriority(p); 866} 867 868void rsi_ContextDump(Context *rsc, int32_t bits) 869{ 870 ObjectBase::dumpAll(rsc); 871} 872 873} 874} 875 876 877RsContext rsContextCreate(RsDevice vdev, uint32_t version, bool useDepth) 878{ 879 Device * dev = static_cast<Device *>(vdev); 880 Context *rsc = new Context(dev, useDepth); 881 return rsc; 882} 883 884void rsContextDestroy(RsContext vrsc) 885{ 886 Context * rsc = static_cast<Context *>(vrsc); 887 delete rsc; 888} 889 890void rsObjDestroyOOB(RsContext vrsc, void *obj) 891{ 892 Context * rsc = static_cast<Context *>(vrsc); 893 rsc->objDestroyAdd(static_cast<ObjectBase *>(obj)); 894} 895 896uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait) 897{ 898 Context * rsc = static_cast<Context *>(vrsc); 899 return rsc->getMessageToClient(data, receiveLen, bufferLen, wait); 900} 901 902void rsContextInitToClient(RsContext vrsc) 903{ 904 Context * rsc = static_cast<Context *>(vrsc); 905 rsc->initToClient(); 906} 907 908void rsContextDeinitToClient(RsContext vrsc) 909{ 910 Context * rsc = static_cast<Context *>(vrsc); 911 rsc->deinitToClient(); 912} 913 914