rsContext.cpp revision a0a1b6fbece2eb8d72d788422ab3e5f58d5a9216
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 21 22using namespace android; 23using namespace android::renderscript; 24 25Context * Context::gCon = NULL; 26 27void Context::initEGL() 28{ 29 mNumConfigs = -1; 30 31 EGLint s_configAttribs[] = { 32 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 33 EGL_RED_SIZE, 5, 34 EGL_GREEN_SIZE, 6, 35 EGL_BLUE_SIZE, 5, 36 EGL_DEPTH_SIZE, 16, 37 EGL_NONE 38 }; 39 40 mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 41 eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion); 42 eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs); 43 44 if (mWndSurface) { 45 mSurface = eglCreateWindowSurface(mDisplay, mConfig, 46 new EGLNativeWindowSurface(mWndSurface), 47 NULL); 48 } else { 49 mSurface = eglCreateWindowSurface(mDisplay, mConfig, 50 android_createDisplaySurface(), 51 NULL); 52 } 53 54 mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL); 55 eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); 56 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth); 57 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight); 58} 59 60bool Context::runScript(Script *s, uint32_t launchID) 61{ 62 ObjectBaseRef<ProgramFragment> frag(mFragment); 63 ObjectBaseRef<ProgramVertex> vtx(mVertex); 64 ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore); 65 66 bool ret = s->run(this, launchID); 67 68 mFragment.set(frag); 69 mVertex.set(vtx); 70 mFragmentStore.set(store); 71 return true; 72 73} 74 75 76bool Context::runRootScript() 77{ 78 rsAssert(mRootScript->mEnviroment.mIsRoot); 79 80 glColor4f(1,1,1,1); 81 glEnable(GL_LIGHT0); 82 glViewport(0, 0, mWidth, mHeight); 83 84 if(mRootScript->mEnviroment.mIsOrtho) { 85 glMatrixMode(GL_PROJECTION); 86 glLoadIdentity(); 87 glOrthof(0, mWidth, mHeight, 0, 0, 1); 88 glMatrixMode(GL_MODELVIEW); 89 } else { 90 float aspectH = ((float)mWidth) / mHeight; 91 glMatrixMode(GL_PROJECTION); 92 glLoadIdentity(); 93 glFrustumf(-1, 1, -aspectH, aspectH, 1, 100); 94 glRotatef(-90, 0,0,1); 95 glTranslatef(0, 0, -3); 96 glMatrixMode(GL_MODELVIEW); 97 } 98 99 glMatrixMode(GL_MODELVIEW); 100 glLoadIdentity(); 101 102 glDepthMask(GL_TRUE); 103 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 104 105 glClearColor(mRootScript->mEnviroment.mClearColor[0], 106 mRootScript->mEnviroment.mClearColor[1], 107 mRootScript->mEnviroment.mClearColor[2], 108 mRootScript->mEnviroment.mClearColor[3]); 109 glClearDepthf(mRootScript->mEnviroment.mClearDepth); 110 glClear(GL_COLOR_BUFFER_BIT); 111 glClear(GL_DEPTH_BUFFER_BIT); 112 113 return runScript(mRootScript.get(), 0); 114} 115 116void Context::setupCheck() 117{ 118 if (mFragmentStore.get()) { 119 mFragmentStore->setupGL(); 120 } 121 if (mFragment.get()) { 122 mFragment->setupGL(); 123 } 124 if (mVertex.get()) { 125 mVertex->setupGL(); 126 } 127 128} 129 130 131void * Context::threadProc(void *vrsc) 132{ 133 Context *rsc = static_cast<Context *>(vrsc); 134 135 gIO = new ThreadIO(); 136 rsc->mServerCommands.init(128); 137 rsc->mServerReturns.init(128); 138 139 rsc->initEGL(); 140 rsc->mRunning = true; 141 bool mDraw = true; 142 while (!rsc->mExit) { 143 mDraw |= gIO->playCoreCommands(rsc); 144 145 if (!mDraw || !rsc->mRootScript.get()) { 146 usleep(10000); 147 continue; 148 } 149 150 if (rsc->mRootScript.get()) { 151 mDraw = rsc->runRootScript(); 152 eglSwapBuffers(rsc->mDisplay, rsc->mSurface); 153 } 154 } 155 156 glClearColor(0,0,0,0); 157 glClear(GL_COLOR_BUFFER_BIT); 158 eglSwapBuffers(rsc->mDisplay, rsc->mSurface); 159 eglTerminate(rsc->mDisplay); 160 return NULL; 161} 162 163Context::Context(Device *dev, Surface *sur) 164{ 165 dev->addContext(this); 166 mDev = dev; 167 mRunning = false; 168 mExit = false; 169 170 mServerCommands.init(256); 171 mServerReturns.init(256); 172 173 // see comment in header 174 gCon = this; 175 176 int status; 177 pthread_attr_t threadAttr; 178 179 status = pthread_attr_init(&threadAttr); 180 if (status) { 181 LOGE("Failed to init thread attribute."); 182 return; 183 } 184 185 sched_param sparam; 186 sparam.sched_priority = ANDROID_PRIORITY_DISPLAY; 187 pthread_attr_setschedparam(&threadAttr, &sparam); 188 189 LOGE("RS Launching thread"); 190 status = pthread_create(&mThreadId, &threadAttr, threadProc, this); 191 if (status) { 192 LOGE("Failed to start rs context thread."); 193 } 194 195 mWndSurface = sur; 196 while(!mRunning) { 197 sleep(1); 198 } 199 200 pthread_attr_destroy(&threadAttr); 201} 202 203Context::~Context() 204{ 205 mExit = true; 206 void *res; 207 208 int status = pthread_join(mThreadId, &res); 209 210 if (mDev) { 211 mDev->removeContext(this); 212 } 213} 214 215void Context::swapBuffers() 216{ 217 eglSwapBuffers(mDisplay, mSurface); 218} 219 220void rsContextSwap(RsContext vrsc) 221{ 222 Context *rsc = static_cast<Context *>(vrsc); 223 rsc->swapBuffers(); 224} 225 226void Context::setRootScript(Script *s) 227{ 228 mRootScript.set(s); 229} 230 231void Context::setFragmentStore(ProgramFragmentStore *pfs) 232{ 233 mFragmentStore.set(pfs); 234 pfs->setupGL(); 235} 236 237void Context::setFragment(ProgramFragment *pf) 238{ 239 mFragment.set(pf); 240 pf->setupGL(); 241} 242 243void Context::setVertex(ProgramVertex *pv) 244{ 245 mVertex.set(pv); 246 pv->setupGL(); 247} 248 249void Context::assignName(ObjectBase *obj, const char *name) 250{ 251 rsAssert(!obj->getName()); 252 obj->setName(name); 253 mNames.add(obj); 254} 255 256void Context::removeName(ObjectBase *obj) 257{ 258 for(size_t ct=0; ct < mNames.size(); ct++) { 259 if (obj == mNames[ct]) { 260 mNames.removeAt(ct); 261 return; 262 } 263 } 264} 265 266ObjectBase * Context::lookupName(const char *name) const 267{ 268 for(size_t ct=0; ct < mNames.size(); ct++) { 269 if (!strcmp(name, mNames[ct]->getName())) { 270 return mNames[ct]; 271 } 272 } 273 return NULL; 274} 275 276/////////////////////////////////////////////////////////////////////////////////////////// 277// 278 279namespace android { 280namespace renderscript { 281 282 283void rsi_ContextBindRootScript(Context *rsc, RsScript vs) 284{ 285 Script *s = static_cast<Script *>(vs); 286 rsc->setRootScript(s); 287} 288 289void rsi_ContextBindSampler(Context *rsc, uint32_t slot, RsSampler vs) 290{ 291 Sampler *s = static_cast<Sampler *>(vs); 292 293 if (slot > RS_MAX_SAMPLER_SLOT) { 294 LOGE("Invalid sampler slot"); 295 return; 296 } 297 298 s->bindToContext(&rsc->mStateSampler, slot); 299} 300 301void rsi_ContextBindProgramFragmentStore(Context *rsc, RsProgramFragmentStore vpfs) 302{ 303 ProgramFragmentStore *pfs = static_cast<ProgramFragmentStore *>(vpfs); 304 rsc->setFragmentStore(pfs); 305} 306 307void rsi_ContextBindProgramFragment(Context *rsc, RsProgramFragment vpf) 308{ 309 ProgramFragment *pf = static_cast<ProgramFragment *>(vpf); 310 rsc->setFragment(pf); 311} 312 313void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv) 314{ 315 ProgramVertex *pv = static_cast<ProgramVertex *>(vpv); 316 rsc->setVertex(pv); 317} 318 319void rsi_AssignName(Context *rsc, void * obj, const char *name) 320{ 321 ObjectBase *ob = static_cast<ObjectBase *>(obj); 322 rsc->assignName(ob, name); 323} 324 325 326} 327} 328 329 330RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version) 331{ 332 Device * dev = static_cast<Device *>(vdev); 333 Context *rsc = new Context(dev, (Surface *)sur); 334 return rsc; 335} 336 337void rsContextDestroy(RsContext vrsc) 338{ 339 Context * rsc = static_cast<Context *>(vrsc); 340 delete rsc; 341} 342 343