rsContext.cpp revision afcb25c65e8145d15aaf50a0ca38333954a97000
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 <GLES/gl.h> 24#include <GLES/glext.h> 25 26using namespace android; 27using namespace android::renderscript; 28 29pthread_key_t Context::gThreadTLSKey = 0; 30 31void Context::initEGL() 32{ 33 mEGL.mNumConfigs = -1; 34 EGLint configAttribs[128]; 35 EGLint *configAttribsPtr = configAttribs; 36 37 memset(configAttribs, 0, sizeof(configAttribs)); 38 39 configAttribsPtr[0] = EGL_SURFACE_TYPE; 40 configAttribsPtr[1] = EGL_WINDOW_BIT; 41 configAttribsPtr += 2; 42 43 if (mUseDepth) { 44 configAttribsPtr[0] = EGL_DEPTH_SIZE; 45 configAttribsPtr[1] = 16; 46 configAttribsPtr += 2; 47 } 48 configAttribsPtr[0] = EGL_NONE; 49 rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint)))); 50 51 mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 52 eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion); 53 54 status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig); 55 if (err) { 56 LOGE("couldn't find an EGLConfig matching the screen format\n"); 57 } 58 //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs); 59 60 if (mWndSurface) { 61 mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL); 62 } else { 63 mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, 64 android_createDisplaySurface(), 65 NULL); 66 } 67 68 mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, NULL, NULL); 69 eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext); 70 eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); 71 eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight); 72 73 74 mGL.mVersion = glGetString(GL_VERSION); 75 mGL.mVendor = glGetString(GL_VENDOR); 76 mGL.mRenderer = glGetString(GL_RENDERER); 77 mGL.mExtensions = glGetString(GL_EXTENSIONS); 78 79 LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); 80 LOGV("GL Version %s", mGL.mVersion); 81 LOGV("GL Vendor %s", mGL.mVendor); 82 LOGV("GL Renderer %s", mGL.mRenderer); 83 LOGV("GL Extensions %s", mGL.mExtensions); 84 85 if (memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { 86 LOGE("Error, OpenGL ES Lite not supported"); 87 } 88 sscanf((const char *)mGL.mVersion + 13, "%i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); 89 90 91} 92 93bool Context::runScript(Script *s, uint32_t launchID) 94{ 95 ObjectBaseRef<ProgramFragment> frag(mFragment); 96 ObjectBaseRef<ProgramVertex> vtx(mVertex); 97 ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore); 98 99 bool ret = s->run(this, launchID); 100 101 mFragment.set(frag); 102 mVertex.set(vtx); 103 mFragmentStore.set(store); 104 return ret; 105} 106 107 108bool Context::runRootScript() 109{ 110#if RS_LOG_TIMES 111 timerSet(RS_TIMER_CLEAR_SWAP); 112#endif 113 rsAssert(mRootScript->mEnviroment.mIsRoot); 114 115 //glColor4f(1,1,1,1); 116 //glEnable(GL_LIGHT0); 117 glViewport(0, 0, mEGL.mWidth, mEGL.mHeight); 118#if 1 119 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 120 121 glClearColor(mRootScript->mEnviroment.mClearColor[0], 122 mRootScript->mEnviroment.mClearColor[1], 123 mRootScript->mEnviroment.mClearColor[2], 124 mRootScript->mEnviroment.mClearColor[3]); 125 if (mUseDepth) { 126 glDepthMask(GL_TRUE); 127 glClearDepthf(mRootScript->mEnviroment.mClearDepth); 128 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 129 } else { 130 glClear(GL_COLOR_BUFFER_BIT); 131 } 132#endif 133#if RS_LOG_TIMES 134 timerSet(RS_TIMER_SCRIPT); 135#endif 136 bool ret = runScript(mRootScript.get(), 0); 137 return ret; 138} 139 140uint64_t Context::getTime() const 141{ 142 struct timespec t; 143 clock_gettime(CLOCK_MONOTONIC, &t); 144 return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); 145} 146 147void Context::timerReset() 148{ 149 for (int ct=0; ct < _RS_TIMER_TOTAL; ct++) { 150 mTimers[ct] = 0; 151 } 152} 153 154void Context::timerInit() 155{ 156 mTimeLast = getTime(); 157 mTimerActive = RS_TIMER_INTERNAL; 158 timerReset(); 159} 160 161void Context::timerSet(Timers tm) 162{ 163 uint64_t last = mTimeLast; 164 mTimeLast = getTime(); 165 mTimers[mTimerActive] += mTimeLast - last; 166 mTimerActive = tm; 167} 168 169void Context::timerPrint() 170{ 171 double total = 0; 172 for (int ct = 0; ct < _RS_TIMER_TOTAL; ct++) { 173 total += mTimers[ct]; 174 } 175 176 LOGV("RS Time Data: Idle %2.1f (%lli), Internal %2.1f (%lli), Script %2.1f (%lli), Clear & Swap %2.1f (%lli)", 177 100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000, 178 100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000, 179 100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimers[RS_TIMER_SCRIPT] / 1000000, 180 100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimers[RS_TIMER_CLEAR_SWAP] / 1000000); 181} 182 183void Context::setupCheck() 184{ 185 if (mFragmentStore.get()) { 186 mFragmentStore->setupGL(this, &mStateFragmentStore); 187 } 188 if (mFragment.get()) { 189 mFragment->setupGL(this, &mStateFragment); 190 } 191 if (mVertex.get()) { 192 mVertex->setupGL(this, &mStateVertex); 193 } 194 195} 196 197 198void * Context::threadProc(void *vrsc) 199{ 200 Context *rsc = static_cast<Context *>(vrsc); 201 202 rsc->initEGL(); 203 204 ScriptTLSStruct *tlsStruct = new ScriptTLSStruct; 205 if (!tlsStruct) { 206 LOGE("Error allocating tls storage"); 207 return NULL; 208 } 209 tlsStruct->mContext = rsc; 210 tlsStruct->mScript = NULL; 211 int status = pthread_setspecific(rsc->gThreadTLSKey, tlsStruct); 212 if (status) { 213 LOGE("pthread_setspecific %i", status); 214 } 215 216 rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); 217 rsc->setVertex(NULL); 218 rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); 219 rsc->setFragment(NULL); 220 rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); 221 rsc->setFragmentStore(NULL); 222 223 rsc->mRunning = true; 224 bool mDraw = true; 225 while (!rsc->mExit) { 226 mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw); 227 mDraw &= (rsc->mRootScript.get() != NULL); 228 229 if (mDraw) { 230 mDraw = rsc->runRootScript(); 231#if RS_LOG_TIMES 232 rsc->timerSet(RS_TIMER_CLEAR_SWAP); 233#endif 234 eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); 235#if RS_LOG_TIMES 236 rsc->timerSet(RS_TIMER_INTERNAL); 237 rsc->timerPrint(); 238 rsc->timerReset(); 239#endif 240 } 241 if (rsc->mObjDestroy.mNeedToEmpty) { 242 rsc->objDestroyOOBRun(); 243 } 244 } 245 246 glClearColor(0,0,0,0); 247 glClear(GL_COLOR_BUFFER_BIT); 248 eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); 249 eglTerminate(rsc->mEGL.mDisplay); 250 rsc->objDestroyOOBRun(); 251 return NULL; 252} 253 254Context::Context(Device *dev, Surface *sur, bool useDepth) 255{ 256 dev->addContext(this); 257 mDev = dev; 258 mRunning = false; 259 mExit = false; 260 mUseDepth = useDepth; 261 262 int status; 263 pthread_attr_t threadAttr; 264 265 status = pthread_key_create(&gThreadTLSKey, NULL); 266 if (status) { 267 LOGE("Failed to init thread tls key."); 268 return; 269 } 270 271 status = pthread_attr_init(&threadAttr); 272 if (status) { 273 LOGE("Failed to init thread attribute."); 274 return; 275 } 276 277 sched_param sparam; 278 sparam.sched_priority = ANDROID_PRIORITY_DISPLAY; 279 pthread_attr_setschedparam(&threadAttr, &sparam); 280 281 mWndSurface = sur; 282 283 objDestroyOOBInit(); 284 timerInit(); 285 286 LOGV("RS Launching thread"); 287 status = pthread_create(&mThreadId, &threadAttr, threadProc, this); 288 if (status) { 289 LOGE("Failed to start rs context thread."); 290 } 291 292 while(!mRunning) { 293 sleep(1); 294 } 295 296 pthread_attr_destroy(&threadAttr); 297} 298 299Context::~Context() 300{ 301 mExit = true; 302 void *res; 303 304 int status = pthread_join(mThreadId, &res); 305 objDestroyOOBRun(); 306 307 if (mDev) { 308 mDev->removeContext(this); 309 pthread_key_delete(gThreadTLSKey); 310 } 311 312 objDestroyOOBDestroy(); 313} 314 315void Context::setRootScript(Script *s) 316{ 317 mRootScript.set(s); 318} 319 320void Context::setFragmentStore(ProgramFragmentStore *pfs) 321{ 322 if (pfs == NULL) { 323 mFragmentStore.set(mStateFragmentStore.mDefault); 324 } else { 325 mFragmentStore.set(pfs); 326 } 327} 328 329void Context::setFragment(ProgramFragment *pf) 330{ 331 if (pf == NULL) { 332 mFragment.set(mStateFragment.mDefault); 333 } else { 334 mFragment.set(pf); 335 } 336} 337 338void Context::allocationCheck(const Allocation *a) 339{ 340 mVertex->checkUpdatedAllocation(a); 341 mFragment->checkUpdatedAllocation(a); 342 mFragmentStore->checkUpdatedAllocation(a); 343} 344 345void Context::setVertex(ProgramVertex *pv) 346{ 347 if (pv == NULL) { 348 mVertex.set(mStateVertex.mDefault); 349 } else { 350 mVertex.set(pv); 351 } 352} 353 354void Context::assignName(ObjectBase *obj, const char *name, uint32_t len) 355{ 356 rsAssert(!obj->getName()); 357 obj->setName(name, len); 358 mNames.add(obj); 359} 360 361void Context::removeName(ObjectBase *obj) 362{ 363 for(size_t ct=0; ct < mNames.size(); ct++) { 364 if (obj == mNames[ct]) { 365 mNames.removeAt(ct); 366 return; 367 } 368 } 369} 370 371ObjectBase * Context::lookupName(const char *name) const 372{ 373 for(size_t ct=0; ct < mNames.size(); ct++) { 374 if (!strcmp(name, mNames[ct]->getName())) { 375 return mNames[ct]; 376 } 377 } 378 return NULL; 379} 380 381void Context::appendNameDefines(String8 *str) const 382{ 383 char buf[256]; 384 for (size_t ct=0; ct < mNames.size(); ct++) { 385 str->append("#define NAMED_"); 386 str->append(mNames[ct]->getName()); 387 str->append(" "); 388 sprintf(buf, "%i\n", (int)mNames[ct]); 389 str->append(buf); 390 } 391} 392 393void Context::appendVarDefines(String8 *str) const 394{ 395 char buf[256]; 396 for (size_t ct=0; ct < mInt32Defines.size(); ct++) { 397 str->append("#define "); 398 str->append(mInt32Defines.keyAt(ct)); 399 str->append(" "); 400 sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct)); 401 str->append(buf); 402 403 } 404 for (size_t ct=0; ct < mFloatDefines.size(); ct++) { 405 str->append("#define "); 406 str->append(mFloatDefines.keyAt(ct)); 407 str->append(" "); 408 sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct)); 409 str->append(buf); 410 } 411} 412 413bool Context::objDestroyOOBInit() 414{ 415 int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL); 416 if (status) { 417 LOGE("Context::ObjDestroyOOBInit mutex init failure"); 418 return false; 419 } 420 return true; 421} 422 423void Context::objDestroyOOBRun() 424{ 425 if (mObjDestroy.mNeedToEmpty) { 426 int status = pthread_mutex_lock(&mObjDestroy.mMutex); 427 if (status) { 428 LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status); 429 return; 430 } 431 432 for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) { 433 mObjDestroy.mDestroyList[ct]->decRef(); 434 } 435 mObjDestroy.mDestroyList.clear(); 436 mObjDestroy.mNeedToEmpty = false; 437 438 status = pthread_mutex_unlock(&mObjDestroy.mMutex); 439 if (status) { 440 LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status); 441 } 442 } 443} 444 445void Context::objDestroyOOBDestroy() 446{ 447 rsAssert(!mObjDestroy.mNeedToEmpty); 448 pthread_mutex_destroy(&mObjDestroy.mMutex); 449} 450 451void Context::objDestroyAdd(ObjectBase *obj) 452{ 453 int status = pthread_mutex_lock(&mObjDestroy.mMutex); 454 if (status) { 455 LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status); 456 return; 457 } 458 459 mObjDestroy.mNeedToEmpty = true; 460 mObjDestroy.mDestroyList.add(obj); 461 462 status = pthread_mutex_unlock(&mObjDestroy.mMutex); 463 if (status) { 464 LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status); 465 } 466} 467 468 469 470/////////////////////////////////////////////////////////////////////////////////////////// 471// 472 473namespace android { 474namespace renderscript { 475 476 477void rsi_ContextBindRootScript(Context *rsc, RsScript vs) 478{ 479 Script *s = static_cast<Script *>(vs); 480 rsc->setRootScript(s); 481} 482 483void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) 484{ 485 Sampler *s = static_cast<Sampler *>(vs); 486 487 if (slot > RS_MAX_SAMPLER_SLOT) { 488 LOGE("Invalid sampler slot"); 489 return; 490 } 491 492 s->bindToContext(&rsc->mStateSampler, slot); 493} 494 495void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs) 496{ 497 ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs); 498 rsc->setFragmentStore(pfs); 499} 500 501void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) 502{ 503 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 504 rsc->setFragment(pf); 505} 506 507void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) 508{ 509 ProgramVertex *pv = static_cast<ProgramVertex *>(vpv); 510 rsc->setVertex(pv); 511} 512 513void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len) 514{ 515 ObjectBase *ob = static_cast<ObjectBase *>(obj); 516 rsc->assignName(ob, name, len); 517} 518 519void rsi_ObjDestroy(Context *rsc, void *obj) 520{ 521 ObjectBase *ob = static_cast<ObjectBase *>(obj); 522 rsc->removeName(ob); 523 ob->decRef(); 524} 525 526void rsi_ContextSetDefineF(Context *rsc, const char* name, float value) 527{ 528 rsc->addInt32Define(name, value); 529} 530 531void rsi_ContextSetDefineI32(Context *rsc, const char* name, int32_t value) 532{ 533 rsc->addFloatDefine(name, value); 534} 535 536} 537} 538 539 540RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version, bool useDepth) 541{ 542 Device * dev = static_cast<Device *>(vdev); 543 Context *rsc = new Context(dev, (Surface *)sur, useDepth); 544 return rsc; 545} 546 547void rsContextDestroy(RsContext vrsc) 548{ 549 Context * rsc = static_cast<Context *>(vrsc); 550 delete rsc; 551} 552 553void rsObjDestroyOOB(RsContext vrsc, void *obj) 554{ 555 Context * rsc = static_cast<Context *>(vrsc); 556 rsc->objDestroyAdd(static_cast<ObjectBase *>(obj)); 557} 558 559