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