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/Draw/OGL/Config.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 GlPipe::~GlPipe()
00059 {
00060 if ( NULL != mActiveThread )
00061 {
00062 delete mActiveThread;
00063 mActiveThread = NULL;
00064 }
00065
00066 if ( NULL != mControlFunctor )
00067 {
00068 delete mControlFunctor;
00069 mControlFunctor = NULL;
00070 }
00071 }
00072
00077 int GlPipe::start()
00078 {
00079 vprASSERT(mThreadRunning == false);
00080
00081
00082 mControlFunctor =
00083 new vpr::ThreadMemberFunctor<GlPipe>(this, &GlPipe::controlLoop, NULL);
00084
00085 mActiveThread = new vpr::Thread(mControlFunctor);
00086
00087 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00088 << "[vrj::GlPipe::start()] Started control loop. " << mActiveThread
00089 << std::endl << vprDEBUG_FLUSH;
00090 return 1;
00091 }
00092
00097 void GlPipe::triggerRender()
00098 {
00099
00100 while (!mThreadRunning)
00101 {
00102 vprDEBUG(vrjDBG_DRAW_MGR,vprDBG_HVERB_LVL) << "Waiting in for thread to start triggerRender.\n" << vprDEBUG_FLUSH;
00103 vpr::Thread::yield();
00104 }
00105
00106 mRenderTriggerSema.release();
00107 }
00108
00113 void GlPipe::completeRender()
00114 {
00115 vprASSERT(mThreadRunning == true);
00116
00117 mRenderCompleteSema.acquire();
00118 }
00119
00121 void GlPipe::triggerSwap()
00122 {
00123 vprASSERT(mThreadRunning == true);
00124 mSwapTriggerSema.release();
00125 }
00126
00128 void GlPipe::completeSwap()
00129 {
00130 vprASSERT(mThreadRunning == true);
00131 mSwapCompleteSema.acquire();
00132 }
00133
00134
00139 void GlPipe::addWindow(GlWindow* win)
00140 {
00141 vpr::Guard<vpr::Mutex> guardNew(mNewWinLock);
00142 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00143 << "[vrj::GlPipe::addWindow()] Pipe: " << mPipeNum
00144 << " adding window (to new wins):\n" << win
00145 << std::endl << vprDEBUG_FLUSH;
00146 mNewWins.push_back(win);
00147 }
00148
00153 void GlPipe::removeWindow(GlWindow* win)
00154 {
00155 vpr::Guard<vpr::Mutex> guardClosing(mClosingWinLock);
00156 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00157 << "[vrj::GlPipe::removeWindow()] Pipe: " << mPipeNum
00158 << " window added to closingWins.\n" << win
00159 << std::endl << vprDEBUG_FLUSH;
00160 mClosingWins.push_back(win);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 void GlPipe::controlLoop(void* nullParam)
00175 {
00176 boost::ignore_unused_variable_warning(nullParam);
00177 mThreadRunning = true;
00178
00179 while (!mControlExit)
00180 {
00181
00182
00183
00184 {
00185 for (unsigned int winId=0;winId<mOpenWins.size();winId++)
00186 {
00187 mOpenWins[winId]->checkEvents();
00188 }
00189 }
00190
00191
00192 {
00193 mRenderTriggerSema.acquire();
00194
00195 GlApp* the_app = mGlDrawManager->getApp();
00196
00197
00198 the_app->pipePreDraw();
00199
00200
00201 for (unsigned int winId = 0 ; winId < mOpenWins.size() ; winId++)
00202 {
00203 renderWindow(mOpenWins[winId]);
00204 }
00205 mRenderCompleteSema.release();
00206 }
00207
00208
00209 {
00210 mSwapTriggerSema.acquire();
00211
00212
00213 for (unsigned int winId = 0 ; winId < mOpenWins.size() ; winId++)
00214 {
00215 swapWindowBuffers(mOpenWins[winId]);
00216 }
00217
00218 mSwapCompleteSema.release();
00219 }
00220 checkForWindowsToClose();
00221 checkForNewWindows();
00222 }
00223
00224 mThreadRunning = false;
00225 }
00226
00227 void GlPipe::stop()
00228 {
00229
00230 std::vector<GlWindow*> windows = getOpenWindows();
00231 for ( std::vector<GlWindow*>::iterator itr = windows.begin();
00232 itr != windows.end();
00233 ++itr )
00234 {
00235 removeWindow(*itr);
00236 }
00237
00238 mControlExit = 1;
00239
00240
00241
00242
00243 triggerRender();
00244
00245 triggerSwap();
00246
00247
00248 mActiveThread->join();
00249 }
00250
00257 void GlPipe::checkForWindowsToClose()
00258 {
00259 if (mClosingWins.size() > 0)
00260 {
00261 vpr::Guard<vpr::Mutex> guardClosing(mClosingWinLock);
00262 vpr::Guard<vpr::Mutex> guardNew(mNewWinLock);
00263 vpr::Guard<vpr::Mutex> guardOpen(mOpenWinLock);
00264
00265 for (unsigned int i=0;i<mClosingWins.size();i++)
00266 {
00267 GlWindow* win = mClosingWins[i];
00268
00269 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00270 << "[vrj::GlPipe::checkForNewWindows()] Just closed window: "
00271 << mClosingWins[i]->getDisplay()->getName() << std::endl
00272 << *(mClosingWins[i]) << std::endl << vprDEBUG_FLUSH;
00273
00274
00275 GlApp* the_app = mGlDrawManager->getApp();
00276
00277 mGlDrawManager->setCurrentContext(win->getId());
00278 mGlDrawManager->currentUserData()->setUser(NULL);
00279 mGlDrawManager->currentUserData()->setProjection(NULL);
00280 mGlDrawManager->currentUserData()->setViewport(NULL);
00281 mGlDrawManager->currentUserData()->setGlWindow(win);
00282
00283 win->makeCurrent();
00284 the_app->contextClose();
00285
00286
00287 win->close();
00288
00289
00290 mNewWins.erase(std::remove(mNewWins.begin(), mNewWins.end(), win), mNewWins.end());
00291 mOpenWins.erase(std::remove(mOpenWins.begin(), mOpenWins.end(), win), mOpenWins.end());
00292
00293
00294 delete win;
00295 mClosingWins[i] = NULL;
00296 }
00297
00298 mClosingWins.erase(mClosingWins.begin(), mClosingWins.end());
00299 vprASSERT(mClosingWins.size() == 0);;
00300 }
00301 }
00302
00307 void GlPipe::checkForNewWindows()
00308 {
00309 if (mNewWins.size() > 0)
00310 {
00311
00312
00313 vpr::Guard<vpr::Mutex> guard_draw_mgr(*mDrawMgrWinLock);
00314
00315
00316 vpr::Guard<vpr::Mutex> guard_new(mNewWinLock);
00317
00318
00319 vpr::Guard<vpr::Mutex> guard_open(mOpenWinLock);
00320
00321 for (unsigned int winNum=0; winNum<mNewWins.size(); winNum++)
00322 {
00323 if (mNewWins[winNum]->open())
00324 {
00325 mNewWins[winNum]->makeCurrent();
00326 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00327 << "[vrj::GlPipe::checkForNewWindows()] Just opened window: "
00328 << mNewWins[winNum]->getDisplay()->getName() << std::endl
00329 << *(mNewWins[winNum]) << std::endl << vprDEBUG_FLUSH;
00330 mNewWins[winNum]->finishSetup();
00331 mOpenWins.push_back(mNewWins[winNum]);
00332 }
00333 else
00334 {
00335 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00336 << clrOutBOLD(clrRED,"ERROR:")
00337 << " vrj::GlPipe::checkForNewWindows(): Failed to open window: "
00338 << mNewWins[winNum]->getDisplay()->getName().c_str()
00339 << std::endl << vprDEBUG_FLUSH;
00340
00341 }
00342 }
00343
00344 mNewWins.erase(mNewWins.begin(), mNewWins.end());
00345 vprASSERT(mNewWins.size() == 0);
00346 }
00347 }
00348
00353 void GlPipe::renderWindow(GlWindow* win)
00354 {
00355 float vp_ox, vp_oy, vp_sx, vp_sy;
00356 Viewport::View view;
00357
00358 GlApp* the_app = mGlDrawManager->getApp();
00359 Display* the_display = win->getDisplay();
00360
00361
00362
00363 float scale_factor = the_app->getDrawScaleFactor();
00364 the_display->updateProjections(scale_factor);
00365
00366 mGlDrawManager->setCurrentContext(win->getId());
00367 mGlDrawManager->currentUserData()->setGlWindow(win);
00368
00369 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_HVERB_LVL)
00370 << "[vrj::GlPipe::renderWindow()] Set context to: "
00371 << GlDrawManager::instance()->getCurrentContext()
00372 << std::endl << vprDEBUG_FLUSH;
00373
00374
00375 win->makeCurrent();
00376
00377
00378
00379 if (win->hasDirtyViewport())
00380 {
00381 win->updateViewport();
00382 }
00383
00384
00385
00386 if (win->hasDirtyContext())
00387 {
00388
00389 mGlDrawManager->currentUserData()->setUser(NULL);
00390 mGlDrawManager->currentUserData()->setProjection(NULL);
00391 mGlDrawManager->currentUserData()->setViewport(NULL);
00392 mGlDrawManager->currentUserData()->setGlWindow(win);
00393
00394 the_app->contextInit();
00395 win->setDirtyContext(false);
00396 }
00397
00398
00399 if (win->isStereo())
00400 {
00401 win->setViewBuffer(Viewport::RIGHT_EYE);
00402 the_app->bufferPreDraw();
00403 win->setViewBuffer(Viewport::LEFT_EYE);
00404 the_app->bufferPreDraw();
00405 }
00406 else
00407 {
00408 the_app->bufferPreDraw();
00409 }
00410
00411 the_app->contextPreDraw();
00412
00413
00414 Viewport* viewport = NULL;
00415 size_t num_vps = the_display->getNumViewports();
00416 for ( size_t vp_num = 0; vp_num < num_vps; ++vp_num )
00417 {
00418 viewport = the_display->getViewport(vp_num);
00419
00420
00421 if (viewport->isActive())
00422 {
00423 view = viewport->getView();
00424
00425
00426 viewport->getOriginAndSize(vp_ox, vp_oy, vp_sx, vp_sy);
00427 win->setViewport(vp_ox, vp_oy, vp_sx, vp_sy);
00428
00429
00430 mGlDrawManager->currentUserData()->setUser(viewport->getUser());
00431 mGlDrawManager->currentUserData()->setViewport(viewport);
00432
00433
00434
00435 {
00436 SimViewport* sim_vp(NULL);
00437 GlSimInterface* draw_sim_i(NULL);
00438
00439 if (viewport->isSimulator())
00440 {
00441 sim_vp = dynamic_cast<SimViewport*>(viewport);
00442 vprASSERT(NULL != sim_vp);
00443 if (NULL != sim_vp)
00444 {
00445 draw_sim_i = dynamic_cast<GlSimInterface*>(sim_vp->getDrawSimInterface());
00446 }
00447 }
00448
00449 if ((Viewport::STEREO == view) || (Viewport::LEFT_EYE == view))
00450 {
00451 win->setViewBuffer(Viewport::LEFT_EYE);
00452 win->setProjection(viewport->getLeftProj());
00453 mGlDrawManager->currentUserData()->setProjection(viewport->getLeftProj());
00454
00455 the_app->draw();
00456
00457 if (NULL != draw_sim_i)
00458 {
00459 draw_sim_i->draw(scale_factor);
00460 }
00461 }
00462 if ((Viewport::STEREO == view) || (Viewport::RIGHT_EYE == view))
00463 {
00464 win->setViewBuffer(Viewport::RIGHT_EYE);
00465 win->setProjection(viewport->getRightProj());
00466 mGlDrawManager->currentUserData()->setProjection(viewport->getRightProj());
00467
00468 the_app->draw();
00469
00470 if (NULL != draw_sim_i)
00471 {
00472 draw_sim_i->draw(scale_factor);
00473 }
00474 }
00475 }
00476 }
00477 }
00478
00479
00480 the_app->contextPostDraw();
00481 }
00482
00487 void GlPipe::swapWindowBuffers(GlWindow* win)
00488 {
00489 win->makeCurrent();
00490 win->swapBuffers();
00491 }
00492
00493 }