[Libreoffice-commits] .: vcl/android vcl/headless vcl/inc vcl/unx

Michael Meeks michael at kemper.freedesktop.org
Sat Feb 25 06:17:02 PST 2012


 vcl/android/androidinst.cxx     |   89 +++++++++++++++++++++++++++++++++-------
 vcl/headless/svpframe.cxx       |   39 +++++++++++++++++
 vcl/headless/svpinst.cxx        |    5 +-
 vcl/inc/android/androidinst.hxx |    5 +-
 vcl/inc/headless/svpframe.hxx   |   11 ++++
 vcl/inc/unx/gtk/gtkframe.hxx    |    2 
 vcl/unx/gtk/window/gtkframe.cxx |    4 +
 7 files changed, 136 insertions(+), 19 deletions(-)

New commits:
commit 9ab611a652334a98ba7922ee6a53b61bbcc4892f
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Sat Feb 25 14:13:08 2012 +0000

    android: move DamageTracker concept into SvpSalFrame and try to use it

diff --git a/vcl/android/androidinst.cxx b/vcl/android/androidinst.cxx
index 94d5bbc..af78a22 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 ae56142..45c9dad 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 91bbff3..f0557f1 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 10d17c5..9f8d22f 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 3dd8961..ac8683f 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 e5fd0cf..50258e0 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 7384a73..112e066 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)


More information about the Libreoffice-commits mailing list