[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/inc vcl/opengl vcl/source

Michael Meeks michael.meeks at collabora.com
Wed Dec 23 08:23:06 PST 2015


 vcl/inc/openglgdiimpl.hxx |    2 +-
 vcl/inc/svdata.hxx        |    1 +
 vcl/opengl/gdiimpl.cxx    |   44 +++++++++++++++++++++++++++-----------------
 vcl/source/app/svdata.cxx |   19 ++++++++++---------
 4 files changed, 39 insertions(+), 27 deletions(-)

New commits:
commit 2a27d83ad8b2cab3af86624f58c183f78c2a67b8
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Dec 10 18:31:04 2015 +0000

    vcl: opengl - lean on the default window's context much more.
    
    Avoid creating our own OpenGLContext to render until we need to
    refresh the screen. Also always re-use context from default window.
    This simplifies our OpenGL Context use significantly, and avoids
    problems with the initial default context getting destroyed in
    some cases.
    
    Change-Id: Ic2239236d3e1f14fd27979c9aab85efd84e6b760
    Reviewed-on: https://gerrit.libreoffice.org/20853
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 3e5ec94..c4fa5c2 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -158,7 +158,7 @@ public:
     void PostDraw();
 
 protected:
-    bool AcquireContext();
+    bool AcquireContext(bool bForceCreate = false);
     bool ReleaseContext();
 
     /// retrieve the default context for offscreen rendering
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index 46527f0..b559cf3 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -357,6 +357,7 @@ struct ImplSVData
 
 void        ImplDeInitSVData();
 VCL_PLUGIN_PUBLIC vcl::Window* ImplGetDefaultWindow();
+VCL_PLUGIN_PUBLIC vcl::Window* ImplGetDefaultContextWindow();
 VCL_PLUGIN_PUBLIC ResMgr*     ImplGetResMgr();
 VCL_PLUGIN_PUBLIC ResId VclResId( sal_Int32 nId ); // throws std::bad_alloc if no res mgr
 DockingManager*     ImplGetDockingManager();
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index ba480f2..a5cec8a 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -92,7 +92,7 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
 
 rtl::Reference<OpenGLContext> OpenGLSalGraphicsImpl::GetOpenGLContext()
 {
-    if( !AcquireContext() )
+    if( !AcquireContext(true) )
         return nullptr;
     return mpContext;
 }
@@ -102,7 +102,7 @@ rtl::Reference<OpenGLContext> OpenGLSalGraphicsImpl::GetDefaultContext()
     return ImplGetDefaultWindow()->GetGraphics()->GetOpenGLContext();
 }
 
-bool OpenGLSalGraphicsImpl::AcquireContext( )
+bool OpenGLSalGraphicsImpl::AcquireContext( bool bForceCreate )
 {
     ImplSVData* pSVData = ImplGetSVData();
 
@@ -121,6 +121,8 @@ bool OpenGLSalGraphicsImpl::AcquireContext( )
         mpContext.clear();
     }
 
+    // We don't care what context we have - but not switching context
+    // is rather useful from a performance perspective.
     OpenGLContext *pContext = pSVData->maGDIData.mpLastContext;
     while( pContext )
     {
@@ -134,7 +136,12 @@ bool OpenGLSalGraphicsImpl::AcquireContext( )
         mpContext = pContext;
     else if( mpWindowContext.is() )
         mpContext = mpWindowContext;
-    else
+    else if( bForceCreate && !IsOffscreen() )
+    {
+        mpWindowContext = CreateWinContext();
+        mpContext = mpWindowContext;
+    }
+    if( !mpContext.is() )
         mpContext = GetDefaultContext();
 
     return mpContext.is();
@@ -175,11 +182,10 @@ void OpenGLSalGraphicsImpl::Init()
         VCL_GL_INFO("::Init - re-size offscreen texture");
     }
 
-    if( !IsOffscreen() )
+    if( mpWindowContext.is() )
     {
-        if( mpWindowContext.is() )
-            mpWindowContext->reset();
-        mpWindowContext = CreateWinContext();
+        mpWindowContext->reset();
+        mpWindowContext.clear();
     }
 }
 
@@ -192,8 +198,11 @@ void OpenGLSalGraphicsImpl::DeInit()
     // let it know. Other eg. VirtualDevice contexts which have
     // references on and rely on this context continuing to work will
     // get a shiny new context in AcquireContext:: next PreDraw.
-    if( mpContext.is() && !IsOffscreen() )
-        mpContext->reset();
+    if( mpWindowContext.is() )
+    {
+        mpWindowContext->reset();
+        mpWindowContext.clear();
+    }
     mpContext.clear();
 }
 
@@ -245,11 +254,6 @@ void OpenGLSalGraphicsImpl::PostDraw()
 
     assert (maOffscreenTex);
 
-    if( IsOffscreen() )
-        assert( !mpWindowContext.is() );
-    else
-        assert( mpWindowContext.is() );
-
     // Always queue the flush.
     if( !IsOffscreen() )
         flush();
@@ -2005,15 +2009,13 @@ void OpenGLSalGraphicsImpl::doFlush()
     if( IsOffscreen() )
         return;
 
-    assert( mpWindowContext.is() );
-
     if( !maOffscreenTex )
     {
         VCL_GL_INFO( "flushAndSwap - odd no texture !" );
         return;
     }
 
-    if (mnDrawCountAtFlush == mnDrawCount)
+    if( mnDrawCountAtFlush == mnDrawCount )
     {
         VCL_GL_INFO( "eliding redundant flushAndSwap, no drawing since last!" );
         return;
@@ -2025,6 +2027,14 @@ void OpenGLSalGraphicsImpl::doFlush()
 
     VCL_GL_INFO( "flushAndSwap" );
 
+    if( !mpWindowContext.is() )
+    {
+        VCL_GL_INFO( "late creation of window context" );
+        mpWindowContext = CreateWinContext();
+    }
+
+    assert( mpWindowContext.is() );
+
     // Interesting ! -> this destroys a context [ somehow ] ...
     mpWindowContext->makeCurrent();
     CHECK_GL_ERROR();
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index edfdbc9..fbde610 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -113,23 +113,25 @@ void ImplDeInitSVData()
         delete pSVData->mpPaperNames, pSVData->mpPaperNames = nullptr;
 }
 
+/// Returns either the application window, or the default GL context window
 vcl::Window* ImplGetDefaultWindow()
 {
     ImplSVData* pSVData = ImplGetSVData();
     if ( pSVData->maWinData.mpAppWin )
         return pSVData->maWinData.mpAppWin;
+    else
+        return ImplGetDefaultContextWindow();
+}
 
-    // First test if we already have a default window.
-    // Don't only place a single if..else inside solar mutex lockframe
-    // because then we might have to wait for the solar mutex what is not necessary
-    // if we already have a default window.
+/// returns the default window created to hold the persistent VCL GL context.
+vcl::Window *ImplGetDefaultContextWindow()
+{
+    ImplSVData* pSVData = ImplGetSVData();
 
+    // Double check locking on mpDefaultWin.
     if ( !pSVData->mpDefaultWin )
     {
-        Application::GetSolarMutex().acquire();
-
-        // Test again because the thread who released the solar mutex could have called
-        // the same method
+        SolarMutexGuard aGuard;
 
         if ( !pSVData->mpDefaultWin && !pSVData->mbDeInit )
         {
@@ -142,7 +144,6 @@ vcl::Window* ImplGetDefaultWindow()
             if( pContext.is() )
                 pContext->acquire();
         }
-        Application::GetSolarMutex().release();
     }
 
     return pSVData->mpDefaultWin;


More information about the Libreoffice-commits mailing list