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