rsContext.cpp revision 8c88090e8cccab103eebe2ff569e116e9f5fb208
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) 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); 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 glViewport(0, 0, mWidth, mHeight); 157 158 timerSet(RS_TIMER_SCRIPT); 159 mStateFragmentStore.mLast.clear(); 160 uint32_t ret = runScript(mRootScript.get()); 161 162 checkError("runRootScript"); 163 if (mError != RS_ERROR_NONE) { 164 // If we have an error condition we stop rendering until 165 // somthing changes that might fix it. 166 ret = 0; 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 mTimeMSLastFrame = frame / 1000000; 216 mTimeMSLastScript = mTimers[RS_TIMER_SCRIPT] / 1000000; 217 mTimeMSLastSwap = mTimers[RS_TIMER_CLEAR_SWAP] / 1000000; 218 219 220 if (props.mLogTimes) { 221 LOGV("RS: Frame (%i), Script %2.1f (%i), Clear & Swap %2.1f (%i), Idle %2.1f (%lli), Internal %2.1f (%lli)", 222 mTimeMSLastFrame, 223 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript, 224 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap, 225 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000, 226 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000); 227 } 228} 229 230bool Context::setupCheck() 231{ 232 if (checkVersion2_0()) { 233 if (!mShaderCache.lookup(this, mVertex.get(), mFragment.get())) { 234 LOGE("Context::setupCheck() 1 fail"); 235 return false; 236 } 237 238 mFragmentStore->setupGL2(this, &mStateFragmentStore); 239 mFragment->setupGL2(this, &mStateFragment, &mShaderCache); 240 mRaster->setupGL2(this, &mStateRaster); 241 mVertex->setupGL2(this, &mStateVertex, &mShaderCache); 242 243 } else { 244 mFragmentStore->setupGL(this, &mStateFragmentStore); 245 mFragment->setupGL(this, &mStateFragment); 246 mRaster->setupGL(this, &mStateRaster); 247 mVertex->setupGL(this, &mStateVertex); 248 } 249 return true; 250} 251 252static bool getProp(const char *str) 253{ 254 char buf[PROPERTY_VALUE_MAX]; 255 property_get(str, buf, "0"); 256 return 0 != strcmp(buf, "0"); 257} 258 259void * Context::threadProc(void *vrsc) 260{ 261 Context *rsc = static_cast<Context *>(vrsc); 262 rsc->mNativeThreadId = gettid(); 263 264 setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY); 265 rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY; 266 267 rsc->props.mLogTimes = getProp("debug.rs.profile"); 268 rsc->props.mLogScripts = getProp("debug.rs.script"); 269 rsc->props.mLogObjects = getProp("debug.rs.object"); 270 rsc->props.mLogShaders = getProp("debug.rs.shader"); 271 272 ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; 273 if (!tlsStruct) { 274 LOGE("Error allocating tls storage"); 275 return NULL; 276 } 277 tlsStruct->mContext = rsc; 278 tlsStruct->mScript = NULL; 279 int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct); 280 if (status) { 281 LOGE("pthread_setspecific %i", status); 282 } 283 284 if (rsc->mIsGraphicsContext) { 285 rsc->mStateRaster.init(rsc); 286 rsc->setRaster(NULL); 287 rsc->mStateVertex.init(rsc); 288 rsc->setVertex(NULL); 289 rsc->mStateFragment.init(rsc); 290 rsc->setFragment(NULL); 291 rsc->mStateFragmentStore.init(rsc); 292 rsc->setFragmentStore(NULL); 293 rsc->mStateVertexArray.init(rsc); 294 } 295 296 rsc->mRunning = true; 297 bool mDraw = true; 298 while (!rsc->mExit) { 299 mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw); 300 mDraw &= (rsc->mRootScript.get() != NULL); 301 mDraw &= (rsc->mWndSurface != NULL); 302 303 uint32_t targetTime = 0; 304 if (mDraw && rsc->mIsGraphicsContext) { 305 targetTime = rsc->runRootScript(); 306 mDraw = targetTime && !rsc->mPaused; 307 rsc->timerSet(RS_TIMER_CLEAR_SWAP); 308 eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); 309 rsc->timerFrame(); 310 rsc->timerSet(RS_TIMER_INTERNAL); 311 rsc->timerPrint(); 312 rsc->timerReset(); 313 } 314 if (rsc->mObjDestroy.mNeedToEmpty) { 315 rsc->objDestroyOOBRun(); 316 } 317 if (rsc->mThreadPriority > 0 && targetTime) { 318 int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000; 319 if (t > 0) { 320 usleep(t); 321 } 322 } 323 } 324 325 LOGV("RS Thread exiting"); 326 if (rsc->mIsGraphicsContext) { 327 rsc->mRaster.clear(); 328 rsc->mFragment.clear(); 329 rsc->mVertex.clear(); 330 rsc->mFragmentStore.clear(); 331 rsc->mRootScript.clear(); 332 rsc->mStateRaster.deinit(rsc); 333 rsc->mStateVertex.deinit(rsc); 334 rsc->mStateFragment.deinit(rsc); 335 rsc->mStateFragmentStore.deinit(rsc); 336 } 337 ObjectBase::zeroAllUserRef(rsc); 338 339 rsc->mObjDestroy.mNeedToEmpty = true; 340 rsc->objDestroyOOBRun(); 341 342 if (rsc->mIsGraphicsContext) { 343 pthread_mutex_lock(&gInitMutex); 344 rsc->deinitEGL(); 345 pthread_mutex_unlock(&gInitMutex); 346 } 347 348 LOGV("RS Thread exited"); 349 return NULL; 350} 351 352void Context::setPriority(int32_t p) 353{ 354 // Note: If we put this in the proper "background" policy 355 // the wallpapers can become completly unresponsive at times. 356 // This is probably not what we want for something the user is actively 357 // looking at. 358 mThreadPriority = p; 359#if 0 360 SchedPolicy pol = SP_FOREGROUND; 361 if (p > 0) { 362 pol = SP_BACKGROUND; 363 } 364 if (!set_sched_policy(mNativeThreadId, pol)) { 365 // success; reset the priority as well 366 } 367#else 368 setpriority(PRIO_PROCESS, mNativeThreadId, p); 369#endif 370} 371 372Context::Context(Device *dev, bool isGraphics, bool useDepth) 373{ 374 pthread_mutex_lock(&gInitMutex); 375 376 dev->addContext(this); 377 mDev = dev; 378 mRunning = false; 379 mExit = false; 380 mUseDepth = useDepth; 381 mPaused = false; 382 mObjHead = NULL; 383 mError = RS_ERROR_NONE; 384 mErrorMsg = NULL; 385 386 memset(&mEGL, 0, sizeof(mEGL)); 387 memset(&mGL, 0, sizeof(mGL)); 388 mIsGraphicsContext = isGraphics; 389 390 int status; 391 pthread_attr_t threadAttr; 392 393 if (!gThreadTLSKeyCount) { 394 status = pthread_key_create(&gThreadTLSKey, NULL); 395 if (status) { 396 LOGE("Failed to init thread tls key."); 397 pthread_mutex_unlock(&gInitMutex); 398 return; 399 } 400 } 401 gThreadTLSKeyCount++; 402 pthread_mutex_unlock(&gInitMutex); 403 404 // Global init done at this point. 405 406 status = pthread_attr_init(&threadAttr); 407 if (status) { 408 LOGE("Failed to init thread attribute."); 409 return; 410 } 411 412 mWndSurface = NULL; 413 414 objDestroyOOBInit(); 415 timerInit(); 416 timerSet(RS_TIMER_INTERNAL); 417 418 LOGV("RS Launching thread"); 419 status = pthread_create(&mThreadId, &threadAttr, threadProc, this); 420 if (status) { 421 LOGE("Failed to start rs context thread."); 422 } 423 424 while(!mRunning) { 425 usleep(100); 426 } 427 428 pthread_attr_destroy(&threadAttr); 429} 430 431Context::~Context() 432{ 433 LOGV("Context::~Context"); 434 mExit = true; 435 mPaused = false; 436 void *res; 437 438 mIO.shutdown(); 439 int status = pthread_join(mThreadId, &res); 440 mObjDestroy.mNeedToEmpty = true; 441 objDestroyOOBRun(); 442 443 // Global structure cleanup. 444 pthread_mutex_lock(&gInitMutex); 445 if (mDev) { 446 mDev->removeContext(this); 447 --gThreadTLSKeyCount; 448 if (!gThreadTLSKeyCount) { 449 pthread_key_delete(gThreadTLSKey); 450 } 451 mDev = NULL; 452 } 453 pthread_mutex_unlock(&gInitMutex); 454 455 objDestroyOOBDestroy(); 456} 457 458void Context::setSurface(uint32_t w, uint32_t h, android_native_window_t *sur) 459{ 460 rsAssert(mIsGraphicsContext); 461 462 EGLBoolean ret; 463 if (mEGL.mSurface != NULL) { 464 ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 465 checkEglError("eglMakeCurrent", ret); 466 467 ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface); 468 checkEglError("eglDestroySurface", ret); 469 470 mEGL.mSurface = NULL; 471 mWidth = 0; 472 mHeight = 0; 473 } 474 475 mWndSurface = sur; 476 if (mWndSurface != NULL) { 477 mWidth = w; 478 mHeight = h; 479 bool first = false; 480 if (!mEGL.mContext) { 481 first = true; 482 pthread_mutex_lock(&gInitMutex); 483 initEGL(true); 484 pthread_mutex_unlock(&gInitMutex); 485 } 486 487 mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL); 488 checkEglError("eglCreateWindowSurface"); 489 if (mEGL.mSurface == EGL_NO_SURFACE) { 490 LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE"); 491 } 492 493 ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext); 494 checkEglError("eglMakeCurrent", ret); 495 496 mStateVertex.updateSize(this); 497 498 if (first) { 499 mGL.mVersion = glGetString(GL_VERSION); 500 mGL.mVendor = glGetString(GL_VENDOR); 501 mGL.mRenderer = glGetString(GL_RENDERER); 502 mGL.mExtensions = glGetString(GL_EXTENSIONS); 503 504 //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); 505 LOGV("GL Version %s", mGL.mVersion); 506 //LOGV("GL Vendor %s", mGL.mVendor); 507 LOGV("GL Renderer %s", mGL.mRenderer); 508 //LOGV("GL Extensions %s", mGL.mExtensions); 509 510 const char *verptr = NULL; 511 if (strlen((const char *)mGL.mVersion) > 9) { 512 if (!memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { 513 verptr = (const char *)mGL.mVersion + 12; 514 } 515 if (!memcmp(mGL.mVersion, "OpenGL ES ", 10)) { 516 verptr = (const char *)mGL.mVersion + 9; 517 } 518 } 519 520 if (!verptr) { 521 LOGE("Error, OpenGL ES Lite not supported"); 522 } else { 523 sscanf(verptr, " %i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); 524 } 525 526 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mGL.mMaxVertexAttribs); 527 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &mGL.mMaxVertexUniformVectors); 528 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGL.mMaxVertexTextureUnits); 529 530 glGetIntegerv(GL_MAX_VARYING_VECTORS, &mGL.mMaxVaryingVectors); 531 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGL.mMaxTextureImageUnits); 532 533 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mGL.mMaxFragmentTextureImageUnits); 534 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGL.mMaxFragmentUniformVectors); 535 536 mGL.OES_texture_npot = NULL != strstr((const char *)mGL.mExtensions, "GL_OES_texture_npot"); 537 } 538 539 } 540} 541 542void Context::pause() 543{ 544 rsAssert(mIsGraphicsContext); 545 mPaused = true; 546} 547 548void Context::resume() 549{ 550 rsAssert(mIsGraphicsContext); 551 mPaused = false; 552} 553 554void Context::setRootScript(Script *s) 555{ 556 rsAssert(mIsGraphicsContext); 557 mRootScript.set(s); 558} 559 560void Context::setFragmentStore(ProgramStore *pfs) 561{ 562 rsAssert(mIsGraphicsContext); 563 if (pfs == NULL) { 564 mFragmentStore.set(mStateFragmentStore.mDefault); 565 } else { 566 mFragmentStore.set(pfs); 567 } 568} 569 570void Context::setFragment(ProgramFragment *pf) 571{ 572 rsAssert(mIsGraphicsContext); 573 if (pf == NULL) { 574 mFragment.set(mStateFragment.mDefault); 575 } else { 576 mFragment.set(pf); 577 } 578} 579 580void Context::setRaster(ProgramRaster *pr) 581{ 582 rsAssert(mIsGraphicsContext); 583 if (pr == NULL) { 584 mRaster.set(mStateRaster.mDefault); 585 } else { 586 mRaster.set(pr); 587 } 588} 589 590void Context::setVertex(ProgramVertex *pv) 591{ 592 rsAssert(mIsGraphicsContext); 593 if (pv == NULL) { 594 mVertex.set(mStateVertex.mDefault); 595 } else { 596 mVertex.set(pv); 597 } 598} 599 600void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) 601{ 602 rsAssert(!obj->getName()); 603 obj->setName(name, len); 604 mNames.add(obj); 605} 606 607void Context::removeName(ObjectBase *obj) 608{ 609 for(size_t ct=0; ct < mNames.size(); ct++) { 610 if (obj == mNames[ct]) { 611 mNames.removeAt(ct); 612 return; 613 } 614 } 615} 616 617bool Context::objDestroyOOBInit() 618{ 619 if (!mObjDestroy.mMutex.init()) { 620 LOGE("Context::ObjDestroyOOBInit mutex init failure"); 621 return false; 622 } 623 return true; 624} 625 626void Context::objDestroyOOBRun() 627{ 628 if (mObjDestroy.mNeedToEmpty) { 629 if (!mObjDestroy.mMutex.lock()) { 630 LOGE("Context::ObjDestroyOOBRun: error locking for OOBRun."); 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 mObjDestroy.mMutex.unlock(); 640 } 641} 642 643void Context::objDestroyOOBDestroy() 644{ 645 rsAssert(!mObjDestroy.mNeedToEmpty); 646} 647 648void Context::objDestroyAdd(ObjectBase *obj) 649{ 650 if (!mObjDestroy.mMutex.lock()) { 651 LOGE("Context::ObjDestroyOOBRun: error locking for OOBRun."); 652 return; 653 } 654 655 mObjDestroy.mNeedToEmpty = true; 656 mObjDestroy.mDestroyList.add(obj); 657 mObjDestroy.mMutex.unlock(); 658} 659 660uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait) 661{ 662 //LOGE("getMessageToClient %i %i", bufferLen, wait); 663 if (!wait) { 664 if (mIO.mToClient.isEmpty()) { 665 // No message to get and not going to wait for one. 666 receiveLen = 0; 667 return 0; 668 } 669 } 670 671 //LOGE("getMessageToClient 2 con=%p", this); 672 uint32_t bytesData = 0; 673 uint32_t commandID = 0; 674 const void *d = mIO.mToClient.get(&commandID, &bytesData); 675 //LOGE("getMessageToClient 3 %i %i", commandID, bytesData); 676 677 *receiveLen = bytesData; 678 if (bufferLen >= bytesData) { 679 memcpy(data, d, bytesData); 680 mIO.mToClient.next(); 681 return commandID; 682 } 683 return 0; 684} 685 686bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace) 687{ 688 //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace); 689 if (cmdID == 0) { 690 LOGE("Attempting to send invalid command 0 to client."); 691 return false; 692 } 693 if (!waitForSpace) { 694 if (mIO.mToClient.getFreeSpace() < len) { 695 // Not enough room, and not waiting. 696 return false; 697 } 698 } 699 //LOGE("sendMessageToClient 2"); 700 void *p = mIO.mToClient.reserve(len); 701 memcpy(p, data, len); 702 mIO.mToClient.commit(cmdID, len); 703 //LOGE("sendMessageToClient 3"); 704 return true; 705} 706 707void Context::initToClient() 708{ 709 while(!mRunning) { 710 usleep(100); 711 } 712} 713 714void Context::deinitToClient() 715{ 716 mIO.mToClient.shutdown(); 717} 718 719const char * Context::getError(RsError *err) 720{ 721 *err = mError; 722 mError = RS_ERROR_NONE; 723 if (*err != RS_ERROR_NONE) { 724 return mErrorMsg; 725 } 726 return NULL; 727} 728 729void Context::setError(RsError e, const char *msg) 730{ 731 mError = e; 732 mErrorMsg = msg; 733} 734 735 736void Context::dumpDebug() const 737{ 738 LOGE("RS Context debug %p", this); 739 LOGE("RS Context debug"); 740 741 LOGE(" EGL ver %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); 742 LOGE(" EGL context %p surface %p, Display=%p", mEGL.mContext, mEGL.mSurface, mEGL.mDisplay); 743 LOGE(" GL vendor: %s", mGL.mVendor); 744 LOGE(" GL renderer: %s", mGL.mRenderer); 745 LOGE(" GL Version: %s", mGL.mVersion); 746 LOGE(" GL Extensions: %s", mGL.mExtensions); 747 LOGE(" GL int Versions %i %i", mGL.mMajorVersion, mGL.mMinorVersion); 748 LOGE(" RS width %i, height %i", mWidth, mHeight); 749 LOGE(" RS running %i, exit %i, useDepth %i, paused %i", mRunning, mExit, mUseDepth, mPaused); 750 LOGE(" RS pThreadID %li, nativeThreadID %i", mThreadId, mNativeThreadId); 751 752 LOGV("MAX Textures %i, %i %i", mGL.mMaxVertexTextureUnits, mGL.mMaxFragmentTextureImageUnits, mGL.mMaxTextureImageUnits); 753 LOGV("MAX Attribs %i", mGL.mMaxVertexAttribs); 754 LOGV("MAX Uniforms %i, %i", mGL.mMaxVertexUniformVectors, mGL.mMaxFragmentUniformVectors); 755 LOGV("MAX Varyings %i", mGL.mMaxVaryingVectors); 756} 757 758/////////////////////////////////////////////////////////////////////////////////////////// 759// 760 761namespace android { 762namespace renderscript { 763 764void rsi_ContextFinish(Context *rsc) 765{ 766} 767 768void rsi_ContextBindRootScript(Context *rsc, RsScript vs) 769{ 770 Script *s = static_cast<Script *>(vs); 771 rsc->setRootScript(s); 772} 773 774void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) 775{ 776 Sampler *s = static_cast<Sampler *>(vs); 777 778 if (slot > RS_MAX_SAMPLER_SLOT) { 779 LOGE("Invalid sampler slot"); 780 return; 781 } 782 783 s->bindToContext(&rsc->mStateSampler, slot); 784} 785 786void rsi_ContextBindProgramStore(Context *rsc, RsProgramStore vpfs) 787{ 788 ProgramStore *pfs = static_cast<ProgramStore *>(vpfs); 789 rsc->setFragmentStore(pfs); 790} 791 792void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) 793{ 794 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 795 rsc->setFragment(pf); 796} 797 798void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr) 799{ 800 ProgramRaster *pr = static_cast<ProgramRaster *>(vpr); 801 rsc->setRaster(pr); 802} 803 804void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) 805{ 806 ProgramVertex *pv = static_cast<ProgramVertex *>(vpv); 807 rsc->setVertex(pv); 808} 809 810void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len) 811{ 812 ObjectBase *ob = static_cast<ObjectBase *>(obj); 813 rsc->assignName(ob, name, len); 814} 815 816void rsi_ObjDestroy(Context *rsc, void *obj) 817{ 818 ObjectBase *ob = static_cast<ObjectBase *>(obj); 819 rsc->removeName(ob); 820 ob->decUserRef(); 821} 822 823void rsi_ContextPause(Context *rsc) 824{ 825 rsc->pause(); 826} 827 828void rsi_ContextResume(Context *rsc) 829{ 830 rsc->resume(); 831} 832 833void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, android_native_window_t *sur) 834{ 835 rsc->setSurface(w, h, sur); 836} 837 838void rsi_ContextSetPriority(Context *rsc, int32_t p) 839{ 840 rsc->setPriority(p); 841} 842 843void rsi_ContextDump(Context *rsc, int32_t bits) 844{ 845 ObjectBase::dumpAll(rsc); 846} 847 848const char * rsi_ContextGetError(Context *rsc, RsError *e) 849{ 850 const char *msg = rsc->getError(e); 851 if (*e != RS_ERROR_NONE) { 852 LOGE("RS Error %i %s", *e, msg); 853 } 854 return msg; 855} 856 857} 858} 859 860 861RsContext rsContextCreate(RsDevice vdev, uint32_t version) 862{ 863 LOGV("rsContextCreate %p", vdev); 864 Device * dev = static_cast<Device *>(vdev); 865 Context *rsc = new Context(dev, false, false); 866 return rsc; 867} 868 869RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, bool useDepth) 870{ 871 LOGV("rsContextCreateGL %p, %i", vdev, useDepth); 872 Device * dev = static_cast<Device *>(vdev); 873 Context *rsc = new Context(dev, true, useDepth); 874 return rsc; 875} 876 877void rsContextDestroy(RsContext vrsc) 878{ 879 Context * rsc = static_cast<Context *>(vrsc); 880 delete rsc; 881} 882 883void rsObjDestroyOOB(RsContext vrsc, void *obj) 884{ 885 Context * rsc = static_cast<Context *>(vrsc); 886 rsc->objDestroyAdd(static_cast<ObjectBase *>(obj)); 887} 888 889uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait) 890{ 891 Context * rsc = static_cast<Context *>(vrsc); 892 return rsc->getMessageToClient(data, receiveLen, bufferLen, wait); 893} 894 895void rsContextInitToClient(RsContext vrsc) 896{ 897 Context * rsc = static_cast<Context *>(vrsc); 898 rsc->initToClient(); 899} 900 901void rsContextDeinitToClient(RsContext vrsc) 902{ 903 Context * rsc = static_cast<Context *>(vrsc); 904 rsc->deinitToClient(); 905} 906 907