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 <stdlib.h>
00036 #include <boost/concept_check.hpp>
00037
00038 #include <jccl/Config/ConfigElement.h>
00039
00040 #include <cluster/ClusterManager.h>
00041
00042 #include <vrj/Display/DisplayManager.h>
00043 #include <vrj/Kernel/Kernel.h>
00044 #include <vrj/Kernel/KernelExceptions.h>
00045
00046 #include <vrj/Display/Display.h>
00047 #include <vrj/Display/Viewport.h>
00048 #include <vrj/Display/SimViewport.h>
00049 #include <vrj/Display/SurfaceViewport.h>
00050
00051 #include <vrj/Draw/OGL/GlApp.h>
00052
00053 #include <vrj/Draw/OGL/GlPipe.h>
00054 #include <vrj/Draw/OGL/GlWindow.h>
00055 #include <vrj/Draw/OGL/GlSimInterfaceFactory.h>
00056
00057 #include <gmtl/Vec.h>
00058 #include <gmtl/Output.h>
00059
00060
00061
00062
00063 #include <vrj/Draw/OGL/GlDrawManager.h>
00064
00065
00066 namespace vrj
00067 {
00068
00069 vprSingletonImp(GlDrawManager);
00070
00071 GlDrawManager::GlDrawManager()
00072 : mApp(NULL)
00073 , drawTriggerSema(0)
00074 , drawDoneSema(0)
00075 , mRunning(false)
00076 , mMemberFunctor(NULL)
00077 , mControlThread(NULL)
00078 {
00079 }
00080
00081 GlDrawManager::~GlDrawManager()
00082 {
00083 if ( mRunning )
00084 {
00085 closeAPI();
00086 mControlThread->join();
00087 }
00088
00089 if ( NULL != mControlThread )
00090 {
00091 delete mControlThread;
00092 mControlThread = NULL;
00093 }
00094
00095 if ( NULL != mMemberFunctor )
00096 {
00097 delete mMemberFunctor;
00098 mMemberFunctor = NULL;
00099 }
00100 }
00101
00103 void GlDrawManager::setApp(App* _app)
00104 {
00105 mApp = dynamic_cast<GlApp*>(_app);
00106
00107
00108
00109 dirtyAllWindows();
00110
00111 if ( NULL == mApp )
00112 {
00113 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00114 << clrOutBOLD(clrRED, "ERROR:")
00115 << " [vrj::GlDrawManager::setApp()] Failed to downcast "
00116 << std::endl << vprDEBUG_FLUSH;
00117 vprDEBUG_NEXT(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00118 << "application object from vrj::App to vrj::GlApp!" << std::endl
00119 << vprDEBUG_FLUSH;
00120 vprDEBUG_NEXT(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00121 << "Type of object " << std::hex << _app << std::dec << " is "
00122 << typeid(_app).name() << std::endl << vprDEBUG_FLUSH;
00123
00124 throw vrj::DrawMgrException("Object not of type vrj::GlApp");
00125 }
00126 }
00127
00129 GlApp* GlDrawManager::getApp()
00130 {
00131 return mApp;
00132 }
00133
00135 void GlDrawManager::start()
00136 {
00137
00138
00139 mRunning = true;
00140
00141 mMemberFunctor =
00142 new vpr::ThreadMemberFunctor<GlDrawManager>(this, &GlDrawManager::main,
00143 NULL);
00144 mControlThread = new vpr::Thread(mMemberFunctor);
00145
00146 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00147 << "vrj::GlDrawManager started (thread: " << mControlThread << ")\n"
00148 << vprDEBUG_FLUSH;
00149 }
00150
00151
00152
00153
00154 void GlDrawManager::draw()
00155 {
00156 drawTriggerSema.release();
00157 }
00158
00159
00164 void GlDrawManager::sync()
00165 {
00166 drawDoneSema.acquire();
00167 }
00168
00169
00171 void GlDrawManager::main(void* nullParam)
00172 {
00173 boost::ignore_unused_variable_warning(nullParam);
00174 bool stop_requested(false);
00175
00176 while ( ! stop_requested )
00177 {
00178
00179
00180
00181
00182
00183 drawTriggerSema.acquire();
00184
00185
00186
00187
00188
00189
00190
00191 if (mRunning)
00192 {
00193
00194 drawAllPipes();
00195 }
00196 else
00197 {
00198 stop_requested = true;
00199 }
00200
00201
00202 drawDoneSema.release();
00203 }
00204 }
00205
00206 void GlDrawManager::drawAllPipes()
00207 {
00208 vprDEBUG_OutputGuard(vrjDBG_DRAW_MGR, vprDBG_HVERB_LVL,
00209 "vrj::GLDrawManager::drawAllPipes()\n",
00210 "vrj::GLDrawManager::drawAllPipes() done.\n");
00211 unsigned int pipe_num;
00212
00213
00214
00215 for (pipe_num = 0; pipe_num < pipes.size(); ++pipe_num)
00216 {
00217 pipes[pipe_num]->triggerRender();
00218 }
00219
00220
00221 for (pipe_num = 0; pipe_num < pipes.size(); ++pipe_num)
00222 {
00223 pipes[pipe_num]->completeRender();
00224 }
00225
00226
00227
00228 cluster::ClusterManager::instance()->createBarrier();
00229
00230
00231
00232
00233
00234 for (pipe_num = 0; pipe_num < pipes.size(); ++pipe_num)
00235 {
00236 pipes[pipe_num]->triggerSwap();
00237 }
00238
00239
00240 for (pipe_num = 0; pipe_num < pipes.size(); ++pipe_num)
00241 {
00242 pipes[pipe_num]->completeSwap();
00243 }
00244 }
00245
00250 void GlDrawManager::initAPI()
00251 {
00252 start();
00253 }
00254
00255
00265 void GlDrawManager::addDisplay(Display* disp)
00266 {
00267 vprASSERT(disp != NULL);
00268
00269 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00270 << "vrj::GlDrawManager::addDisplay: " << disp
00271 << std::endl << vprDEBUG_FLUSH;
00272
00273
00274
00275 std::vector<vrj::Viewport*>::size_type num_vp(disp->getNumViewports());
00276 std::vector<vrj::Viewport*>::size_type i;
00277
00278 for ( i = 0 ; i < num_vp ; ++i )
00279 {
00280 Viewport* vp = disp->getViewport(i);
00281
00282 if (vp->isSimulator())
00283 {
00284 jccl::ConfigElementPtr vp_element = vp->getConfigElement();
00285
00286 SimViewport* sim_vp(NULL);
00287 sim_vp = dynamic_cast<SimViewport*>(vp);
00288 vprASSERT(NULL != sim_vp);
00289
00290 sim_vp->setDrawSimInterface(NULL);
00291
00292
00293 vprASSERT(1 == vp_element->getNum("simulator_plugin") && "You must supply a simulator plugin.");
00294
00295
00296 jccl::ConfigElementPtr sim_element =
00297 vp_element->getProperty<jccl::ConfigElementPtr>("simulator_plugin");
00298
00299 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_CONFIG_LVL)
00300 << "GlDrawManager::addDisplay() creating simulator of type '"
00301 << sim_element->getID() << "'\n" << vprDEBUG_FLUSH;
00302
00303 DrawSimInterface* new_sim_i =
00304 GlSimInterfaceFactory::instance()->createObject(sim_element->getID());
00305
00306
00307
00308 vprASSERT(NULL != new_sim_i && "Failed to create draw simulator");
00309 sim_vp->setDrawSimInterface(new_sim_i);
00310 new_sim_i->initialize(sim_vp);
00311 new_sim_i->config(sim_element);
00312 }
00313 }
00314
00315
00316
00317
00318
00319 GlWindow* new_win = getGLWindow();
00320 new_win->configWindow(disp);
00321 mWins.push_back(new_win);
00322
00323
00324 unsigned int pipe_num = new_win->getDisplay()->getPipe();
00325
00326 if (pipes.size() < (pipe_num+1))
00327 {
00328 while (pipes.size() < (pipe_num+1))
00329 {
00330 GlPipe* new_pipe = new GlPipe(pipes.size(), this,
00331 &mCreateWindowMutex);
00332 pipes.push_back(new_pipe);
00333 new_pipe->start();
00334
00335 }
00336 }
00337
00338
00339 GlPipe* pipe;
00340 pipe = pipes[pipe_num];
00341 pipe->addWindow(new_win);
00342
00343 vprASSERT(isValidWindow(new_win));
00344 }
00345
00346
00352 void GlDrawManager::removeDisplay(Display* disp)
00353 {
00354 GlPipe* pipe; pipe = NULL;
00355 GlWindow* win; win = NULL;
00356
00357 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL)
00358 << "vrj::GlDrawManager::removeDisplay: " << disp
00359 << std::endl << vprDEBUG_FLUSH;
00360
00361 for (unsigned int i=0;i<mWins.size();i++)
00362 {
00363 if (mWins[i]->getDisplay() == disp)
00364 {
00365 win = mWins[i];
00366 pipe = pipes[win->getDisplay()->getPipe()];
00367 }
00368 }
00369
00370
00371 if (win != NULL)
00372 {
00373 vprASSERT(pipe != NULL);
00374 vprASSERT(isValidWindow(win));
00375 pipe->removeWindow(win);
00376 mWins.erase(std::remove(mWins.begin(),mWins.end(),win), mWins.end());
00377 vprASSERT(!isValidWindow(win));
00378 }
00379 else
00380 {
00381 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL) << clrOutNORM(clrRED,"ERROR:")
00382 << "vrj::GlDrawManager::removeDisplay: Attempted to remove a display that was not found.\n"
00383 << vprDEBUG_FLUSH;
00384 vprASSERT(false);
00385 }
00386
00387 }
00388
00389
00391 void GlDrawManager::closeAPI()
00392 {
00393 vprDEBUG(vrjDBG_DRAW_MGR, vprDBG_STATE_LVL) << "vrj::GlDrawManager::closeAPI\n" << vprDEBUG_FLUSH;
00394
00395 mRunning = false;
00396
00397
00398 drawTriggerSema.release();
00399 drawDoneSema.acquire();
00400 mControlThread->join();
00401
00402
00403 unsigned int pipe_num;
00404
00405 for (pipe_num = 0; pipe_num < pipes.size(); ++pipe_num)
00406 {
00407 pipes[pipe_num]->stop();
00408
00409 vrj::GlPipe* old_pipe = pipes[pipe_num];
00410
00411 pipes.erase(std::remove(pipes.begin(), pipes.end(), old_pipe));
00412 delete old_pipe;
00413 }
00414
00415
00416
00417 }
00418
00424 bool GlDrawManager::configAdd(jccl::ConfigElementPtr element)
00425 {
00426 boost::ignore_unused_variable_warning(element);
00427 return false;
00428 }
00429
00435 bool GlDrawManager::configRemove(jccl::ConfigElementPtr element)
00436 {
00437 boost::ignore_unused_variable_warning(element);
00438 return false;
00439 }
00440
00445 bool GlDrawManager::configCanHandle(jccl::ConfigElementPtr element)
00446 {
00447 boost::ignore_unused_variable_warning(element);
00448 return false;
00449 }
00450
00451 GlUserData* GlDrawManager::currentUserData()
00452 {
00453 return &(*mUserData);
00454 }
00455
00456 int GlDrawManager::getCurrentContext()
00457 {
00458 return (*mContextId);
00459 }
00460
00461 void GlDrawManager::setCurrentContext(int val)
00462 {
00463 (*mContextId) = val;
00464 }
00465
00470 void GlDrawManager::dirtyAllWindows()
00471 {
00472
00473 for (unsigned int winId=0;winId<mWins.size();winId++)
00474 {
00475 mWins[winId]->setDirtyContext(true);
00476 }
00477 }
00478
00479
00480 bool GlDrawManager::isValidWindow(GlWindow* win)
00481 {
00482 bool ret_val = false;
00483 for (unsigned int i=0;i<mWins.size();i++)
00484 {
00485 if (mWins[i] == win)
00486 {
00487 ret_val = true;
00488 }
00489 }
00490
00491 return ret_val;
00492 }
00493
00494
00496 void GlDrawManager::outStream(std::ostream& out)
00497 {
00498 out << clrSetNORM(clrGREEN)
00499 << "========== GlDrawManager: " << (void*)this << " ========="
00500 << clrRESET << std::endl
00501 << clrOutNORM(clrCYAN,"\tapp: ") << (void*)mApp << std::endl
00502 << clrOutNORM(clrCYAN,"\tWindow count: ") << mWins.size()
00503 << std::endl << std::flush;
00504
00505 for (unsigned int i = 0; i < mWins.size(); i++)
00506 {
00507 vprASSERT(mWins[i] != NULL);
00508 out << clrOutNORM(clrCYAN,"\tGlWindow:\n") << *(mWins[i]) << std::endl;
00509 }
00510 out << "=======================================" << std::endl;
00511 }
00512
00513 }
00514
00515
00516 #if defined(VPR_OS_Windows)
00517 # include <vrj/Draw/OGL/GlWindowWin32.h>
00518 #elif defined(VPR_OS_Darwin) && ! defined(VRJ_USE_X11)
00519 # include <vrj/Draw/OGL/GlWindowOSX.h>
00520 #else
00521 # include <vrj/Draw/OGL/GlWindowXWin.h>
00522 #endif
00523
00524 namespace vrj
00525 {
00526
00527 vrj::GlWindow* GlDrawManager::getGLWindow()
00528 {
00529 #if defined(VPR_OS_Windows)
00530 return new vrj::GlWindowWin32;
00531 #elif defined(VPR_OS_Darwin) && ! defined(VRJ_USE_X11)
00532 return new vrj::GlWindowOSX;
00533 #else
00534 return new vrj::GlWindowXWin;
00535 #endif
00536 }
00537
00538 }