00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <vrj/vrjConfig.h>
00034
00035 #include <vpr/vpr.h>
00036
00037 #ifdef VPR_OS_Darwin
00038 # include <OpenGL/gl.h>
00039 #else
00040 # include <GL/gl.h>
00041 #endif
00042
00043 #include <vrj/Kernel/Kernel.h>
00044 #include <vrj/Draw/OGL/GlPipe.h>
00045 #include <vrj/Draw/OGL/GlApp.h>
00046 #include <vpr/Thread/Thread.h>
00047 #include <vpr/Sync/Guard.h>
00048 #include <vrj/Util/Debug.h>
00049
00050 #include <vrj/Display/SurfaceViewport.h>
00051 #include <vrj/Display/SimViewport.h>
00052 #include <vrj/Draw/OGL/GlSimInterface.h>
00053 #include <boost/concept_check.hpp>
00054
00055 namespace vrj
00056 {
00057
00058
00063 int GlPipe::start()
00064 {
00065 vprASSERT(mThreadRunning == false);
00066
00067
00068 vpr::ThreadMemberFunctor<GlPipe>* memberFunctor =
00069 new vpr::ThreadMemberFunctor<GlPipe>(this, &GlPipe::controlLoop, NULL);
00070
00071 mActiveThread = new vpr::Thread(memberFunctor);
00072
00073 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00074 << "vjGlPipe::start: Started control loop. " << mActiveThread
00075 << std::endl << vprDEBUG_FLUSH;
00076 return 1;
00077 }
00078
00083 void GlPipe::triggerRender()
00084 {
00085
00086 while(!mThreadRunning)
00087 {
00088 vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_HVERB_LVL) << "Waiting in for thread to start triggerRender.\n" << vprDEBUG_FLUSH;
00089 vpr::Thread::yield();
00090 }
00091
00092 renderTriggerSema.release();
00093 }
00094
00099 void GlPipe::completeRender()
00100 {
00101 vprASSERT(mThreadRunning == true);
00102
00103 renderCompleteSema.acquire();
00104 }
00105
00107 void GlPipe::triggerSwap()
00108 {
00109 vprASSERT(mThreadRunning == true);
00110 swapTriggerSema.release();
00111 }
00112
00114 void GlPipe::completeSwap()
00115 {
00116 vprASSERT(mThreadRunning == true);
00117 swapCompleteSema.acquire();
00118 }
00119
00120
00125 void GlPipe::addWindow(GlWindow* win)
00126 {
00127 vpr::Guard<vpr::Mutex> guardNew(mNewWinLock);
00128 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00129 << "vjGlPipe::addWindow: Pipe: " << mPipeNum
00130 << " adding window (to new wins):\n" << win
00131 << std::endl << vprDEBUG_FLUSH;
00132 mNewWins.push_back(win);
00133 }
00134
00139 void GlPipe::removeWindow(GlWindow* win)
00140 {
00141 vpr::Guard<vpr::Mutex> guardClosing(mClosingWinLock);
00142 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00143 << "vjGlPipe:: removeWindow: Pipe: " << mPipeNum
00144 << " window added to closingWins.\n" << win
00145 << std::endl << vprDEBUG_FLUSH;
00146 mClosingWins.push_back(win);
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 void GlPipe::controlLoop(void* nullParam)
00161 {
00162 boost::ignore_unused_variable_warning(nullParam);
00163 mThreadRunning = true;
00164
00165 while (!controlExit)
00166 {
00167 checkForWindowsToClose();
00168 checkForNewWindows();
00169
00170
00171
00172
00173 {
00174 for(unsigned int winId=0;winId<mOpenWins.size();winId++)
00175 mOpenWins[winId]->checkEvents();
00176 }
00177
00178
00179 {
00180 renderTriggerSema.acquire();
00181
00182 GlApp* the_app = glManager->getApp();
00183
00184
00185 the_app->pipePreDraw();
00186
00187
00188 for (unsigned int winId=0;winId < mOpenWins.size();winId++) {
00189 renderWindow(mOpenWins[winId]);
00190 }
00191 renderCompleteSema.release();
00192 }
00193
00194
00195 {
00196 swapTriggerSema.acquire();
00197
00198
00199 for(unsigned int winId=0;winId < mOpenWins.size();winId++)
00200 {
00201 swapWindowBuffers(mOpenWins[winId]);
00202 }
00203
00204 swapCompleteSema.release();
00205 }
00206 }
00207
00208 mThreadRunning = false;
00209 }
00210
00217 void GlPipe::checkForWindowsToClose()
00218 {
00219 if(mClosingWins.size() > 0)
00220 {
00221 vpr::Guard<vpr::Mutex> guardClosing(mClosingWinLock);
00222 vpr::Guard<vpr::Mutex> guardNew(mNewWinLock);
00223 vpr::Guard<vpr::Mutex> guardOpen(mOpenWinLock);
00224
00225 for(unsigned int i=0;i<mClosingWins.size();i++)
00226 {
00227 GlWindow* win = mClosingWins[i];
00228
00229
00230 GlApp* the_app = glManager->getApp();
00231
00232 glManager->setCurrentContext(win->getId());
00233 glManager->currentUserData()->setUser(NULL);
00234 glManager->currentUserData()->setProjection(NULL);
00235 glManager->currentUserData()->setViewport(NULL);
00236 glManager->currentUserData()->setGlWindow(win);
00237
00238 win->makeCurrent();
00239 the_app->contextClose();
00240
00241
00242 win->close();
00243
00244
00245 mNewWins.erase(std::remove(mNewWins.begin(), mNewWins.end(), win), mNewWins.end());
00246 mOpenWins.erase(std::remove(mOpenWins.begin(), mOpenWins.end(), win), mOpenWins.end());
00247
00248
00249 delete win;
00250 mClosingWins[i] = NULL;
00251 }
00252
00253 mClosingWins.erase(mClosingWins.begin(), mClosingWins.end());
00254 vprASSERT(mClosingWins.size() == 0);;
00255 }
00256 }
00257
00262 void GlPipe::checkForNewWindows()
00263 {
00264 if (mNewWins.size() > 0)
00265 {
00266 vpr::Guard<vpr::Mutex> guardNew(mNewWinLock);
00267 vpr::Guard<vpr::Mutex> guardOpen(mOpenWinLock);
00268
00269 for (unsigned int winNum=0; winNum<mNewWins.size(); winNum++)
00270 {
00271 if (mNewWins[winNum]->open())
00272 {
00273 mNewWins[winNum]->makeCurrent();
00274 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00275 << "vrj::GlPipe::checkForNewWindows(): Just opened window: "
00276 << mNewWins[winNum]->getDisplay()->getName() << std::endl
00277 << *(mNewWins[winNum]) << std::endl << vprDEBUG_FLUSH;
00278 mNewWins[winNum]->finishSetup();
00279 mOpenWins.push_back(mNewWins[winNum]);
00280 } else {
00281 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00282 << clrOutBOLD(clrRED,"ERROR:") << "vjGlPipe::checkForNewWindows: Failed to open window: "
00283 << mNewWins[winNum]->getDisplay()->getName().c_str()
00284 << std::endl << vprDEBUG_FLUSH;
00285
00286 }
00287 }
00288
00289 mNewWins.erase(mNewWins.begin(), mNewWins.end());
00290 vprASSERT(mNewWins.size() == 0);
00291 }
00292 }
00293
00298 void GlPipe::renderWindow(GlWindow* win)
00299 {
00300 float vp_ox, vp_oy, vp_sx, vp_sy;
00301 Viewport::View view;
00302
00303 GlApp* the_app = glManager->getApp();
00304 Display* the_display = win->getDisplay();
00305
00306
00307
00308 float scale_factor = the_app->getDrawScaleFactor();
00309 the_display->updateProjections(scale_factor);
00310
00311 glManager->setCurrentContext(win->getId());
00312
00313 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_HVERB_LVL)
00314 << "vjGlPipe::renderWindow: Set context to: "
00315 << GlDrawManager::instance()->getCurrentContext()
00316 << std::endl << vprDEBUG_FLUSH;
00317
00318
00319 win->makeCurrent();
00320
00321
00322 if(win->hasDirtyViewport())
00323 {
00324 win->updateViewport();
00325 }
00326
00327
00328
00329 if(win->hasDirtyContext())
00330 {
00331
00332 glManager->currentUserData()->setUser(NULL);
00333 glManager->currentUserData()->setProjection(NULL);
00334 glManager->currentUserData()->setViewport(NULL);
00335 glManager->currentUserData()->setGlWindow(win);
00336
00337 the_app->contextInit();
00338 win->setDirtyContext(false);
00339 }
00340
00341
00342 if(win->isStereo())
00343 {
00344 win->setViewBuffer(Viewport::RIGHT_EYE);
00345 the_app->bufferPreDraw();
00346 win->setViewBuffer(Viewport::LEFT_EYE);
00347 the_app->bufferPreDraw();
00348 }
00349 else
00350 {
00351 the_app->bufferPreDraw();
00352 }
00353
00354 the_app->contextPreDraw();
00355
00356
00357 Viewport* viewport = NULL;
00358 unsigned num_vps = the_display->getNumViewports();
00359 for(unsigned vp_num=0; vp_num < num_vps; vp_num++)
00360 {
00361 viewport = the_display->getViewport(vp_num);
00362
00363
00364 if(viewport->isActive())
00365 {
00366 view = viewport->getView();
00367
00368
00369 viewport->getOriginAndSize(vp_ox, vp_oy, vp_sx, vp_sy);
00370 win->setViewport(vp_ox, vp_oy, vp_sx, vp_sy);
00371
00372
00373 glManager->currentUserData()->setUser(viewport->getUser());
00374 glManager->currentUserData()->setViewport(viewport);
00375 glManager->currentUserData()->setGlWindow(win);
00376
00377
00378
00379 {
00380 SimViewport* sim_vp(NULL);
00381 GlSimInterface* draw_sim_i(NULL);
00382
00383 if(viewport->isSimulator())
00384 {
00385 sim_vp = dynamic_cast<SimViewport*>(viewport);
00386 vprASSERT(NULL != sim_vp);
00387 draw_sim_i = dynamic_cast<GlSimInterface*>(sim_vp->getDrawSimInterface());
00388 }
00389
00390 if((Viewport::STEREO == view) || (Viewport::LEFT_EYE == view))
00391 {
00392 win->setViewBuffer(Viewport::LEFT_EYE);
00393 win->setProjection(viewport->getLeftProj());
00394 glManager->currentUserData()->setProjection(viewport->getLeftProj());
00395
00396 the_app->draw();
00397
00398 if(NULL != draw_sim_i)
00399 {
00400 draw_sim_i->draw(scale_factor);
00401 }
00402 }
00403 if ((Viewport::STEREO == view) || (Viewport::RIGHT_EYE == view))
00404 {
00405 win->setViewBuffer(Viewport::RIGHT_EYE);
00406 win->setProjection(viewport->getRightProj());
00407 glManager->currentUserData()->setProjection(viewport->getRightProj());
00408
00409 the_app->draw();
00410
00411 if(NULL != draw_sim_i)
00412 {
00413 draw_sim_i->draw(scale_factor);
00414 }
00415 }
00416 }
00417 }
00418 }
00419
00420
00421 the_app->contextPostDraw();
00422 }
00423
00428 void GlPipe::swapWindowBuffers(GlWindow* win)
00429 {
00430 win->makeCurrent();
00431 win->swapBuffers();
00432 }
00433
00434 }