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