diff options
author | David Tardon <dtardon@redhat.com> | 2012-06-16 16:31:28 +0200 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2012-06-18 10:55:31 +0200 |
commit | 012b43d571aaa4f79b7f6fcfa92939e8d19af492 (patch) | |
tree | 478cfb6d89cac060635972f9d0d9554bb7321bf3 | |
parent | 990586bd5bca08ffb868f5473050b31519ed5f9d (diff) |
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
-rw-r--r-- | canvas/source/cairo/cairo_spritecanvashelper.cxx | 56 | ||||
-rw-r--r-- | canvas/source/cairo/cairo_spritecanvashelper.hxx | 12 |
2 files changed, 53 insertions, 15 deletions
diff --git a/canvas/source/cairo/cairo_spritecanvashelper.cxx b/canvas/source/cairo/cairo_spritecanvashelper.cxx index e3d7969728f9..4af8dc66cc1f 100644 --- a/canvas/source/cairo/cairo_spritecanvashelper.cxx +++ b/canvas/source/cairo/cairo_spritecanvashelper.cxx @@ -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: */ diff --git a/canvas/source/cairo/cairo_spritecanvashelper.hxx b/canvas/source/cairo/cairo_spritecanvashelper.hxx index 8e3e60901302..e3de50392bf4 100644 --- a/canvas/source/cairo/cairo_spritecanvashelper.hxx +++ b/canvas/source/cairo/cairo_spritecanvashelper.hxx @@ -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; }; } |