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