Permalink
Browse files

Implement limiting readback to updated region in eqPly:

- Track normalized region in KD-Tree renderer
- Update pixel-based region in eqPly::Channel
- Use pixel-based region to form intersection with requested readback

To be moved to client library with proper API later.

[ ] May break build
[ ] May break existing applications (see CHANGES.txt)
[ ] Bugfix
[x] New Feature
[ ] Cleanup
[x] Optimization
[ ] Documentation
  • Loading branch information...
1 parent c4a8a55 commit 448af149cd170d4e251b9032c34a222bb8b937f5 @eile eile committed Jan 6, 2012
@@ -1,5 +1,5 @@
# Copyright (c) 2010 Daniel Pfeifer <daniel@pfeifer-mail.de>
-# 2010-2011 Stefan Eilemann <eile@eyescale.ch>
+# 2010-2012 Stefan Eilemann <eile@eyescale.ch>
if(MSVC)
add_definitions(/wd4996)
@@ -25,6 +25,7 @@ set(KD_SOURCES
vertexBufferLeaf.cpp
vertexBufferNode.cpp
vertexBufferRoot.cpp
+ vertexBufferState.cpp
vertexData.cpp
)
@@ -1,5 +1,5 @@
-/* Copyright (c) 2006-2011, Stefan Eilemann <eile@equalizergraphics.com>
+/* Copyright (c) 2006-2012, Stefan Eilemann <eile@equalizergraphics.com>
* 2010, Cedric Stalder <cedric.stalder@gmail.com>
* 2007, Tobias Wolf <twolf@access.unizh.ch>
*
@@ -93,6 +93,8 @@ void Channel::frameClear( const eq::uint128_t& frameID )
return;
_initJitter();
+ _region.invalidate();
+
const FrameData& frameData = _getFrameData();
const int32_t eyeIndex = co::base::getIndexOfLastBit( getEye() );
if( _isDone() && !_accum[ eyeIndex ].transfer )
@@ -204,6 +206,7 @@ void Channel::frameAssemble( const eq::uint128_t& frameID )
}
eq::Channel::frameAssemble( frameID );
+ _updateRegion( getInputFrames( ));
return;
}
// else
@@ -239,22 +242,20 @@ void Channel::frameAssemble( const eq::uint128_t& frameID )
}
resetAssemblyState();
+ _updateRegion( frames );
}
void Channel::frameReadback( const eq::uint128_t& frameID )
{
- if( stopRendering( ))
- return;
-
- if( _isDone( ))
+ if( stopRendering() || _isDone() || !_region.hasArea( ))
return;
- // OPT: Drop alpha channel from all frames during network transport
const FrameData& frameData = _getFrameData();
const eq::Frames& frames = getOutputFrames();
for( eq::FramesCIter i = frames.begin(); i != frames.end(); ++i )
{
eq::Frame* frame = *i;
+ // OPT: Drop alpha channel from all frames during network transport
frame->setAlphaUsage( false );
if( frameData.isIdle( ))
@@ -266,9 +267,34 @@ void Channel::frameReadback( const eq::uint128_t& frameID )
frame->useCompressor( eq::Frame::BUFFER_COLOR, EQ_COMPRESSOR_AUTO );
else
frame->useCompressor( eq::Frame::BUFFER_COLOR, EQ_COMPRESSOR_NONE );
- }
- eq::Channel::frameReadback( frameID );
+ const eq::DrawableConfig& drawable = getDrawableConfig();
+ eq::Window::ObjectManager* glObjects = getObjectManager();
+ eq::FrameData* data = frame->getData();
+
+ if( data->getType() == eq::Frame::TYPE_TEXTURE )
+ frame->readback( glObjects, drawable );
+ else
+ {
+ // ROI readback, TODO move to eq::Channel::frameReadback
+ EQASSERT( data->getType() == eq::Frame::TYPE_MEMORY );
+ const eq::PixelViewport& framePVP = data->getPixelViewport();
+ eq::PixelViewport area = framePVP + frame->getOffset();
+
+ area.intersect( _region );
+ if( !area.hasArea( ))
+ continue;
+
+ eq::Image* image = data->newImage( data->getType(), drawable );
+ image->readback( data->getBuffers(), area, frame->getZoom(),
+ glObjects );
+
+ const eq::Pixel& pixel = getPixel();
+ area -= frame->getOffset();
+ image->setOffset( (area.x - framePVP.x) * pixel.w,
+ (area.y - framePVP.y) * pixel.h );
+ }
+ }
}
void Channel::frameStart( const eq::uint128_t& frameID,
@@ -633,10 +659,30 @@ void Channel::_drawModel( const Model* model )
glUseProgram( program );
model->cullDraw( state );
- state.setChannel( 0 );
+ if( getName() == "channel-left" )
+ EQINFO << state.getRegion() << std::endl;
+ _updateRegion( state.getRegion( ));
+ state.setChannel( 0 );
if( program != VertexBufferState::INVALID )
glUseProgram( 0 );
+
+#ifndef NDEBUG // region border
+ const eq::PixelViewport& pvp = getPixelViewport();
+
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glOrtho( 0.f, pvp.w, 0.f, pvp.h, -1.f, 1.f );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+
+ glBegin( GL_LINE_LOOP ); {
+ glVertex3f( float( _region.x ) , float( _region.y ), -.99f );
+ glVertex3f( float( _region.getXEnd()), float( _region.y ), -.99f );
+ glVertex3f( float( _region.getXEnd()), float( _region.getYEnd()), -.99f );
+ glVertex3f( float( _region.x ), float( _region.getYEnd()), -.99f );
+ } glEnd();
+#endif
}
void Channel::_drawOverlay()
@@ -647,7 +693,6 @@ void Channel::_drawOverlay()
if( !texture )
return;
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
applyScreenFrustum();
@@ -657,23 +702,7 @@ void Channel::_drawOverlay()
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHTING );
glColor3f( 1.0f, 1.0f, 1.0f );
-
-#if 1
- // border
- const eq::PixelViewport& pvp = getPixelViewport();
- const eq::Viewport& vp = getViewport();
- const float w = pvp.w / vp.w - .5f;
- const float h = pvp.h / vp.h - .5f;
-
- glBegin( GL_LINE_LOOP );
- {
- glVertex3f( .5f, .5f, 0.f );
- glVertex3f( w, .5f, 0.f );
- glVertex3f( w, h, 0.f );
- glVertex3f( .5f, h, 0.f );
- }
- glEnd();
-#endif
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
// logo
glEnable( GL_BLEND );
@@ -831,4 +860,38 @@ void Channel::_updateNearFar( const mesh::BoundingSphere& boundingSphere )
}
}
+void Channel::_updateRegion( const eq::Vector4f& vp )
+{
+ if( vp == eq::Vector4f::ZERO )
+ return;
+
+ eq::PixelViewport pvp = getPixelViewport();
+ pvp.x = 0;
+ pvp.y = 0;
+
+ eq::PixelViewport region( pvp );
+ region.apply( eq::Viewport( vp ));
+ _region.merge( region );
+ _region.intersect( pvp );
+}
+
+void Channel::_updateRegion( const eq::Frames& frames )
+{
+ // Increase ROI, TODO move to eq::Channel::frameReadback
+ for( eq::FramesCIter i = frames.begin(); i != frames.end(); ++i )
+ {
+ const eq::Frame* frame = *i;
+ const eq::FrameData* data = frame->getData();
+ const eq::Images& images = data->getImages();
+
+ for( eq::ImagesCIter j = images.begin(); j != images.end(); ++j )
+ {
+ const eq::Image* image = *j;
+ const eq::PixelViewport area = image->getPixelViewport() +
+ frame->getOffset();
+ _region.merge( area );
+ }
+ }
+}
+
}
@@ -1,6 +1,6 @@
-/* Copyright (c) 2006-2011, Stefan Eilemann <eile@equalizergraphics.com>
- * Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com>
+/* Copyright (c) 2006-2012, Stefan Eilemann <eile@equalizergraphics.com>
+ * 2010, Cedric Stalder <cedric.stalder@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -79,6 +79,8 @@ namespace eqPly
void _drawOverlay();
void _drawHelp();
void _updateNearFar( const mesh::BoundingSphere& boundingSphere );
+ void _updateRegion( const eq::Vector4f& vp ); // with draw area
+ void _updateRegion( const eq::Frames& frames ); // with assemble area
bool _isDone() const;
@@ -108,6 +110,7 @@ namespace eqPly
_accum[ eq::NUM_EYES ];
eq::PixelViewport _currentPVP;
+ eq::PixelViewport _region;
};
}
@@ -1,7 +1,7 @@
/* Copyright (c) 2007, Tobias Wolf <twolf@access.unizh.ch>
* 2009, Cedric Stalder <cedric.stalder@gmail.com>
- * 2011, Stefan Eilemann <eile@eyescale.ch>
+ * 2011-2012, Stefan Eilemann <eile@eyescale.ch>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -72,6 +72,7 @@ namespace mesh
typedef vmml::vector< 4, GLubyte > Color;
typedef vmml::vector< 3, GLfloat > Normal;
typedef vmml::matrix< 4, 4, float > Matrix4f;
+ typedef vmml::vector< 4, float > Vector4f;
typedef size_t Index;
typedef GLushort ShortIndex;
@@ -131,9 +132,8 @@ namespace mesh
const Index LEAF_SIZE( 21845 );
// binary mesh file version, increment if changing the file format
- const unsigned short FILE_VERSION ( 0x0115 );
-
-
+ const unsigned short FILE_VERSION ( 0x0116 );
+
// enumeration for the sort axis
enum Axis
{
@@ -1,6 +1,6 @@
/* Copyright (c) 2007, Tobias Wolf <twolf@access.unizh.ch>
- * 2008-2011, Stefan Eilemann <eile@equalizergraphics.com>
+ * 2008-2012, Stefan Eilemann <eile@equalizergraphics.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -61,20 +61,15 @@ namespace mesh
virtual Index getNumberOfVertices() const = 0;
const BoundingSphere& getBoundingSphere() const
- {
- return _boundingSphere;
- }
-
- const float* getRange() const
- {
- return &_range[0];
- }
+ { return _boundingSphere; }
+ const float* getRange() const { return &_range[0]; }
+
virtual const VertexBufferBase* getLeft() const { return 0; }
virtual const VertexBufferBase* getRight() const { return 0; }
virtual const BoundingSphere& updateBoundingSphere() = 0;
-
+
protected:
VertexBufferBase() : _boundingSphere( 0.0f )
{
@@ -86,8 +81,7 @@ namespace mesh
{
os.write( reinterpret_cast< char* >( &_boundingSphere ),
sizeof( BoundingSphere ) );
- os.write( reinterpret_cast< char* >( &_range ),
- sizeof( Range ) );
+ os.write( reinterpret_cast< char* >( &_range ), sizeof( Range ) );
}
virtual void fromMemory( char** addr, VertexBufferData& globalData )
@@ -1,5 +1,5 @@
-/* Copyright (c) 2008-2010, Stefan Eilemann <eile@equalizergraphics.com>
+/* Copyright (c) 2008-2012, Stefan Eilemann <eile@equalizergraphics.com>
* 2010, Cedric Stalder <cedric.stalder@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
@@ -165,7 +165,8 @@ void VertexBufferDist::getInstanceData( co::DataOStream& os )
const mesh::VertexBufferLeaf* leaf =
static_cast< const mesh::VertexBufferLeaf* >( _node );
- os << uint64_t( leaf->_vertexStart ) << uint64_t( leaf->_indexStart )
+ os << leaf->_boundingBox[0] << leaf->_boundingBox[1]
+ << uint64_t( leaf->_vertexStart ) << uint64_t( leaf->_indexStart )
<< uint64_t( leaf->_indexLength ) << leaf->_vertexLength;
}
@@ -222,7 +223,8 @@ void VertexBufferDist::applyInstanceData( co::DataIStream& is )
mesh::VertexBufferLeaf* leaf = new mesh::VertexBufferLeaf( data );
uint64_t i1, i2, i3;
- is >> i1 >> i2 >> i3 >> leaf->_vertexLength;
+ is >> leaf->_boundingBox[0] >> leaf->_boundingBox[1]
+ >> i1 >> i2 >> i3 >> leaf->_vertexLength;
leaf->_vertexStart = size_t( i1 );
leaf->_indexStart = size_t( i2 );
leaf->_indexLength = size_t( i3 );
Oops, something went wrong.

0 comments on commit 448af14

Please sign in to comment.