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