[Libreoffice-commits] core.git: Branch 'libreoffice-5-0' - include/vcl vcl/inc vcl/opengl vcl/unx

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Fri Aug 7 02:33:57 PDT 2015


 include/vcl/salnativewidgets.hxx         |   42 +++++++++++++++
 vcl/inc/opengl/x11/gdiimpl.hxx           |   11 +++-
 vcl/inc/unx/salgdi.h                     |    6 ++
 vcl/inc/unx/x11/x11gdiimpl.h             |    6 ++
 vcl/opengl/x11/gdiimpl.cxx               |   84 ++++++++++++++++++++++++++-----
 vcl/unx/generic/gdi/gdiimpl.cxx          |   11 ++++
 vcl/unx/generic/gdi/gdiimpl.hxx          |    5 +
 vcl/unx/generic/gdi/salgdi2.cxx          |   15 +++++
 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx |   23 +++++---
 9 files changed, 182 insertions(+), 21 deletions(-)

New commits:
commit b4faa69e4a9a99cdd12b7999d95459b1a8639e9f
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Jul 23 19:15:20 2015 +0900

    tdf#92018 cache native controls for X11 OpenGL backend (for now)
    
    Change-Id: I85c7cc01113bc4ac810c450a6460059463cc8e03
    (cherry picked from commit 450727fdffa4a0dc3b2d4e635a5c1bc0411b3c36)
    Reviewed-on: https://gerrit.libreoffice.org/17554
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/include/vcl/salnativewidgets.hxx b/include/vcl/salnativewidgets.hxx
index 66bc744..9692a80 100644
--- a/include/vcl/salnativewidgets.hxx
+++ b/include/vcl/salnativewidgets.hxx
@@ -25,6 +25,8 @@
 #include <tools/gen.hxx>
 #include <o3tl/typed_flags_set.hxx>
 
+#include <boost/functional/hash.hpp>
+
 /* Control Types:
  *
  *   Specify the overall, whole control
@@ -254,6 +256,46 @@ namespace o3tl
     template<> struct typed_flags<ControlState> : is_typed_flags<ControlState, 0xc007f> {};
 }
 
+class ControlCacheKey
+{
+public:
+    ControlType mnType;
+    ControlPart mnPart;
+    ControlState mnState;
+    Size maSize;
+
+    ControlCacheKey(ControlType nType, ControlPart nPart, ControlState nState, const Size& rSize)
+        : mnType(nType)
+        , mnPart(nPart)
+        , mnState(nState)
+        , maSize(rSize)
+    {}
+
+    bool operator==(ControlCacheKey const& aOther) const
+    {
+        return mnType == aOther.mnType
+            && mnPart == aOther.mnPart
+            && mnState == aOther.mnState
+            && maSize.Width() == aOther.maSize.Width()
+            && maSize.Height() == aOther.maSize.Height();
+    }
+};
+
+struct ControlCacheHashFunction
+{
+    std::size_t operator()(ControlCacheKey const& aCache) const
+    {
+        std::size_t seed = 0;
+        boost::hash_combine(seed, aCache.mnType);
+        boost::hash_combine(seed, aCache.mnPart);
+        boost::hash_combine(seed, aCache.mnState);
+        boost::hash_combine(seed, aCache.maSize.Width());
+        boost::hash_combine(seed, aCache.maSize.Height());
+        return seed;
+    }
+};
+
+
 /* ButtonValue:
  *
  *   Identifies the tri-state value options
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index feb3961..9e2ece3 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -16,6 +16,8 @@
 #include "unx/x11/x11gdiimpl.h"
 #include "openglgdiimpl.hxx"
 
+class TextureCombo;
+
 class VCL_PLUGIN_PUBLIC X11OpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public X11GraphicsImpl
 {
 private:
@@ -29,6 +31,8 @@ protected:
     virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
     virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE;
 
+    bool RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY, TextureCombo& rCombo);
+
 public:
     // implementation of X11GraphicsImpl
 
@@ -37,7 +41,12 @@ public:
     virtual void Init() SAL_OVERRIDE;
 
     bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
-    bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY ) SAL_OVERRIDE;
+    bool RenderPixmapToScreen(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY) SAL_OVERRIDE;
+
+    bool RenderAndCacheNativeControl(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY,
+                                     ControlCacheKey& aControlCacheKey) SAL_OVERRIDE;
+    bool TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey,
+                                      int nX, int nY) SAL_OVERRIDE;
 };
 
 #endif // INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 0a0d0d3..a44ef1e 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -272,6 +272,12 @@ public:
     virtual void                    BeginPaint() SAL_OVERRIDE;
     virtual void                    EndPaint() SAL_OVERRIDE;
 
+    bool TryRenderCachedNativeControl(ControlCacheKey& aControlCacheKey,
+                                      int nX, int nY);
+
+    bool RenderAndCacheNativeControl(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY,
+                                     ControlCacheKey& aControlCacheKey);
+
     // fill a pixmap from a screen region
     bool                            FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY );
 
diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h
index 22859c3..c504364 100644
--- a/vcl/inc/unx/x11/x11gdiimpl.h
+++ b/vcl/inc/unx/x11/x11gdiimpl.h
@@ -12,6 +12,8 @@
 
 #include "unx/pixmap.hxx"
 
+class ControlCacheKey;
+
 class X11GraphicsImpl
 {
 public:
@@ -19,6 +21,10 @@ public:
 
     virtual bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) = 0;
     virtual bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY ) = 0;
+
+    virtual bool TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey, int nX, int nY) = 0;
+    virtual bool RenderAndCacheNativeControl(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY,
+                                             ControlCacheKey& aControlCacheKey) = 0;
 };
 
 #endif // INCLUDED_VCL_INC_UNX_X11_X11GDIIMPL_HXX
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 1d453da..3890b64 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -111,18 +111,28 @@ bool X11OpenGLSalGraphicsImpl::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX,
     return true;
 }
 
-bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY )
+struct TextureCombo
+{
+    std::unique_ptr<OpenGLTexture> mpTexture;
+    std::unique_ptr<OpenGLTexture> mpMask;
+};
+
+typedef std::unordered_map<ControlCacheKey, std::unique_ptr<TextureCombo>, ControlCacheHashFunction> ControlCacheType;
+
+ControlCacheType gTextureCache;
+
+bool X11OpenGLSalGraphicsImpl::RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY, TextureCombo& rCombo)
 {
-    const int aAttribs[] = {
+    const int aAttribs[] =
+    {
         GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
         GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
         None
     };
+
     Display* pDisplay = mrParent.GetXDisplay();
     bool bInverted;
 
-    SAL_INFO( "vcl.opengl", "RenderPixmapToScreen (" << nX << " " << nY << ")" );
-
     const long nWidth = pPixmap->GetWidth();
     const long nHeight = pPixmap->GetHeight();
     SalTwoRect aPosAry(0, 0, nWidth, nHeight, nX, nY, nWidth, nHeight);
@@ -145,27 +155,28 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixm
 
     //TODO: lfrb: glXGetProc to get the functions
 
-    OpenGLTexture aTexture( pPixmap->GetWidth(), pPixmap->GetHeight(), false );
+    rCombo.mpTexture.reset(new OpenGLTexture(pPixmap->GetWidth(), pPixmap->GetHeight(), false));
+
     glActiveTexture( GL_TEXTURE0 );
-    aTexture.Bind();
+    rCombo.mpTexture->Bind();
     glXBindTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT, NULL );
-    aTexture.Unbind();
+    rCombo.mpTexture->Unbind();
 
     if( pMask != NULL && pGlxMask )
     {
-        OpenGLTexture aMaskTexture( pMask->GetWidth(), pMask->GetHeight(), false );
-        aMaskTexture.Bind();
+        rCombo.mpMask.reset(new OpenGLTexture(pPixmap->GetWidth(), pPixmap->GetHeight(), false));
+        rCombo.mpMask->Bind();
         glXBindTexImageEXT( pDisplay, pGlxMask, GLX_FRONT_LEFT_EXT, NULL );
-        aMaskTexture.Unbind();
+        rCombo.mpMask->Unbind();
 
-        DrawTextureDiff( aTexture, aMaskTexture, aPosAry, bInverted );
+        DrawTextureDiff(*rCombo.mpTexture, *rCombo.mpMask, aPosAry, bInverted);
 
         glXReleaseTexImageEXT( pDisplay, pGlxMask, GLX_FRONT_LEFT_EXT );
         glXDestroyPixmap( pDisplay, pGlxMask );
     }
     else
     {
-        DrawTexture( aTexture, aPosAry, bInverted );
+        DrawTexture(*rCombo.mpTexture, aPosAry, bInverted);
     }
 
     CHECK_GL_ERROR();
@@ -176,7 +187,56 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixm
     PostDraw();
 
     CHECK_GL_ERROR();
+
     return true;
 }
 
+bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY )
+{
+    SAL_INFO( "vcl.opengl", "RenderPixmapToScreen (" << nX << " " << nY << ")" );
+
+    TextureCombo aCombo;
+    return RenderPixmap(pPixmap, pMask, nX, nY, aCombo);
+}
+
+bool X11OpenGLSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey, int nX, int nY)
+{
+    static bool gbCacheEnabled = !getenv("SAL_WITHOUT_WIDGET_CACHE");
+
+    if (!gbCacheEnabled)
+        return false;
+
+    ControlCacheType::const_iterator iterator = gTextureCache.find(rControlCacheKey);
+
+    if (iterator == gTextureCache.end())
+        return false;
+
+    const std::unique_ptr<TextureCombo>& pCombo = iterator->second;
+
+    PreDraw();
+
+    OpenGLTexture& rTexture = *pCombo->mpTexture;
+
+    SalTwoRect aPosAry(0,  0,  rTexture.GetWidth(), rTexture.GetHeight(),
+                       nX, nY, rTexture.GetWidth(), rTexture.GetHeight());
+
+    if (pCombo->mpMask)
+        DrawTextureDiff(rTexture, *pCombo->mpMask, aPosAry, true);
+    else
+        DrawTexture(rTexture, aPosAry, true);
+
+    PostDraw();
+
+    return true;
+}
+
+bool X11OpenGLSalGraphicsImpl::RenderAndCacheNativeControl(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY,
+                                                           ControlCacheKey& aControlCacheKey)
+{
+    std::unique_ptr<TextureCombo> pCombo(new TextureCombo);
+    bool bResult = RenderPixmap(pPixmap, pMask, nX, nY, *pCombo);
+    gTextureCache[aControlCacheKey] = std::move(pCombo);
+    return bResult;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index f5b8098..1408edf 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -212,6 +212,17 @@ bool X11SalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* /*
     return true;
 }
 
+bool X11SalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey& /*rControlCacheKey*/, int /*nX*/, int /*nY*/)
+{
+    return false;
+}
+
+bool X11SalGraphicsImpl::RenderAndCacheNativeControl(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY,
+                                              ControlCacheKey& /*rControlCacheKey*/)
+{
+    return RenderPixmapToScreen(pPixmap, pMask, nX, nY);
+}
+
 XID X11SalGraphicsImpl::GetXRenderPicture()
 {
     XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
index 9b2b9d5..2cf40f9 100644
--- a/vcl/unx/generic/gdi/gdiimpl.hxx
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -284,6 +284,11 @@ public:
     void Init() SAL_OVERRIDE;
     bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
     bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY ) SAL_OVERRIDE;
+
+    virtual bool TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey,
+                                              int nX, int nY) SAL_OVERRIDE;
+    virtual bool RenderAndCacheNativeControl(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY,
+                                             ControlCacheKey& aControlCacheKey) SAL_OVERRIDE;
 };
 
 #endif
diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx
index 7b667cb..b6be71f 100644
--- a/vcl/unx/generic/gdi/salgdi2.cxx
+++ b/vcl/unx/generic/gdi/salgdi2.cxx
@@ -90,6 +90,21 @@ bool X11SalGraphics::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask,
     return rImpl.RenderPixmapToScreen( pPixmap, pMask, nX, nY );
 }
 
+bool X11SalGraphics::TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey, int nX, int nY)
+{
+    SAL_INFO( "vcl", "TryRenderCachedNativeControl" );
+    X11GraphicsImpl& rImpl = dynamic_cast<X11GraphicsImpl&>(*mxImpl.get());
+    return rImpl.TryRenderCachedNativeControl(rControlCacheKey, nX, nY);
+}
+
+bool X11SalGraphics::RenderAndCacheNativeControl(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY,
+                                                 ControlCacheKey& rControlCacheKey)
+{
+    SAL_INFO( "vcl", "RenderAndCachePixmap" );
+    X11GraphicsImpl& rImpl = dynamic_cast<X11GraphicsImpl&>(*mxImpl.get());
+    return rImpl.RenderAndCacheNativeControl(pPixmap, pMask, nX, nY, rControlCacheKey);
+}
+
 extern "C"
 {
     static Bool GraphicsExposePredicate( Display*, XEvent* pEvent, XPointer pFrameWindow )
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index 0e0331e..d49f045 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -887,12 +887,23 @@ bool GtkSalGraphics::drawNativeControl(ControlType nType, ControlPart nPart,
     if( aClipRegion.IsNull() )
         aClipRegion = aCtrlRect;
 
+    Rectangle aPixmapRect;
+
+    // make pixmap a little larger since some themes draw decoration
+    // outside the rectangle, see e.g. checkbox
+    aPixmapRect = Rectangle(Point( aCtrlRect.Left()-1, aCtrlRect.Top()-1 ),
+                            Size( aCtrlRect.GetWidth()+2, aCtrlRect.GetHeight()+2) );
+
+    ControlCacheKey aControlCacheKey(nType, nPart, nState, aPixmapRect.GetSize());
+    if (TryRenderCachedNativeControl(aControlCacheKey, aPixmapRect.Left(), aPixmapRect.Top()))
+        return true;
+
     clipList aClip;
     int nPasses = 0;
     GdkDrawable* gdkDrawable[2];
     std::unique_ptr<GdkX11Pixmap> xPixmap;
     std::unique_ptr<GdkX11Pixmap> xMask;
-    Rectangle aPixmapRect;
+
     if ((bNeedPixmapPaint || (nState & ControlState::DOUBLEBUFFERING))
         && nType != CTRL_SCROLLBAR
         && nType != CTRL_SPINBOX
@@ -902,11 +913,6 @@ bool GtkSalGraphics::drawNativeControl(ControlType nType, ControlPart nPart,
         && ! (nType == CTRL_TOOLBAR && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) )
         )
     {
-        // make pixmap a little larger since some themes draw decoration
-        // outside the rectangle, see e.g. checkbox
-        aPixmapRect = Rectangle( Point( aCtrlRect.Left()-1, aCtrlRect.Top()-1 ),
-                                 Size( aCtrlRect.GetWidth()+2, aCtrlRect.GetHeight()+2) );
-
         if( bNeedTwoPasses )
         {
             xPixmap.reset( NWGetPixmapFromScreen( aPixmapRect, BG_WHITE ) );
@@ -960,7 +966,9 @@ bool GtkSalGraphics::drawNativeControl(ControlType nType, ControlPart nPart,
     }
 
     if( xPixmap )
-        returnVal = NWRenderPixmapToScreen( xPixmap.get(), xMask.get(), aPixmapRect) && returnVal;
+        returnVal = returnVal && RenderAndCacheNativeControl(xPixmap.get(), xMask.get(),
+                                                             aPixmapRect.Left(), aPixmapRect.Top(),
+                                                             aControlCacheKey);
 
     return returnVal;
 }
@@ -4261,7 +4269,6 @@ GdkX11Pixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect, int nBgC
 {
     GdkX11Pixmap* pPixmap;
     int nDepth = vcl_sal::getSalDisplay(GetGenericData())->GetVisual( m_nXScreen ).GetDepth();
-;
 
     pPixmap = new GdkX11Pixmap( srcRect.GetWidth(), srcRect.GetHeight(), nDepth );
 


More information about the Libreoffice-commits mailing list