fdo#30519 paint scrolled area from the right surface

This adds a way to test whether mpCompositeSurface contains the front
buffer image, so it can be used as a source in painting operations.
It means the mpCompositeSurface changed status from 'temporary' to
'persistent' (which it was anyway, from implementation POV :-)

Change-Id: Iee4fc7a97cd60e47d0abb148e7337f0b50cabb40
This commit is contained in:
David Tardon 2012-06-16 16:31:28 +02:00
parent 990586bd5b
commit 012b43d571
2 changed files with 53 additions and 15 deletions

View File

@ -144,7 +144,8 @@ namespace cairocanvas
mpRedrawManager( NULL ),
mpOwningSpriteCanvas( NULL ),
mpCompositingSurface(),
maCompositingSurfaceSize()
maCompositingSurfaceSize(),
mbCompositingSurfaceDirty(true)
{
}
@ -222,7 +223,7 @@ namespace cairocanvas
// TODO(P1): Might be worthwile to track areas of background
// changes, too.
if( !bUpdateAll && !io_bSurfaceDirty )
if( !bUpdateAll && !io_bSurfaceDirty && !mbCompositingSurfaceDirty )
{
// background has not changed, so we're free to optimize
// repaint to areas where a sprite has changed
@ -270,6 +271,7 @@ namespace cairocanvas
// rendering and sprite changing
mpRedrawManager->clearChangeRecords();
mbCompositingSurfaceDirty = false;
io_bSurfaceDirty = false;
// commit to screen
@ -351,16 +353,33 @@ namespace cairocanvas
::basegfx::B2IRange aDestRect( rDestRect );
aDestRect.intersect( aOutputBounds );
cairo_save( pCompositingCairo.get() );
// scroll content in device back buffer
cairo_set_source_surface( pCompositingCairo.get(),
mpOwningSpriteCanvas->getBufferSurface()->getCairoSurface().get(),
::basegfx::B2ISize aScrollSize( aDestRect.getWidth(), aDestRect.getHeight() );
SurfaceSharedPtr pScrollSurface( getTemporarySurface() );
CairoSharedPtr pScrollCairo( pScrollSurface->getCairo() );
cairo_save( pScrollCairo.get() );
// scroll the current content of the compositing surface (and,
// thus, of the window) in temp. surface
cairo_set_source_surface( pScrollCairo.get(),
pCompositingSurface->getCairoSurface().get(),
aDestPos.getX() - aSourceUpperLeftPos.getX(),
aDestPos.getY() - aSourceUpperLeftPos.getY() );
cairo_rectangle( pScrollCairo.get(),
aDestPos.getX(), aDestPos.getY(),
aScrollSize.getX(), aScrollSize.getY() );
cairo_clip( pScrollCairo.get() );
cairo_set_operator( pScrollCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_paint( pScrollCairo.get() );
cairo_restore( pScrollCairo.get() );
cairo_save( pCompositingCairo.get() );
// copy the scrolled area back onto the compositing surface
cairo_set_source_surface( pCompositingCairo.get(),
pScrollSurface->getCairoSurface().get(),
0, 0 );
cairo_rectangle( pCompositingCairo.get(),
aDestPos.getX(), aDestPos.getY(),
sal::static_int_cast<sal_Int32>(aDestRect.getWidth()),
sal::static_int_cast<sal_Int32>(aDestRect.getHeight()) );
aScrollSize.getX(), aScrollSize.getY() );
cairo_clip( pCompositingCairo.get() );
cairo_set_operator( pCompositingCairo.get(), CAIRO_OPERATOR_SOURCE );
cairo_paint( pCompositingCairo.get() );
@ -530,15 +549,28 @@ namespace cairocanvas
if( !mpCompositingSurface )
{
mpCompositingSurface =
mpOwningSpriteCanvas->getWindowSurface()->getSimilar(
CAIRO_CONTENT_COLOR,
rNeededSize.getX(), rNeededSize.getY() );
mpCompositingSurface = createSurface( rNeededSize );
maCompositingSurfaceSize = rNeededSize;
mbCompositingSurfaceDirty = true;
mpTemporarySurface.reset();
}
return mpCompositingSurface;
}
::cairo::SurfaceSharedPtr SpriteCanvasHelper::getTemporarySurface()
{
if ( !mpTemporarySurface )
mpTemporarySurface = createSurface( maCompositingSurfaceSize );
return mpTemporarySurface;
}
::cairo::SurfaceSharedPtr SpriteCanvasHelper::createSurface( const ::basegfx::B2ISize& rNeededSize ) const
{
return mpOwningSpriteCanvas->getWindowSurface()->getSimilar(
CAIRO_CONTENT_COLOR,
rNeededSize.getX(), rNeededSize.getY() );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -131,6 +131,8 @@ namespace cairocanvas
private:
::cairo::SurfaceSharedPtr getCompositingSurface( const ::basegfx::B2ISize& rNeededSize );
::cairo::SurfaceSharedPtr getTemporarySurface();
::cairo::SurfaceSharedPtr createSurface( const ::basegfx::B2ISize& rNeededSize ) const;
/// Set from the SpriteCanvas: instance coordinating sprite redraw
::canvas::SpriteRedrawManager* mpRedrawManager;
@ -138,9 +140,13 @@ namespace cairocanvas
/// Set from the init method. used to generate sprites
SpriteCanvas* mpOwningSpriteCanvas;
/// a temporary surface used to composite the frontbuffer image
::cairo::SurfaceSharedPtr mpCompositingSurface;
::basegfx::B2ISize maCompositingSurfaceSize;
/// a surface used to composite the frontbuffer image
::cairo::SurfaceSharedPtr mpCompositingSurface;
::basegfx::B2ISize maCompositingSurfaceSize;
bool mbCompositingSurfaceDirty;
/// a temporary surface that is guaranteed to be the same size
//as the compositing surface
::cairo::SurfaceSharedPtr mpTemporarySurface;
};
}