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