00001
00002
00003
00004
00005 #define NOMINMAX
00006 #include "channel.h"
00007
00008 #include "channelStatistics.h"
00009 #include "compositor.h"
00010 #include "commands.h"
00011 #include "configEvent.h"
00012 #include "frame.h"
00013 #include "global.h"
00014 #include "log.h"
00015 #include "nodeFactory.h"
00016 #include "packets.h"
00017 #include "range.h"
00018 #include "renderContext.h"
00019 #include "view.h"
00020
00021 #include <eq/net/command.h>
00022
00023 using namespace eq::base;
00024 using namespace std;
00025
00026 namespace eq
00027 {
00028 typedef net::CommandFunc<Channel> ChannelFunc;
00029
00030 #define MAKE_ATTR_STRING( attr ) ( string("EQ_CHANNEL_") + #attr )
00031 std::string Channel::_iAttributeStrings[IATTR_ALL] = {
00032 MAKE_ATTR_STRING( IATTR_HINT_STATISTICS ),
00033 };
00034
00035 Channel::Channel( Window* parent )
00036 : _window( parent )
00037 , _context( 0 )
00038 , _fixedPVP( false )
00039 , _frustum( vmml::Frustumf::DEFAULT )
00040 , _ortho( vmml::Frustumf::DEFAULT )
00041 , _view( 0 )
00042 {
00043 net::CommandQueue* queue = parent->getPipeThreadQueue();
00044
00045 registerCommand( CMD_CHANNEL_CONFIG_INIT,
00046 ChannelFunc( this, &Channel::_cmdConfigInit ), queue );
00047 registerCommand( CMD_CHANNEL_CONFIG_EXIT,
00048 ChannelFunc( this, &Channel::_cmdConfigExit ), queue );
00049 registerCommand( CMD_CHANNEL_FRAME_START,
00050 ChannelFunc( this, &Channel::_cmdFrameStart ), queue );
00051 registerCommand( CMD_CHANNEL_FRAME_FINISH,
00052 ChannelFunc( this, &Channel::_cmdFrameFinish ), queue );
00053 registerCommand( CMD_CHANNEL_FRAME_CLEAR,
00054 ChannelFunc( this, &Channel::_cmdFrameClear ), queue );
00055 registerCommand( CMD_CHANNEL_FRAME_DRAW,
00056 ChannelFunc( this, &Channel::_cmdFrameDraw ), queue );
00057 registerCommand( CMD_CHANNEL_FRAME_DRAW_FINISH,
00058 ChannelFunc( this, &Channel::_cmdFrameDrawFinish ), queue );
00059 registerCommand( CMD_CHANNEL_FRAME_ASSEMBLE,
00060 ChannelFunc( this, &Channel::_cmdFrameAssemble ), queue );
00061 registerCommand( CMD_CHANNEL_FRAME_READBACK,
00062 ChannelFunc( this, &Channel::_cmdFrameReadback ), queue );
00063 registerCommand( CMD_CHANNEL_FRAME_TRANSMIT,
00064 ChannelFunc( this, &Channel::_cmdFrameTransmit ), queue );
00065
00066 parent->_addChannel( this );
00067 EQINFO << " New eq::Channel @" << (void*)this << endl;
00068 }
00069
00070 Channel::~Channel()
00071 {
00072 _window->_removeChannel( this );
00073 }
00074
00075
00076
00077
00078 void Channel::_setPixelViewport( const PixelViewport& pvp )
00079 {
00080 EQASSERT( pvp.hasArea( ));
00081 if( !pvp.hasArea( ))
00082 return;
00083
00084 _fixedPVP = true;
00085
00086 if( _pvp == pvp && _vp.hasArea( ))
00087 return;
00088
00089 _pvp = pvp;
00090 _vp.invalidate();
00091
00092 if( !_window )
00093 return;
00094
00095 const PixelViewport& windowPVP = _window->getPixelViewport();
00096 if( windowPVP.isValid( ))
00097 _vp = pvp.getSubVP( windowPVP );
00098
00099 EQVERB << "Channel pvp set: " << _pvp << ":" << _vp << endl;
00100 }
00101
00102 void Channel::_setViewport( const Viewport& vp )
00103 {
00104 if( !vp.hasArea( ))
00105 return;
00106
00107 _fixedPVP = false;
00108
00109 if( _vp == vp && _pvp.hasArea( ))
00110 return;
00111
00112 _vp = vp;
00113 _pvp.invalidate();
00114
00115 if( !_window )
00116 return;
00117
00118 PixelViewport windowPVP = _window->getPixelViewport();
00119 if( windowPVP.isValid( ))
00120 {
00121 windowPVP.x = 0;
00122 windowPVP.y = 0;
00123 _pvp = windowPVP.getSubPVP( vp );
00124
00125
00126 Event event;
00127 event.type = Event::CHANNEL_RESIZE;
00128 event.originator = getID();
00129 event.resize.x = _pvp.x;
00130 event.resize.y = _pvp.y;
00131 event.resize.w = _pvp.w;
00132 event.resize.h = _pvp.h;
00133
00134 processEvent( event );
00135 }
00136
00137 EQVERB << "Channel vp set: " << _pvp << ":" << _vp << endl;
00138 }
00139
00140 void Channel::_notifyViewportChanged()
00141 {
00142 if( !_window )
00143 return;
00144
00145 eq::PixelViewport windowPVP = _window->getPixelViewport();
00146 if( !windowPVP.isValid( ))
00147 return;
00148
00149 windowPVP.x = 0;
00150 windowPVP.y = 0;
00151
00152 if( _fixedPVP )
00153 _vp = _pvp.getSubVP( windowPVP );
00154 else
00155 {
00156 eq::PixelViewport pvp = windowPVP.getSubPVP( _vp );
00157 if( _pvp == pvp )
00158 return;
00159
00160 _pvp = pvp;
00161
00162
00163 Event event;
00164 event.type = Event::CHANNEL_RESIZE;
00165 event.originator = getID();
00166 event.resize.x = _pvp.x;
00167 event.resize.y = _pvp.y;
00168 event.resize.w = _pvp.w;
00169 event.resize.h = _pvp.h;
00170
00171 processEvent( event );
00172 }
00173
00174 EQINFO << "Channel viewport update: " << _pvp << ":" << _vp << endl;
00175 }
00176
00177 void Channel::setNearFar( const float nearPlane, const float farPlane )
00178 {
00179 _frustum.adjustNear( nearPlane );
00180 _frustum.farPlane = farPlane;
00181 _ortho.nearPlane = nearPlane;
00182 _ortho.farPlane = farPlane;
00183
00184 if( _context )
00185 {
00186 _context->frustum.adjustNear( nearPlane );
00187 _context->frustum.farPlane = farPlane;
00188 _context->ortho.nearPlane = nearPlane;
00189 _context->ortho.farPlane = farPlane;
00190 }
00191
00192 if( _frustum.nearPlane == nearPlane && _frustum.farPlane == farPlane )
00193 return;
00194
00195 ChannelSetNearFarPacket packet;
00196 packet.nearPlane = nearPlane;
00197 packet.farPlane = farPlane;
00198
00199 net::NodePtr node = RefPtr_static_cast< Server, net::Node >( getServer( ));
00200 send( node, packet );
00201 }
00202
00203 void Channel::addStatistic( Event& event )
00204 {
00205 _statistics.push_back( event.statistic );
00206 processEvent( event );
00207 }
00208
00209
00210
00211
00212
00213 void Channel::frameClear( const uint32_t frameID )
00214 {
00215 EQ_GL_CALL( applyBuffer( ));
00216 EQ_GL_CALL( applyViewport( ));
00217
00218 #ifndef NDEBUG
00219 if( getenv( "EQ_TAINT_CHANNELS" ))
00220 {
00221 const vmml::Vector3ub color = getUniqueColor();
00222 glClearColor( color.r/255.0f, color.g/255.0f, color.b/255.0f, 1.0f );
00223 }
00224 #endif // DEBUG
00225
00226 EQ_GL_CALL( glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ));
00227 }
00228
00229 void Channel::frameDraw( const uint32_t frameID )
00230 {
00231 EQ_GL_CALL( applyBuffer( ));
00232 EQ_GL_CALL( applyViewport( ));
00233
00234 EQ_GL_CALL( glMatrixMode( GL_PROJECTION ));
00235 EQ_GL_CALL( glLoadIdentity( ));
00236 EQ_GL_CALL( applyFrustum( ));
00237
00238 EQ_GL_CALL( glMatrixMode( GL_MODELVIEW ));
00239 EQ_GL_CALL( glLoadIdentity( ));
00240 EQ_GL_CALL( applyHeadTransform( ));
00241 }
00242
00243 void Channel::frameAssemble( const uint32_t frameID )
00244 {
00245 EQ_GL_CALL( applyBuffer( ));
00246 EQ_GL_CALL( applyViewport( ));
00247 EQ_GL_CALL( setupAssemblyState( ));
00248
00249 Compositor::assembleFrames( getInputFrames(), this );
00250
00251 EQ_GL_CALL( resetAssemblyState( ));
00252 }
00253
00254 void Channel::frameReadback( const uint32_t frameID )
00255 {
00256 EQ_GL_CALL( applyBuffer( ));
00257 EQ_GL_CALL( applyViewport( ));
00258 EQ_GL_CALL( setupAssemblyState( ));
00259
00260 Window::ObjectManager* glObjects = getWindow()->getObjectManager();
00261
00262 const FrameVector& frames = getOutputFrames();
00263 for( FrameVector::const_iterator i = frames.begin(); i != frames.end(); ++i)
00264 {
00265 Frame* frame = *i;
00266 frame->startReadback( glObjects );
00267 }
00268 for( FrameVector::const_iterator i = frames.begin(); i != frames.end(); ++i)
00269 {
00270 Frame* frame = *i;
00271 frame->syncReadback();
00272 }
00273
00274 EQ_GL_CALL( resetAssemblyState( ));
00275 }
00276
00277 void Channel::setupAssemblyState()
00278 {
00279 EQ_GL_ERROR( "before setupAssemblyState" );
00280 glPushAttrib( GL_ENABLE_BIT | GL_STENCIL_BUFFER_BIT | GL_VIEWPORT_BIT |
00281 GL_SCISSOR_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT |
00282 GL_POLYGON_BIT );
00283
00284 glDisable( GL_DEPTH_TEST );
00285 glDisable( GL_BLEND );
00286 glDisable( GL_ALPHA_TEST );
00287 glDisable( GL_STENCIL_TEST );
00288 glDisable( GL_TEXTURE_1D );
00289 glDisable( GL_TEXTURE_2D );
00290 glDisable( GL_TEXTURE_3D );
00291 glDisable( GL_FOG );
00292 glDisable( GL_CLIP_PLANE0 );
00293 glDisable( GL_CLIP_PLANE1 );
00294 glDisable( GL_CLIP_PLANE2 );
00295 glDisable( GL_CLIP_PLANE3 );
00296 glDisable( GL_CLIP_PLANE4 );
00297 glDisable( GL_CLIP_PLANE5 );
00298
00299 glPolygonMode( GL_FRONT, GL_FILL );
00300
00301 EQASSERT( _window );
00302 const PixelViewport& pvp = _window->getPixelViewport();
00303 EQASSERT( pvp.isValid( ));
00304
00305 glViewport( 0, 0, pvp.w, pvp.h );
00306 glScissor( 0, 0, pvp.w, pvp.h );
00307
00308 glMatrixMode( GL_PROJECTION );
00309 glPushMatrix();
00310 glLoadIdentity();
00311 glOrtho( 0.0f, pvp.w, 0.0f, pvp.h, -1.0f, 1.0f );
00312
00313 glMatrixMode( GL_MODELVIEW );
00314 glPushMatrix();
00315 glLoadIdentity();
00316 EQ_GL_ERROR( "after setupAssemblyState" );
00317 }
00318
00319 void Channel::resetAssemblyState()
00320 {
00321 EQ_GL_ERROR( "before resetAssemblyState" );
00322 glMatrixMode( GL_PROJECTION );
00323 glPopMatrix();
00324
00325 glMatrixMode( GL_MODELVIEW );
00326 glPopMatrix();
00327
00328 glPopAttrib();
00329 EQ_GL_ERROR( "after resetAssemblyState" );
00330 }
00331
00332 void Channel::_setRenderContext( RenderContext& context )
00333 {
00334 _context = &context;
00335 _window->addRenderContext( context );
00336 }
00337
00338 const Viewport& Channel::getViewport() const
00339 {
00340 return _context ? _context->vp : _vp;
00341 }
00342
00343 const PixelViewport& Channel::getPixelViewport() const
00344 {
00345 return _context ? _context->pvp : _pvp;
00346 }
00347
00348 const vmml::Vector2i& Channel::getPixelOffset() const
00349 {
00350 return _context ? _context->offset : vmml::Vector2i::ZERO;
00351 }
00352
00353 uint32_t Channel::getDrawBuffer() const
00354 {
00355 return _context ? _context->buffer : GL_BACK;
00356 }
00357
00358 uint32_t Channel::getReadBuffer() const
00359 {
00360 return _context ? _context->buffer : GL_BACK;
00361 }
00362
00363 const ColorMask& Channel::getDrawBufferMask() const
00364 {
00365 return _context ? _context->drawBufferMask : ColorMask::ALL;
00366 }
00367
00368 const vmml::Frustumf& Channel::getFrustum() const
00369 {
00370 return _context ? _context->frustum : _frustum;
00371 }
00372
00373 const vmml::Frustumf& Channel::getOrtho() const
00374 {
00375 return _context ? _context->ortho : _ortho;
00376 }
00377
00378 const Range& Channel::getRange() const
00379 {
00380 return _context ? _context->range : Range::ALL;
00381 }
00382
00383 const Pixel& Channel::getPixel() const
00384 {
00385 return _context ? _context->pixel : Pixel::ALL;
00386 }
00387
00388 Eye Channel::getEye() const
00389 {
00390 return _context ? _context->eye : EYE_CYCLOP;
00391 }
00392
00393 const vmml::Matrix4f& Channel::getHeadTransform() const
00394 {
00395 return _context ? _context->headTransform : vmml::Matrix4f::IDENTITY;
00396 }
00397
00398 const vmml::Vector2i& Channel::getScreenOrigin() const
00399 {
00400 return _context ? _context->screenOrigin : vmml::Vector2i::ZERO;
00401 }
00402
00403 vmml::Vector2i Channel::getScreenSize() const
00404 {
00405 return _context ? _context->screenSize : vmml::Vector2i( _pvp.w, _pvp.h );
00406 }
00407
00408 vmml::Frustumf Channel::getScreenFrustum() const
00409 {
00410 vmml::Vector2i origin = getScreenOrigin();
00411 const PixelViewport& pvp = getPixelViewport();
00412 const Pixel& pixel = getPixel();
00413
00414 origin.x += pixel.x;
00415 origin.y += pixel.y;
00416
00417 return vmml::Frustumf( origin.x, origin.x + pvp.w * pixel.w,
00418 origin.y, origin.y + pvp.h * pixel.h,
00419 -1.f, 1.f );
00420 }
00421
00422
00423 void Channel::applyBuffer() const
00424 {
00425 EQ_GL_CALL( glReadBuffer( getReadBuffer( )));
00426 EQ_GL_CALL( glDrawBuffer( getDrawBuffer( )));
00427
00428 applyColorMask();
00429 }
00430
00431 void Channel::applyColorMask() const
00432 {
00433 const ColorMask& colorMask = getDrawBufferMask();
00434 glColorMask( colorMask.red, colorMask.green, colorMask.blue, true );
00435 }
00436
00437 void Channel::applyViewport() const
00438 {
00439 const PixelViewport& pvp = getPixelViewport();
00440
00441
00442 if( !pvp.hasArea( ))
00443 {
00444 EQERROR << "Can't apply viewport " << pvp << endl;
00445 return;
00446 }
00447
00448 EQ_GL_CALL( glViewport( pvp.x, pvp.y, pvp.w, pvp.h ));
00449 EQ_GL_CALL( glScissor( pvp.x, pvp.y, pvp.w, pvp.h ));
00450 }
00451
00452 void Channel::applyFrustum() const
00453 {
00454 const vmml::Frustumf& frustum = getFrustum();
00455 EQ_GL_CALL( glFrustum( frustum.left, frustum.right, \
00456 frustum.bottom, frustum.top, \
00457 frustum.nearPlane, frustum.farPlane ));
00458 EQVERB << "Apply " << frustum << endl;
00459 }
00460
00461 void Channel::applyOrtho() const
00462 {
00463 const vmml::Frustumf& ortho = getOrtho();
00464 EQ_GL_CALL( glOrtho( ortho.left, ortho.right, \
00465 ortho.bottom, ortho.top, \
00466 ortho.nearPlane, ortho.farPlane ));
00467 EQVERB << "Apply " << ortho << endl;
00468 }
00469
00470 void Channel::applyScreenFrustum() const
00471 {
00472 const vmml::Frustumf frustum = getScreenFrustum();
00473 EQ_GL_CALL( glOrtho( frustum.left, frustum.right, \
00474 frustum.bottom, frustum.top, \
00475 frustum.nearPlane, frustum.farPlane ));
00476 EQVERB << "Apply " << frustum << endl;
00477 }
00478
00479 void Channel::applyHeadTransform() const
00480 {
00481 const vmml::Matrix4f& xfm = getHeadTransform();
00482 EQ_GL_CALL( glMultMatrixf( xfm.ml ));
00483 EQVERB << "Apply head transform: " << xfm << endl;
00484 }
00485
00486 bool Channel::processEvent( const Event& event )
00487 {
00488 ConfigEvent configEvent;
00489 configEvent.data = event;
00490
00491 switch( event.type )
00492 {
00493 case Event::STATISTIC:
00494 break;
00495
00496 case Event::CHANNEL_RESIZE:
00497 {
00498 const View* view = getView();
00499 if( !view )
00500 return true;
00501
00502
00503 configEvent.data.type = Event::VIEW_RESIZE;
00504 configEvent.data.originator = view->getID();
00505 break;
00506 }
00507
00508 default:
00509 EQWARN << "Unhandled channel event of type " << event.type
00510 << endl;
00511 EQUNIMPLEMENTED;
00512 }
00513
00514 Config* config = getConfig();
00515 config->sendEvent( configEvent );
00516 return true;
00517 }
00518
00519 #define HEIGHT 12
00520 #define SPACE 2
00521
00522 void Channel::drawStatistics()
00523 {
00524 Config* config = getConfig();
00525 EQASSERT( config );
00526
00527 vector< FrameStatistics > statistics;
00528 config->getStatistics( statistics );
00529
00530 if( statistics.empty( ))
00531 return;
00532
00533 EQ_GL_CALL( applyBuffer( ));
00534 EQ_GL_CALL( applyViewport( ));
00535 EQ_GL_CALL( setupAssemblyState( ));
00536
00537 glClear( GL_DEPTH_BUFFER_BIT );
00538
00539 glDisable( GL_LIGHTING );
00540 glEnable( GL_DEPTH_TEST );
00541
00542 const util::BitmapFont& font =_window->getObjectManager()->getDefaultFont();
00543
00544 int64_t xStart = 0;
00545 PixelViewport pvp = _window->getPixelViewport();
00546 pvp.x = 0;
00547 pvp.y = 0;
00548
00549
00550 int64_t xMax = 0;
00551 int64_t xMin = std::numeric_limits< int64_t >::max();
00552
00553 for( vector< FrameStatistics >::const_iterator i = statistics.begin();
00554 i != statistics.end(); ++i )
00555 {
00556 const FrameStatistics& frameStats = *i;
00557 const SortedStatistics& configStats = frameStats.second;
00558
00559 for( SortedStatistics::const_iterator j = configStats.begin();
00560 j != configStats.end(); ++j )
00561 {
00562 const Statistics& stats = j->second;
00563
00564 for( Statistics::const_iterator k = stats.begin();
00565 k != stats.end(); ++k )
00566 {
00567 const Statistic& stat = *k;
00568 xMax = EQ_MAX( xMax, stat.endTime );
00569 xMin = EQ_MIN( xMin, stat.endTime );
00570 }
00571 }
00572 }
00573 uint32_t scale = 1;
00574 while( (xMax - xMin) / scale > pvp.w )
00575 scale *= 10;
00576
00577 xMax /= scale;
00578 xStart = xMax - pvp.getXEnd() + SPACE;
00579 uint32_t nextY = pvp.getYEnd() - SPACE;
00580 std::map< uint32_t, uint32_t > positions;
00581
00582 float dim = 0.0f;
00583 for( vector< FrameStatistics >::reverse_iterator i = statistics.rbegin();
00584 i != statistics.rend(); ++i )
00585 {
00586 const FrameStatistics& frameStats = *i;
00587 const SortedStatistics& configStats = frameStats.second;
00588
00589 int64_t frameMin = xMax;
00590 int64_t frameMax = 0;
00591
00592
00593 for( SortedStatistics::const_iterator j = configStats.begin();
00594 j != configStats.end(); ++j )
00595 {
00596 const uint32_t id = j->first;
00597 const Statistics& stats = j->second;
00598
00599 if( stats.empty( ))
00600 continue;
00601
00602 if( positions.find( id ) == positions.end( ))
00603 {
00604 positions.insert(
00605 std::pair< uint32_t, uint32_t >( id, nextY ));
00606 nextY -= (HEIGHT + SPACE);
00607 }
00608
00609 const uint32_t y = positions[ id ];
00610
00611 const Statistic& nameStat = stats.front();
00612 glColor3f( 1.f, 1.f, 1.f );
00613 glRasterPos3f( 100.f, y-SPACE-12.0f, 0.99f );
00614 font.draw( nameStat.resourceName );
00615
00616 glBegin( GL_QUADS );
00617 for( Statistics::const_iterator k = stats.begin();
00618 k != stats.end(); ++k )
00619 {
00620 const Statistic& stat = *k;
00621 const int64_t startTime = stat.startTime / scale;
00622 const int64_t endTime = stat.endTime / scale;
00623
00624 frameMin = EQ_MIN( frameMin, startTime );
00625 frameMax = EQ_MAX( frameMax, endTime );
00626
00627 if( endTime < xStart || endTime == startTime )
00628 continue;
00629
00630 float y1 = y;
00631 float y2 = y - HEIGHT;
00632 float z = 0.0f;
00633
00634 switch( stat.type )
00635 {
00636 case Statistic::CHANNEL_CLEAR:
00637 glColor3f( .5f-dim, 1.0f-dim, .5f-dim );
00638 break;
00639 case Statistic::CHANNEL_DRAW:
00640 glColor3f( 0.f, 1.0f-dim, 0.f );
00641 break;
00642 case Statistic::CHANNEL_DRAW_FINISH:
00643 glColor3f( 0.f, .5f-dim, 0.f );
00644 break;
00645 case Statistic::CHANNEL_ASSEMBLE:
00646 glColor3f( 1.0f-dim, 1.0f-dim, 0.f );
00647 break;
00648 case Statistic::CHANNEL_READBACK:
00649 glColor3f( 1.0f-dim, .5f-dim, .5f-dim );
00650 break;
00651 case Statistic::NODE_TRANSMIT:
00652 case Statistic::CHANNEL_TRANSMIT:
00653 glColor3f( 0.f, 0.f, 1.0f-dim );
00654 z = 0.5f;
00655 break;
00656 case Statistic::CHANNEL_TRANSMIT_NODE:
00657 glColor3f( 0.5f-dim, 0.5f-dim, 1.0f-dim );
00658 y1 -= SPACE;
00659 z = 0.6f;
00660 break;
00661 case Statistic::CHANNEL_COMPRESS:
00662 case Statistic::NODE_COMPRESS:
00663 glColor3f( 1.0f-dim, 1.0f-dim, 1.0f-dim );
00664 y1 -= SPACE;
00665 z = 0.7f;
00666 break;
00667 case Statistic::CHANNEL_WAIT_FRAME:
00668 case Statistic::CONFIG_WAIT_FINISH_FRAME:
00669 glColor3f( 1.0f-dim, 0.f, 0.f );
00670 y1 -= SPACE;
00671 y2 += SPACE;
00672 z = 0.1f;
00673 break;
00674
00675 case Statistic::WINDOW_FINISH:
00676 glColor3f( 1.0f-dim, .5f-dim, 0.f );
00677 break;
00678
00679 case Statistic::WINDOW_SWAP_BARRIER:
00680 glColor3f( 1.0f-dim, 0.f, 0.f );
00681 break;
00682
00683 case Statistic::CONFIG_START_FRAME:
00684 glColor3f( .5f-dim, 1.0f-dim, .5f-dim );
00685 z = 0.1f;
00686 break;
00687 case Statistic::CONFIG_FINISH_FRAME:
00688 glColor3f( .5f-dim, .5f-dim, .5f-dim );
00689 break;
00690
00691 default:
00692 glColor3f( 1.0f-dim, 1.0f-dim, 1.0f-dim );
00693 z = 0.2f;
00694 break;
00695 }
00696
00697 const float x1 = startTime - xStart;
00698 const float x2 = endTime - xStart;
00699
00700 glVertex3f( x2, y1, z );
00701 glVertex3f( x1, y1, z );
00702 glVertex3f( x1, y2, z );
00703 glVertex3f( x2, y2, z );
00704 }
00705 glEnd();
00706 }
00707
00708 frameMin -= xStart;
00709 frameMax -= xStart;
00710
00711 glBegin( GL_QUADS );
00712 glColor3f( .5f-dim, 1.0f-dim, .5f-dim );
00713 glVertex3f( frameMin+1.0f, pvp.getYEnd(), 0.3f );
00714 glVertex3f( frameMin, pvp.getYEnd(), 0.3f );
00715 glVertex3f( frameMin, nextY, 0.3f );
00716 glVertex3f( frameMin+1.0f, nextY, 0.3f );
00717
00718 glColor3f( .5f-dim, .5f-dim, .5f-dim );
00719 glVertex3f( frameMax+1.0f, pvp.getYEnd(), 0.3f );
00720 glVertex3f( frameMax, pvp.getYEnd(), 0.3f );
00721 glVertex3f( frameMax, nextY, 0.3f );
00722 glVertex3f( frameMax+1.0f, nextY, 0.3f );
00723 glEnd();
00724
00725 dim += .2f;
00726 }
00727
00728 glColor3f( 1.f, 1.f, 1.f );
00729 ostringstream scaleText;
00730 scaleText << ": " << scale << "ms/pixel";
00731 font.draw( scaleText.str( ));
00732
00733 EQ_GL_CALL( resetAssemblyState( ));
00734 }
00735
00736 void Channel::outlineViewport()
00737 {
00738 setupAssemblyState();
00739
00740 const PixelViewport& pvp = getPixelViewport();
00741 glDisable( GL_LIGHTING );
00742 glColor3f( 1.0f, 1.0f, 1.0f );
00743 glBegin( GL_LINE_LOOP );
00744 {
00745 glVertex3f( pvp.x + .5f, pvp.y + .5f, 0.f );
00746 glVertex3f( pvp.getXEnd() - .5f, pvp.y + .5f, 0.f );
00747 glVertex3f( pvp.getXEnd() - .5f, pvp.getYEnd() - .5f, 0.f );
00748 glVertex3f( pvp.x + .5f, pvp.getYEnd() - .5f, 0.f );
00749 }
00750 glEnd();
00751
00752 resetAssemblyState();
00753 }
00754
00755
00756
00757
00758
00759 net::CommandResult Channel::_cmdConfigInit( net::Command& command )
00760 {
00761 const ChannelConfigInitPacket* packet =
00762 command.getPacket<ChannelConfigInitPacket>();
00763 EQLOG( LOG_TASKS ) << "TASK channel config init " << packet << endl;
00764
00765 if( packet->viewID != EQ_ID_INVALID )
00766 {
00767 View* view = new View;
00768 Config* config = getConfig();
00769
00770 if( config->mapObject( view, packet->viewID ))
00771 _view = view;
00772 else
00773 {
00774 delete view;
00775 EQUNREACHABLE;
00776 }
00777 }
00778
00779 if( packet->pvp.isValid( ))
00780 _setPixelViewport( packet->pvp );
00781 else
00782 _setViewport( packet->vp );
00783
00784 _name = packet->name;
00785 _color = packet->color;
00786 memcpy( _iAttributes, packet->iAttributes, IATTR_ALL * sizeof( int32_t ));
00787
00788 _error.clear();
00789 ChannelConfigInitReplyPacket reply;
00790 reply.result = configInit( packet->initID );
00791
00792 reply.nearPlane = _frustum.nearPlane;
00793 reply.farPlane = _frustum.farPlane;
00794
00795 EQLOG( LOG_TASKS ) << "TASK channel config init reply " << &reply << endl;
00796 send( command.getNode(), reply, _error );
00797 return net::COMMAND_HANDLED;
00798 }
00799
00800 net::CommandResult Channel::_cmdConfigExit( net::Command& command )
00801 {
00802 const ChannelConfigExitPacket* packet =
00803 command.getPacket<ChannelConfigExitPacket>();
00804 EQLOG( LOG_TASKS ) << "TASK configExit " << getName() << " " << packet
00805 << endl;
00806
00807 ChannelConfigExitReplyPacket reply;
00808 reply.result = configExit();
00809
00810 if( _view )
00811 {
00812 Config* config = getConfig();
00813
00814 config->unmapObject( _view );
00815 delete _view;
00816 _view = 0;
00817 }
00818
00819 send( command.getNode(), reply );
00820 return net::COMMAND_HANDLED;
00821 }
00822
00823 net::CommandResult Channel::_cmdFrameStart( net::Command& command )
00824 {
00825 const ChannelFrameStartPacket* packet =
00826 command.getPacket<ChannelFrameStartPacket>();
00827 EQVERB << "handle channel frame start " << packet << endl;
00828
00829
00830 if( _view )
00831 _view->sync( packet->viewVersion );
00832
00833 frameStart( packet->frameID, packet->frameNumber );
00834
00835 return net::COMMAND_HANDLED;
00836 }
00837
00838 net::CommandResult Channel::_cmdFrameFinish( net::Command& command )
00839 {
00840 const ChannelFrameFinishPacket* packet =
00841 command.getPacket<ChannelFrameFinishPacket>();
00842 EQLOG( LOG_TASKS ) << "TASK frame finish " << getName() << " " << packet << endl;
00843
00844 frameFinish( packet->frameID, packet->frameNumber );
00845
00846 ChannelFrameFinishReplyPacket reply( packet );
00847 reply.nStatistics = _statistics.size();
00848
00849 command.getNode()->send( reply, _statistics );
00850
00851 _statistics.clear();
00852 return net::COMMAND_HANDLED;
00853 }
00854
00855 net::CommandResult Channel::_cmdFrameClear( net::Command& command )
00856 {
00857 ChannelFrameClearPacket* packet =
00858 command.getPacket<ChannelFrameClearPacket>();
00859 EQLOG( LOG_TASKS ) << "TASK clear " << getName() << " " << packet << endl;
00860
00861 ChannelStatistics event( Statistic::CHANNEL_CLEAR, this );
00862
00863 _setRenderContext( packet->context );
00864 frameClear( packet->context.frameID );
00865 _context = 0;
00866
00867 return net::COMMAND_HANDLED;
00868 }
00869
00870 net::CommandResult Channel::_cmdFrameDraw( net::Command& command )
00871 {
00872 ChannelFrameDrawPacket* packet =
00873 command.getPacket<ChannelFrameDrawPacket>();
00874 EQLOG( LOG_TASKS ) << "TASK draw " << getName() << " " << packet << endl;
00875
00876 ChannelStatistics event( Statistic::CHANNEL_DRAW, this );
00877
00878 _setRenderContext( packet->context );
00879 frameDraw( packet->context.frameID );
00880 _context = 0;
00881
00882 return net::COMMAND_HANDLED;
00883 }
00884
00885 net::CommandResult Channel::_cmdFrameDrawFinish( net::Command& command )
00886 {
00887 ChannelFrameDrawFinishPacket* packet =
00888 command.getPacket< ChannelFrameDrawFinishPacket >();
00889 EQLOG( LOG_TASKS ) << "TASK draw finish " << getName() << " " << packet
00890 << endl;
00891
00892 ChannelStatistics event( Statistic::CHANNEL_DRAW_FINISH, this );
00893 frameDrawFinish( packet->frameID, packet->frameNumber );
00894
00895 return net::COMMAND_HANDLED;
00896 }
00897
00898 net::CommandResult Channel::_cmdFrameAssemble( net::Command& command )
00899 {
00900 ChannelFrameAssemblePacket* packet =
00901 command.getPacket<ChannelFrameAssemblePacket>();
00902 EQLOG( LOG_TASKS | LOG_ASSEMBLY ) << "TASK assemble " << getName() << " "
00903 << packet << endl;
00904
00905 ChannelStatistics event( Statistic::CHANNEL_ASSEMBLE, this );
00906 _setRenderContext( packet->context );
00907
00908 for( uint32_t i=0; i<packet->nFrames; ++i )
00909 {
00910 Pipe* pipe = getPipe();
00911 Frame* frame = pipe->getFrame( packet->frames[i], _context->eye );
00912 _inputFrames.push_back( frame );
00913 }
00914
00915 frameAssemble( packet->context.frameID );
00916
00917 _inputFrames.clear();
00918 _context = 0;
00919
00920 return net::COMMAND_HANDLED;
00921 }
00922
00923 net::CommandResult Channel::_cmdFrameReadback( net::Command& command )
00924 {
00925 ChannelFrameReadbackPacket* packet =
00926 command.getPacket<ChannelFrameReadbackPacket>();
00927 EQLOG( LOG_TASKS | LOG_ASSEMBLY ) << "TASK readback " << getName() << " "
00928 << packet << endl;
00929
00930 ChannelStatistics event( Statistic::CHANNEL_READBACK, this );
00931 _setRenderContext( packet->context );
00932
00933 for( uint32_t i=0; i<packet->nFrames; ++i )
00934 {
00935 Pipe* pipe = getPipe();
00936 Frame* frame = pipe->getFrame( packet->frames[i], _context->eye );
00937 _outputFrames.push_back( frame );
00938 }
00939
00940 frameReadback( packet->context.frameID );
00941
00942 for( FrameVector::const_iterator i = _outputFrames.begin();
00943 i != _outputFrames.end(); ++i)
00944 {
00945 Frame* frame = *i;
00946 frame->setReady();
00947 }
00948
00949 _outputFrames.clear();
00950 _context = 0;
00951 return net::COMMAND_HANDLED;
00952 }
00953
00954 net::CommandResult Channel::_cmdFrameTransmit( net::Command& command )
00955 {
00956 const ChannelFrameTransmitPacket* packet =
00957 command.getPacket<ChannelFrameTransmitPacket>();
00958 EQLOG( LOG_TASKS | LOG_ASSEMBLY ) << "TASK transmit " << getName() << " "
00959 << packet << endl;
00960
00961 #ifndef EQ_ASYNC_TRANSMIT
00962 ChannelStatistics event( Statistic::CHANNEL_TRANSMIT, this );
00963 #endif
00964
00965 net::Session* session = getSession();
00966 net::NodePtr localNode = session->getLocalNode();
00967 net::NodePtr server = session->getServer();
00968 Pipe* pipe = getPipe();
00969 Frame* frame = pipe->getFrame( packet->frame,
00970 packet->context.eye );
00971
00972 for( uint32_t i=0; i<packet->nNodes; ++i )
00973 {
00974 net::NodeID nodeID = packet->nodes[i];
00975 nodeID.convertToHost();
00976
00977 net::NodePtr node = command.getNode();
00978 net::NodePtr toNode = localNode->connect( nodeID, node );
00979 EQLOG( LOG_ASSEMBLY ) << "channel \"" << getName() << "\" transmit "
00980 << frame << " to " << nodeID << endl;
00981
00982 #ifdef EQ_ASYNC_TRANSMIT
00983 getNode()->transmitter.send( frame->getData(), toNode,
00984 getPipe()->getCurrentFrame( ));
00985 #else
00986 ChannelStatistics nodeEvent( Statistic::CHANNEL_TRANSMIT_NODE, this );
00987 ChannelStatistics compressEvent( Statistic::CHANNEL_COMPRESS, this );
00988 compressEvent.event.statistic.endTime =
00989 compressEvent.event.statistic.startTime + frame->transmit( toNode );
00990 #endif
00991 }
00992
00993 return net::COMMAND_HANDLED;
00994 }
00995 }