summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2012-02-25 14:13:08 +0000
committerMichael Meeks <michael.meeks@suse.com>2012-02-25 14:17:57 +0000
commit9ab611a652334a98ba7922ee6a53b61bbcc4892f (patch)
treeb12763802820f501f85148b19748538e54227e84
parent7e454a3e3dc7f7f85a623ab6a7afab6f40bccaa6 (diff)
android: move DamageTracker concept into SvpSalFrame and try to use it
-rw-r--r--vcl/android/androidinst.cxx89
-rw-r--r--vcl/headless/svpframe.cxx39
-rw-r--r--vcl/headless/svpinst.cxx5
-rw-r--r--vcl/inc/android/androidinst.hxx5
-rw-r--r--vcl/inc/headless/svpframe.hxx11
-rw-r--r--vcl/inc/unx/gtk/gtkframe.hxx2
-rw-r--r--vcl/unx/gtk/window/gtkframe.cxx4
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)