Commit 43ae1cb9 authored by Maciej Suminski's avatar Maciej Suminski

Smarter way of the overlay rendering (overlay is always refreshed, while...

Smarter way of the overlay rendering (overlay is always refreshed, while cached&noncached targets only if the viewport or items have changed).
parent e87eea7a
......@@ -127,6 +127,8 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent )
{
m_gal->ResizeScreen( aEvent.GetSize().x, aEvent.GetSize().y );
m_view->SetTargetDirty( KiGfx::TARGET_CACHED );
m_view->SetTargetDirty( KiGfx::TARGET_NONCACHED );
}
......@@ -134,24 +136,19 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool eraseBackground, const wxRect* rect )
{
#ifdef __WXDEBUG__
prof_counter time;
prof_start( &time, false );
#endif /* __WXDEBUG__ */
printf("Refresh!\n");
m_gal->BeginDrawing();
m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
m_gal->ClearScreen();
m_gal->DrawGrid();
m_view->Redraw();
m_gal->EndDrawing();
#ifdef __WXDEBUG__
prof_end( &time );
wxLogDebug( wxT( "EDA_DRAW_PANEL_GAL::Refresh: %.0f ms (%.0f fps)" ),
static_cast<double>( time.value ) / 1000.0, 1000000.0 / static_cast<double>( time.value ) );
#endif /* __WXDEBUG__ */
......@@ -184,6 +181,9 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
m_gal->SetScreenDPI( 106 ); // Display resolution setting
m_gal->ComputeWorldScreenMatrix();
wxSize size = GetClientSize();
m_gal->ResizeScreen( size.GetX(), size.GetY() );
if( m_painter )
m_painter->SetGAL( m_gal );
......@@ -193,9 +193,6 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
m_view->RecacheAllItems( true );
}
wxSize size = GetClientSize();
m_gal->ResizeScreen( size.GetX(), size.GetY() );
m_currentGal = aGalType;
}
......
......@@ -36,8 +36,6 @@ using namespace KiGfx;
CAIRO_COMPOSITOR::CAIRO_COMPOSITOR( cairo_t** aMainContext ) :
m_current( 0 ), m_currentContext( aMainContext ), m_mainContext( *aMainContext )
{
// Obtain the transformation matrix used in the main context
cairo_get_matrix( m_mainContext, &m_matrix );
}
......@@ -65,11 +63,10 @@ void CAIRO_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
}
unsigned int CAIRO_COMPOSITOR::GetBuffer()
unsigned int CAIRO_COMPOSITOR::CreateBuffer()
{
// Pixel storage
BitmapPtr bitmap( new unsigned int[m_bufferSize] );
memset( bitmap.get(), 0x00, m_bufferSize * sizeof(int) );
// Create the Cairo surface
......@@ -78,10 +75,10 @@ unsigned int CAIRO_COMPOSITOR::GetBuffer()
CAIRO_FORMAT_ARGB32, m_width,
m_height, m_stride );
cairo_t* context = cairo_create( surface );
#ifdef __WXDEBUG__
cairo_status_t status = cairo_status( context );
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, "Cairo context creation error" );
#endif /* __WXDEBUG__ */
#ifdef __WXDEBUG__
cairo_status_t status = cairo_status( context );
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, "Cairo context creation error" );
#endif /* __WXDEBUG__ */
// Set default settings for the buffer
cairo_set_antialias( context, CAIRO_ANTIALIAS_SUBPIXEL );
......@@ -89,6 +86,7 @@ unsigned int CAIRO_COMPOSITOR::GetBuffer()
cairo_set_line_cap( context, CAIRO_LINE_CAP_ROUND );
// Use the same transformation matrix as the main context
cairo_get_matrix( m_mainContext, &m_matrix );
cairo_set_matrix( context, &m_matrix );
// Store the new buffer
......@@ -101,53 +99,41 @@ unsigned int CAIRO_COMPOSITOR::GetBuffer()
void CAIRO_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
{
if( aBufferHandle <= usedBuffers() )
{
m_current = aBufferHandle - 1;
*m_currentContext = m_buffers[m_current].context;
}
wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
#ifdef __WXDEBUG__
else
wxLogDebug( wxT( "Tried to use a not existing buffer" ) );
#endif
// Get currently used transformation matrix, so it can be applied to the new buffer
cairo_get_matrix( *m_currentContext, &m_matrix );
m_current = aBufferHandle - 1;
*m_currentContext = m_buffers[m_current].context;
// Apply the current transformation matrix
cairo_set_matrix( *m_currentContext, &m_matrix );
}
void CAIRO_COMPOSITOR::ClearBuffer()
{
// Reset the transformation matrix, so it is possible to composite images using
// screen coordinates instead of world coordinates
cairo_identity_matrix( m_buffers[m_current].context );
cairo_set_source_rgba( m_buffers[m_current].context, 0.0, 0.0, 0.0, 0.0 );
cairo_rectangle( m_buffers[m_current].context, 0.0, 0.0, m_width, m_height );
cairo_fill( m_buffers[m_current].context );
// Restore the transformation matrix
cairo_set_matrix( m_buffers[m_current].context, &m_matrix );
// Clear the pixel storage
memset( m_buffers[m_current].bitmap.get(), 0x00, m_bufferSize * sizeof(int) );
}
void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
{
if( aBufferHandle <= usedBuffers() )
{
// Reset the transformation matrix, so it is possible to composite images using
// screen coordinates instead of world coordinates
cairo_identity_matrix( m_mainContext );
wxASSERT_MSG( aBufferHandle <= usedBuffers(), wxT( "Tried to use a not existing buffer" ) );
cairo_set_source_surface( m_mainContext, m_buffers[aBufferHandle - 1].surface, 0.0, 0.0 );
cairo_paint( m_mainContext );
// Reset the transformation matrix, so it is possible to composite images using
// screen coordinates instead of world coordinates
cairo_get_matrix( m_mainContext, &m_matrix );
cairo_identity_matrix( m_mainContext );
// Restore the transformation matrix
cairo_set_matrix( m_mainContext, &m_matrix );
}
// Draw the selected buffer contents
cairo_set_source_surface( m_mainContext, m_buffers[aBufferHandle - 1].surface, 0.0, 0.0 );
cairo_paint( m_mainContext );
#ifdef __WXDEBUG__
else
wxLogDebug( wxT( "Tried to use a not existing buffer" ) );
#endif
// Restore the transformation matrix
cairo_set_matrix( m_mainContext, &m_matrix );
}
......
......@@ -48,6 +48,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
isGrouping = false;
isInitialized = false;
isDeleteSavedPixels = false;
validCompositor = false;
groupCounter = 0;
// Connecting the event handlers
......@@ -90,7 +91,11 @@ CAIRO_GAL::~CAIRO_GAL()
void CAIRO_GAL::BeginDrawing()
{
initSurface();
setCompositor();
if( !validCompositor )
setCompositor();
compositor->SetMainContext( context );
compositor->SetBuffer( mainBuffer );
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
cairo_push_group( currentContext );
......@@ -120,9 +125,9 @@ void CAIRO_GAL::EndDrawing()
for( size_t count = 0; count < bufferSize; count++ )
{
unsigned int value = bitmapBuffer[count];
*wxOutputPtr++ = (value >> 16) & 0xff; // Red pixel
*wxOutputPtr++ = (value >> 8) & 0xff; // Green pixel
*wxOutputPtr++ = value & 0xff; // Blue pixel
*wxOutputPtr++ = ( value >> 16 ) & 0xff; // Red pixel
*wxOutputPtr++ = ( value >> 8 ) & 0xff; // Green pixel
*wxOutputPtr++ = value & 0xff; // Blue pixel
}
wxImage img( (int) screenSize.x, (int) screenSize.y, (unsigned char*) wxOutput, true );
......@@ -273,6 +278,10 @@ void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight )
deleteBitmaps();
allocateBitmaps();
if( validCompositor )
compositor->Resize( aWidth, aHeight );
validCompositor = false;
SetSize( wxSize( aWidth, aHeight ) );
}
......@@ -719,7 +728,7 @@ void CAIRO_GAL::SetTarget( RenderTarget aTarget )
{
// If the compositor is not set, that means that there is a recaching process going on
// and we do not need the compositor now
if( !compositor )
if( !validCompositor )
return;
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
......@@ -751,6 +760,31 @@ RenderTarget CAIRO_GAL::GetTarget() const
}
void CAIRO_GAL::ClearTarget( RenderTarget aTarget )
{
// Save the current state
unsigned int currentBuffer = compositor->GetBuffer();
switch( aTarget )
{
// Cached and noncached items are rendered to the same buffer
default:
case TARGET_CACHED:
case TARGET_NONCACHED:
compositor->SetBuffer( mainBuffer );
break;
case TARGET_OVERLAY:
compositor->SetBuffer( overlayBuffer );
break;
}
compositor->ClearBuffer();
// Restore the previous state
compositor->SetBuffer( currentBuffer );
}
VECTOR2D CAIRO_GAL::ComputeCursorToWorld( const VECTOR2D& aCursorPosition )
{
MATRIX3x3D inverseMatrix = worldScreenMatrix.Inverse();
......@@ -972,8 +1006,10 @@ void CAIRO_GAL::setCompositor()
compositor->Resize( screenSize.x, screenSize.y );
// Prepare buffers
mainBuffer = compositor->GetBuffer();
overlayBuffer = compositor->GetBuffer();
mainBuffer = compositor->CreateBuffer();
overlayBuffer = compositor->CreateBuffer();
validCompositor = true;
}
......
......@@ -74,7 +74,7 @@ void OPENGL_COMPOSITOR::Initialize()
GL_RENDERBUFFER, m_depthBuffer );
// Unbind the framebuffer, so by default all the rendering goes directly to the display
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glBindFramebuffer( GL_FRAMEBUFFER, DIRECT_RENDERING );
m_currentFbo = 0;
m_initialized = true;
......@@ -91,7 +91,7 @@ void OPENGL_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
}
unsigned int OPENGL_COMPOSITOR::GetBuffer()
unsigned int OPENGL_COMPOSITOR::CreateBuffer()
{
wxASSERT( m_initialized );
......@@ -169,8 +169,8 @@ unsigned int OPENGL_COMPOSITOR::GetBuffer()
ClearBuffer();
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
m_currentFbo = 0;
glBindFramebuffer( GL_FRAMEBUFFER, DIRECT_RENDERING );
m_currentFbo = DIRECT_RENDERING;
// Store the new buffer
OPENGL_BUFFER buffer = { textureTarget, attachmentPoint };
......@@ -186,10 +186,10 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
return;
// Change the rendering destination to the selected attachment point
if( aBufferHandle == 0 )
if( aBufferHandle == DIRECT_RENDERING )
{
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
m_currentFbo = 0;
glBindFramebuffer( GL_FRAMEBUFFER, DIRECT_RENDERING );
m_currentFbo = DIRECT_RENDERING;
}
else if( m_currentFbo != m_framebuffer )
{
......@@ -197,7 +197,7 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
m_currentFbo = m_framebuffer;
}
if( m_currentFbo != 0 && m_current != aBufferHandle - 1 )
if( m_currentFbo != DIRECT_RENDERING )
{
m_current = aBufferHandle - 1;
glDrawBuffer( m_buffers[m_current].attachmentPoint );
......@@ -219,8 +219,8 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
wxASSERT( m_initialized );
// Switch to the main framebuffer and blit the scene
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
m_currentFbo = 0;
glBindFramebuffer( GL_FRAMEBUFFER, DIRECT_RENDERING );
m_currentFbo = DIRECT_RENDERING;
// Depth test has to be disabled to make transparency working
glDisable( GL_DEPTH_TEST );
......@@ -279,4 +279,4 @@ void OPENGL_COMPOSITOR::clean()
}
GLuint OPENGL_COMPOSITOR::m_currentFbo = 0;
GLuint OPENGL_COMPOSITOR::m_currentFbo = DIRECT_RENDERING;
......@@ -130,8 +130,8 @@ void OPENGL_GAL::BeginDrawing()
// Prepare rendering target buffers
compositor.Initialize();
mainBuffer = compositor.GetBuffer();
overlayBuffer = compositor.GetBuffer();
mainBuffer = compositor.CreateBuffer();
overlayBuffer = compositor.CreateBuffer();
isFramebufferInitialized = true;
}
......@@ -187,13 +187,10 @@ void OPENGL_GAL::BeginDrawing()
SetFillColor( fillColor );
SetStrokeColor( strokeColor );
// Prepare buffers for drawing
compositor.SetBuffer( mainBuffer );
compositor.ClearBuffer();
compositor.SetBuffer( overlayBuffer );
compositor.ClearBuffer();
compositor.SetBuffer( 0 ); // Unbind buffers
// Unbind buffers - set compositor for direct drawing
compositor.SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
// Remove all previously stored items
nonCachedManager.Clear();
overlayManager.Clear();
......@@ -711,6 +708,31 @@ RenderTarget OPENGL_GAL::GetTarget() const
}
void OPENGL_GAL::ClearTarget( RenderTarget aTarget )
{
// Save the current state
unsigned int oldTarget = compositor.GetBuffer();
switch( aTarget )
{
// Cached and noncached items are rendered to the same buffer
default:
case TARGET_CACHED:
case TARGET_NONCACHED:
compositor.SetBuffer( mainBuffer );
break;
case TARGET_OVERLAY:
compositor.SetBuffer( overlayBuffer );
break;
}
compositor.ClearBuffer();
// Restore the previous state
compositor.SetBuffer( oldTarget );
}
VECTOR2D OPENGL_GAL::ComputeCursorToWorld( const VECTOR2D& aCursorPosition )
{
VECTOR2D cursorPosition = aCursorPosition;
......
......@@ -39,6 +39,28 @@
using namespace KiGfx;
VIEW::VIEW( bool aIsDynamic ) :
m_enableOrderModifier( false ),
m_scale( 1.0 ),
m_painter( NULL ),
m_gal( NULL ),
m_dynamic( aIsDynamic )
{
// Redraw everything at the beginning
for( int i = 0; i < TARGETS_NUMBER; ++i )
SetTargetDirty( i );
}
VIEW::~VIEW()
{
BOOST_FOREACH( LayerMap::value_type& l, m_layers )
{
delete l.second.items;
}
}
void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
{
if( m_layers.find( aLayer ) == m_layers.end() )
......@@ -197,25 +219,6 @@ int VIEW::Query( const BOX2I& aRect, std::vector<LayerItemPair>& aResult )
}
VIEW::VIEW( bool aIsDynamic ) :
m_enableOrderModifier( false ),
m_scale( 1.0 ),
m_painter( NULL ),
m_gal( NULL ),
m_dynamic( aIsDynamic )
{
}
VIEW::~VIEW()
{
BOOST_FOREACH( LayerMap::value_type& l, m_layers )
{
delete l.second.items;
}
}
VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
{
MATRIX3x3D matrix = m_gal->GetWorldScreenMatrix().Inverse();
......@@ -267,6 +270,11 @@ void VIEW::SetGAL( GAL* aGal )
// clear group numbers, so everything is going to be recached
clearGroupCache();
// every target has to be refreshed
SetTargetDirty( TARGET_CACHED );
SetTargetDirty( TARGET_NONCACHED );
SetTargetDirty( TARGET_OVERLAY );
// force the new GAL to display the current viewport.
SetCenter( m_center );
SetScale( m_scale );
......@@ -326,6 +334,10 @@ void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
SetCenter( m_center - delta );
m_scale = aScale;
// Redraw everything after the viewport has changed
SetTargetDirty( TARGET_CACHED );
SetTargetDirty( TARGET_NONCACHED );
}
......@@ -334,6 +346,10 @@ void VIEW::SetCenter( const VECTOR2D& aCenter )
m_center = aCenter;
m_gal->SetLookAtPoint( m_center );
m_gal->ComputeWorldScreenMatrix();
// Redraw everything after the viewport has changed
SetTargetDirty( TARGET_CACHED );
SetTargetDirty( TARGET_NONCACHED );
}
......@@ -347,6 +363,8 @@ void VIEW::sortLayers()
m_orderedLayers[n++] = &i->second;
sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder );
SetTargetDirty( TARGET_CACHED );
}
......@@ -554,15 +572,15 @@ void VIEW::redrawRect( const BOX2I& aRect )
{
BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers )
{
if( l->enabled && areRequiredLayersEnabled( l->id ) )
if( l->enabled && isTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
{
drawItem drawFunc( this, l );
m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder );
l->items->Query( aRect, drawFunc );
l->isDirty = false;
}
l->isDirty = false;
}
}
......@@ -648,9 +666,27 @@ void VIEW::Redraw()
VECTOR2D screenSize = m_gal->GetScreenPixelSize();
BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ),
ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
rect.Normalize();
if( isTargetDirty( TARGET_CACHED ) || isTargetDirty( TARGET_NONCACHED ) )
{
// TARGET_CACHED and TARGET_NONCACHED have to be redrawn together, as they contain
// layers that rely on each other (eg. netnames are noncached, but tracks - are cached)
m_gal->ClearTarget( TARGET_NONCACHED );
m_gal->ClearTarget( TARGET_CACHED );
SetTargetDirty( TARGET_NONCACHED );
SetTargetDirty( TARGET_CACHED );
m_gal->DrawGrid();
}
m_gal->ClearTarget( TARGET_OVERLAY );
redrawRect( rect );
// All targets were redrawn, so nothing is dirty
SetTargetDirty( TARGET_CACHED, false );
SetTargetDirty( TARGET_NONCACHED, false );
}
......@@ -801,3 +837,19 @@ void VIEW::RecacheAllItems( bool aImmediately )
wxLogDebug( wxT( "RecacheAllItems::%.1f ms" ), (double) totalRealTime.value / 1000.0 );
#endif /* __WXDEBUG__ */
}
bool VIEW::isTargetDirty( int aTarget ) const
{
wxASSERT( aTarget < TARGETS_NUMBER );
// Check if any of layers belonging to the target is dirty
BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers )
{
if( l->target == aTarget && l->isDirty )
return true;
}
// If no layer is dirty, just check the target status itself
return m_dirtyTargets[aTarget];
}
......@@ -50,8 +50,14 @@ public:
/// @copydoc COMPOSITOR::Resize()
virtual void Resize( unsigned int aWidth, unsigned int aHeight );
/// @copydoc COMPOSITOR::CreateBuffer()
virtual unsigned int CreateBuffer();
/// @copydoc COMPOSITOR::GetBuffer()
virtual unsigned int GetBuffer();
inline virtual unsigned int GetBuffer() const
{
return m_current + 1;
}
/// @copydoc COMPOSITOR::SetBuffer()
virtual void SetBuffer( unsigned int aBufferHandle );
......@@ -62,6 +68,21 @@ public:
/// @copydoc COMPOSITOR::DrawBuffer()
virtual void DrawBuffer( unsigned int aBufferHandle );
/**
* Function SetMainContext()
* Sets a context to be treated as the main context (ie. as a target of buffers rendering and
* as a source of settings for newly created buffers).
*
* @param aMainContext is the context that should be treated as the main one.
*/
inline virtual void SetMainContext( cairo_t* aMainContext )
{
m_mainContext = aMainContext;
// Use the context's transformation matrix
cairo_get_matrix( m_mainContext, &m_matrix );
}
protected:
typedef boost::shared_array<unsigned int> BitmapPtr;
typedef struct
......@@ -71,7 +92,7 @@ protected:
BitmapPtr bitmap; ///< Pixel storage
} CAIRO_BUFFER;
unsigned int m_current; ///< Currently used buffer handle
unsigned int m_current; ///< Currently used buffer handle
typedef std::deque<CAIRO_BUFFER> CAIRO_BUFFERS;
/// Pointer to the current context, so it can be changed
......
......@@ -221,6 +221,9 @@ public:
/// @copydoc GAL::GetTarget()
virtual RenderTarget GetTarget() const;
/// @copydoc GAL::ClearTarget()
virtual void ClearTarget( RenderTarget aTarget );
// -------
// Cursor
// -------
......@@ -267,6 +270,7 @@ private:
unsigned int mainBuffer; ///< Handle to the main buffer
unsigned int overlayBuffer; ///< Handle to the overlay buffer
RenderTarget currentTarget; ///< Current rendering target
bool validCompositor; ///< Compositor initialization flag
// Variables related to wxWidgets
wxWindow* parentWindow; ///< Parent window
......
......@@ -57,12 +57,20 @@ public:
virtual void Resize( unsigned int aWidth, unsigned int aHeight ) = 0;
/**
* Function GetBuffer()
* Function CreateBuffer()
* prepares a new buffer that may be used as a rendering target.
*
* @return is the handle of the buffer. In case of failure 0 (zero) is returned as the handle.
*/
virtual unsigned int GetBuffer() = 0;
virtual unsigned int CreateBuffer() = 0;
/**
* Function GetBuffer()
* returns currently used buffer handle.
*
* @return Currently used buffer handle.
*/
virtual unsigned int GetBuffer() const = 0;
/**
* Function SetBuffer()
......
......@@ -42,6 +42,9 @@ namespace KiGfx
TARGET_NONCACHED, ///< Auxiliary rendering target (noncached)
TARGET_OVERLAY ///< Items that may change while the view stays the same (noncached)
};
/// Number of available rendering targets
static const int TARGETS_NUMBER = 3;
}
#endif /* DEFINITIONS_H_ */
......@@ -579,6 +579,13 @@ public:
*/
virtual RenderTarget GetTarget() const = 0;
/**
* @brief Clears the target for rendering.
*
* @param aTarget is the target to be cleared.
*/
virtual void ClearTarget( RenderTarget aTarget ) = 0;
// -------------
// Grid methods
// -------------
......
......@@ -49,18 +49,30 @@ public:
/// @copydoc COMPOSITOR::Resize()
virtual void Resize( unsigned int aWidth, unsigned int aHeight );
/// @copydoc COMPOSITOR::GetBuffer()
virtual unsigned int GetBuffer();
/// @copydoc COMPOSITOR::CreateBuffer()
virtual unsigned int CreateBuffer();
/// @copydoc COMPOSITOR::SetBuffer()
virtual void SetBuffer( unsigned int aBufferHandle );
/// @copydoc COMPOSITOR::GetBuffer()
inline virtual unsigned int GetBuffer() const
{
if( m_currentFbo == DIRECT_RENDERING )
return DIRECT_RENDERING;
return m_current + 1;
}
/// @copydoc COMPOSITOR::ClearBuffer()
virtual void ClearBuffer();
/// @copydoc COMPOSITOR::DrawBuffer()
virtual void DrawBuffer( unsigned int aBufferHandle );
// Constant used by glBindFramebuffer to turn off rendering to framebuffers
static const unsigned int DIRECT_RENDERING = 0;
protected:
typedef struct
{
......
......@@ -214,6 +214,9 @@ public:
/// @copydoc GAL::GetTarget()
virtual RenderTarget GetTarget() const;
/// @copydoc GAL::ClearTarget()
virtual void ClearTarget( RenderTarget aTarget );
// -------
// Cursor
// -------
......
......@@ -392,6 +392,20 @@ public:
*/
bool IsDirty() const;
/**
* Function SetTargetDirty()
* Sets or clears target 'dirty' flag.
* @param aTarget is the target to set.
* @param aState says if the flag should be set or cleared.
*/
inline void SetTargetDirty( int aTarget, bool aState = true )
{
wxASSERT( aTarget < TARGETS_NUMBER );
m_dirtyTargets[aTarget] = aState;
}
static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown
private:
......@@ -462,6 +476,14 @@ private:
return ( m_layers.at( aLayer ).target == TARGET_CACHED );
}
/**
* Function isTargetDirty()
* Returns true if any of layers belonging to the target or the target itself should be
* redrawn.
* @return True if the above condition is fulfilled.
*/
bool isTargetDirty( int aTarget ) const;
/// Contains set of possible displayed layers and its properties
LayerMap m_layers;
......@@ -487,6 +509,9 @@ private:
/// static (eg. image/PDF) - does not.
bool m_dynamic;
/// Flags to mark targets as dirty, so they have to be redrawn on the next refresh event
bool m_dirtyTargets[TARGETS_NUMBER];
/// Rendering order modifier for layers that are marked as top layers
static const int TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment