diff options
author | Michael Meeks <michael.meeks@suse.com> | 2012-02-25 14:13:08 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2012-02-25 14:17:57 +0000 |
commit | 9ab611a652334a98ba7922ee6a53b61bbcc4892f (patch) | |
tree | b12763802820f501f85148b19748538e54227e84 | |
parent | 7e454a3e3dc7f7f85a623ab6a7afab6f40bccaa6 (diff) |
android: move DamageTracker concept into SvpSalFrame and try to use it
-rw-r--r-- | vcl/android/androidinst.cxx | 89 | ||||
-rw-r--r-- | vcl/headless/svpframe.cxx | 39 | ||||
-rw-r--r-- | vcl/headless/svpinst.cxx | 5 | ||||
-rw-r--r-- | vcl/inc/android/androidinst.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/headless/svpframe.hxx | 11 | ||||
-rw-r--r-- | vcl/inc/unx/gtk/gtkframe.hxx | 2 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtkframe.cxx | 4 |
7 files changed, 136 insertions, 19 deletions
diff --git a/vcl/android/androidinst.cxx b/vcl/android/androidinst.cxx index 94d5bbcea706..af78a22d5841 100644 --- a/vcl/android/androidinst.cxx +++ b/vcl/android/androidinst.cxx @@ -35,6 +35,7 @@ #include <osl/detail/android-bootstrap.h> #include <osl/detail/android_native_app_glue.h> #include <rtl/strbuf.hxx> +#include <basebmp/scanlineformats.hxx> extern void VCL_DLLPUBLIC plasma_now(const char *msg); @@ -203,7 +204,7 @@ static void BlitFrameRegionToWindow(ANativeWindow_Buffer *pOutBuffer, const ARect &rSrcRect, int nDestX, int nDestY) { - fprintf (stderr, "Blit frame #2 src %d,%d->%d,%d to position %d, %d\n", + fprintf (stderr, "Blit frame src %d,%d->%d,%d to position %d, %d\n", rSrcRect.left, rSrcRect.top, rSrcRect.right, rSrcRect.bottom, nDestX, nDestY); @@ -215,11 +216,10 @@ static void BlitFrameRegionToWindow(ANativeWindow_Buffer *pOutBuffer, // FIXME: do some cropping goodness on aSrcRect to ensure no overflows etc. ARect aSrcRect = rSrcRect; - // FIXME: we have WINDOW_FORMAT_RGB_565 = 4 ... - + // FIXME: by default we have WINDOW_FORMAT_RGB_565 = 4 ... for (unsigned int y = 0; y < (unsigned int)(aSrcRect.bottom - aSrcRect.top); y++) { - unsigned char *sp = ( pSrc + nStride * (aSrcRect.bottom - aSrcRect.top - y - 1) + + unsigned char *sp = ( pSrc + nStride * (aSrcRect.top + y) + aSrcRect.left * 3 /* src pixel size */ ); switch (pOutBuffer->format) { @@ -258,7 +258,6 @@ static void BlitFrameRegionToWindow(ANativeWindow_Buffer *pOutBuffer, break; } } - fprintf (stderr, "done blit!\n"); } void AndroidSalInstance::BlitFrameToWindow(ANativeWindow_Buffer *pOutBuffer, @@ -288,7 +287,7 @@ void AndroidSalInstance::RedrawWindows(ANativeWindow *pWindow) if (aOutBuffer.bits != NULL) { -#if 1 // pre-'clean' the buffer with cruft: +#if 0 // pre-'clean' the buffer with cruft: // hard-code / guess at a format ... int32_t *p = (int32_t *)aOutBuffer.bits; for (int32_t y = 0; y < aOutBuffer.height; y++) @@ -296,18 +295,42 @@ void AndroidSalInstance::RedrawWindows(ANativeWindow *pWindow) for (int32_t x = 0; x < aOutBuffer.stride; x++) *p++ = (y << 24) + (x << 10) + 0xff ; } -#endif +#endif + int i = 0; std::list< SalFrame* >::const_iterator it; - for ( it = getFrames().begin(); it != getFrames().end(); it++ ) + for ( it = getFrames().begin(); it != getFrames().end(); i++, it++ ) { SvpSalFrame *pFrame = static_cast<SvpSalFrame *>(*it); if (pFrame->IsVisible()) { - // FIXME: force a re-draw - this appears not to happen much otherwis - pFrame->PostPaint(true); + fprintf( stderr, "render visible frame %d\n", i ); +#ifndef REGION_RE_RENDER BlitFrameToWindow (&aOutBuffer, pFrame->getDevice()); +#else + // Sadly it seems that due to double buffering, we don't + // get back in our buffer what we had there last time - so we cannot + // do incremental rendering. Presumably this will require us to + // render to a bitmap, and keep that updated instead in future. + + // Intersect re-rendering region with this frame + Region aClipped( maRedrawRegion ); + basegfx::B2IVector aDevSize = pFrame->getDevice()->getSize(); + aClipped.Intersect( Rectangle( 0, 0, aDevSize.getX(), aDevSize.getY() ) ); + + Rectangle aSubRect; + RegionHandle aHdl = aClipped.BeginEnumRects(); + while( aClipped.GetNextEnumRect( aHdl, aSubRect ) ) + { + ARect aASubRect = { aSubRect.Left(), aSubRect.Top(), + aSubRect.Right(), aSubRect.Bottom() }; + BlitFrameRegionToWindow(&aOutBuffer, pFrame->getDevice(), + aASubRect, + aSubRect.Left(), aSubRect.Top()); + } + aClipped.EndEnumRects( aHdl ); +#endif } } } @@ -316,9 +339,17 @@ void AndroidSalInstance::RedrawWindows(ANativeWindow *pWindow) ANativeWindow_unlockAndPost(pWindow); fprintf (stderr, "done render!\n"); + maRedrawRegion.SetEmpty(); mbQueueReDraw = false; } +void AndroidSalInstance::damaged(AndroidSalFrame */* frame */, const Rectangle &rRect) +{ + // FIXME: translate rRect to the frame's offset ... + maRedrawRegion.Union( rRect ); + mbQueueReDraw = true; +} + static const char *app_cmd_name(int cmd) { switch (cmd) { @@ -374,6 +405,9 @@ void AndroidSalInstance::onAppCmd (struct android_app* app, int32_t cmd) fprintf (stderr, "we have an app window ! %p %dx%x (%d) set %d\n", pWindow, aRect.right, aRect.bottom, ANativeWindow_getFormat(pWindow), nRet); + maRedrawRegion = Region( Rectangle( 0, 0, ANativeWindow_getWidth(pWindow), + ANativeWindow_getHeight(pWindow) ) ); + mbQueueReDraw = true; break; } case APP_CMD_WINDOW_RESIZED: @@ -390,6 +424,8 @@ void AndroidSalInstance::onAppCmd (struct android_app* app, int32_t cmd) case APP_CMD_WINDOW_REDRAW_NEEDED: { fprintf (stderr, "redraw needed\n"); + maRedrawRegion = Region( Rectangle( 0, 0, ANativeWindow_getWidth(pWindow), + ANativeWindow_getHeight(pWindow) ) ); mbQueueReDraw = true; break; } @@ -462,9 +498,6 @@ int32_t AndroidSalInstance::onInputEvent (struct android_app* app, AInputEvent* fprintf (stderr, "no focused frame to emit event on\n"); fprintf( stderr, "bHandled == %s\n", bHandled? "true": "false" ); - - // FIXME: queueing full re-draw on key events ... - mbQueueReDraw = true; break; } case AINPUT_EVENT_TYPE_MOTION: @@ -634,8 +667,11 @@ public: SalFrame *pParent, sal_uLong nSalFrameStyle, SystemParentData *pSysParent ) - : SvpSalFrame( pInstance, pParent, nSalFrameStyle, pSysParent ) + : SvpSalFrame( pInstance, pParent, nSalFrameStyle, + true, basebmp::Format::TWENTYFOUR_BIT_TC_MASK, + pSysParent ) { + enableDamageTracker(); } virtual void GetWorkArea( Rectangle& rRect ) @@ -643,6 +679,31 @@ public: AndroidSalInstance::getInstance()->GetWorkArea( rRect ); } + virtual void damaged( const basegfx::B2IBox& rDamageRect) + { + long long area = rDamageRect.getWidth() * rDamageRect.getHeight(); +// if( area > 32 * 1024 ) + fprintf( stderr, "bitmap damaged %d %d (%dx%d) area %lld\n", + (int) rDamageRect.getMinX(), + (int) rDamageRect.getMinY(), + (int) rDamageRect.getWidth(), + (int) rDamageRect.getHeight(), + area ); + if (rDamageRect.getWidth() <= 0 || + rDamageRect.getHeight() <= 0) + { + fprintf (stderr, "ERROR: damage region has tiny / negative size\n"); + return; + } + Rectangle aRect( std::max((long) 0, (long) rDamageRect.getMinX() ), + std::max((long) 0, (long) rDamageRect.getMinY() ), + std::max((long) 0, (long) ( rDamageRect.getMinX() + + rDamageRect.getWidth() ) ), + std::max((long) 0, (long) ( rDamageRect.getMinY() + + rDamageRect.getHeight() ) ) ); + AndroidSalInstance::getInstance()->damaged( this, aRect ); + } + virtual void UpdateSettings( AllSettings &rSettings ) { // Clobber the UI fonts diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx index ae5614226022..45c9dadcd61a 100644 --- a/vcl/headless/svpframe.cxx +++ b/vcl/headless/svpframe.cxx @@ -31,6 +31,7 @@ #include "headless/svpinst.hxx" #include "headless/svpgdi.hxx" +#include <basebmp/bitmapdevice.hxx> #include <basebmp/scanlineformats.hxx> #include <basegfx/vector/b2ivector.hxx> @@ -39,14 +40,47 @@ using namespace basegfx; SvpSalFrame* SvpSalFrame::s_pFocusFrame = NULL; +namespace { + /// Decouple SalFrame lifetime from damagetracker lifetime + struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker + { + DamageTracker( SvpSalFrame& rFrame ) : m_rFrame( rFrame ) {} + virtual void damaged( const basegfx::B2IBox& rDamageRect ) const + { + m_rFrame.damaged( rDamageRect ); + } + SvpSalFrame& m_rFrame; + }; +} + +void SvpSalFrame::enableDamageTracker( bool bOn ) +{ + if( m_bDamageTracking == bOn ) + return; + if( m_aFrame.get() ) + { + if( m_bDamageTracking ) + m_aFrame->setDamageTracker( basebmp::IBitmapDeviceDamageTrackerSharedPtr() ); + else + m_aFrame->setDamageTracker( + basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker( *this ) ) ); + } + m_bDamageTracking = bOn; +} + SvpSalFrame::SvpSalFrame( SvpSalInstance* pInstance, SalFrame* pParent, sal_uLong nSalFrameStyle, + bool bTopDown, + sal_Int32 nScanlineFormat, SystemParentData* ) : m_pInstance( pInstance ), m_pParent( static_cast<SvpSalFrame*>(pParent) ), m_nStyle( nSalFrameStyle ), m_bVisible( false ), + m_bDamageTracking( false ), + m_bTopDown( bTopDown ), + m_nScanlineFormat( nScanlineFormat ), m_nMinWidth( 0 ), m_nMinHeight( 0 ), m_nMaxWidth( 0 ), @@ -242,7 +276,10 @@ void SvpSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u aFrameSize.setX( 1 ); if( aFrameSize.getY() == 0 ) aFrameSize.setY( 1 ); - m_aFrame = createBitmapDevice( aFrameSize, false, SVP_DEFAULT_BITMAP_FORMAT ); + m_aFrame = createBitmapDevice( aFrameSize, m_bTopDown, m_nScanlineFormat ); + if (m_bDamageTracking) + m_aFrame->setDamageTracker( + basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker( *this ) ) ); // update device in existing graphics for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin(); it != m_aGraphics.end(); ++it ) diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx index 91bbff33de92..f0557f1cd468 100644 --- a/vcl/headless/svpinst.cxx +++ b/vcl/headless/svpinst.cxx @@ -44,6 +44,7 @@ #include <salframe.hxx> #include <svdata.hxx> #include <generic/gendata.hxx> +#include <basebmp/scanlineformats.hxx> #include <vcl/solarmutex.hxx> // FIXME: remove when we re-work the svp mainloop #include <unx/salunxtime.h> @@ -182,12 +183,12 @@ bool SvpSalInstance::CheckTimeout( bool bExecuteTimers ) SalFrame* SvpSalInstance::CreateChildFrame( SystemParentData* pParent, sal_uLong nStyle ) { - return new SvpSalFrame( this, NULL, nStyle, pParent ); + return new SvpSalFrame( this, NULL, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT, pParent ); } SalFrame* SvpSalInstance::CreateFrame( SalFrame* pParent, sal_uLong nStyle ) { - return new SvpSalFrame( this, pParent, nStyle ); + return new SvpSalFrame( this, pParent, nStyle, false, SVP_DEFAULT_BITMAP_FORMAT ); } void SvpSalInstance::DestroyFrame( SalFrame* pFrame ) diff --git a/vcl/inc/android/androidinst.hxx b/vcl/inc/android/androidinst.hxx index 10d17c53b8b5..9f8d22f98645 100644 --- a/vcl/inc/android/androidinst.hxx +++ b/vcl/inc/android/androidinst.hxx @@ -38,6 +38,7 @@ #include <headless/svpinst.hxx> #include <headless/svpframe.hxx> +class AndroidSalFrame; class AndroidSalInstance : public SvpSalInstance { void BlitFrameToWindow(ANativeWindow_Buffer *pOutBuffer, @@ -64,10 +65,12 @@ public: void RedrawWindows(ANativeWindow *pWindow); SalFrame *getFocusFrame() const; + void damaged(AndroidSalFrame *frame, const Rectangle &rRect); protected: virtual void DoReleaseYield( int nTimeoutMS ); struct android_app *mpApp; - bool mbQueueReDraw; + Region maRedrawRegion; + bool mbQueueReDraw; private: EGLDisplay mxDisplay; diff --git a/vcl/inc/headless/svpframe.hxx b/vcl/inc/headless/svpframe.hxx index 3dd896165b6e..ac8683fcf502 100644 --- a/vcl/inc/headless/svpframe.hxx +++ b/vcl/inc/headless/svpframe.hxx @@ -29,6 +29,7 @@ #ifndef _SVP_SVPFRAME_HXX #include <vcl/sysdata.hxx> +#include <basegfx/range/b2ibox.hxx> #include <salframe.hxx> #include "svpelement.hxx" @@ -45,6 +46,9 @@ class SvpSalFrame : public SalFrame, public SvpElement std::list< SvpSalFrame* > m_aChildren; // List of child frames sal_uLong m_nStyle; bool m_bVisible; + bool m_bDamageTracking; + bool m_bTopDown; + sal_Int32 m_nScanlineFormat; long m_nMinWidth; long m_nMinHeight; long m_nMaxWidth; @@ -60,12 +64,15 @@ public: SvpSalFrame( SvpSalInstance* pInstance, SalFrame* pParent, sal_uLong nSalFrameStyle, + bool bTopDown, + sal_Int32 nScanlineFormat, SystemParentData* pSystemParent = NULL ); virtual ~SvpSalFrame(); void GetFocus(); void LoseFocus(); void PostPaint(bool bImmediate) const; + void AllocateFrame(); // SvpElement virtual const basebmp::BitmapDeviceSharedPtr& getDevice() const { return m_aFrame; } @@ -121,6 +128,10 @@ public: virtual void UnionClipRegion( long nX, long nY, long nWidth, long nHeight ); virtual void EndSetClipRegion(); + // If enabled we can get damage notifications for regions immediately rendered to ... + virtual void enableDamageTracker( bool bOn = true ); + virtual void damaged( const basegfx::B2IBox& /* rDamageRect */) {} + /*TODO: functional implementation */ virtual void SetScreenNumber( unsigned int nScreen ) { (void)nScreen; } virtual void SetApplicationID(const rtl::OUString &rApplicationID) { (void) rApplicationID; } diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index e5fd0cf5660a..50258e0b42ec 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -432,7 +432,7 @@ public: static GtkSalFrame *getFromWindow( GtkWindow *pWindow ); - virtual void damaged (const basegfx::B2IBox& rDamageRect); + virtual void damaged (const basegfx::B2IBox& rDamageRect); }; #define OOO_TYPE_FIXED ooo_fixed_get_type() diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index 7384a735569b..112e066d8e76 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -345,6 +345,7 @@ GetAlternateKeyCode( const sal_uInt16 nKeyCode ) static int debugQueuePureRedraw = 0; static int debugRedboxRedraws = 0; +namespace { /// Decouple SalFrame lifetime from damagetracker lifetime struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker { @@ -357,6 +358,7 @@ struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker GtkSalFrame& m_rFrame; }; +} #endif void GtkSalFrame::doKeyCallback( guint state, @@ -1572,6 +1574,8 @@ void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) } } +// FIXME: we should really be an SvpSalFrame sub-class, and +// share their AllocateFrame ! void GtkSalFrame::AllocateFrame() { #if GTK_CHECK_VERSION(3,0,0) |