[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - 4 commits - include/vcl vcl/Executable_vcldemo.mk vcl/generic vcl/inc vcl/osx vcl/source vcl/unx vcl/win vcl/workben

Michael Meeks michael.meeks at collabora.com
Wed Jan 7 03:45:46 PST 2015


 include/vcl/opengl/OpenGLContext.hxx |    8 +++-
 vcl/Executable_vcldemo.mk            |    7 ++-
 vcl/generic/app/geninst.cxx          |    8 +++-
 vcl/inc/unx/gtk/gtkinst.hxx          |    5 --
 vcl/osx/salinst.cxx                  |    4 ++
 vcl/source/opengl/OpenGLContext.cxx  |   21 ++++++++++
 vcl/unx/gtk/app/gtkinst.cxx          |   14 -------
 vcl/win/source/app/salinst.cxx       |    3 +
 vcl/workben/vcldemo.cxx              |   67 ++++++++++++++++++++++++++++++-----
 9 files changed, 104 insertions(+), 33 deletions(-)

New commits:
commit fb97ade682fffa577b28b76b08e6b3c9737723e9
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Jan 6 16:09:09 2015 +0000

    vcl: reset OpenGLContext(s) when yielding the last SolarMutex.
    
    This should make OpenGL thread-safe to allow multiple threads to
    render using VCL's OpenGL backend, and fix misc. associated driver
    horrors, will give some performance cost for tight Yield loops.
    
    Change-Id: Ib23702262fd9f0925a5ed8c642d0a26e92136b37

diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index a98f825..30e5261 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -222,8 +222,14 @@ public:
     OpenGLProgram*      UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
 
     bool isCurrent();
-    void clearCurrent();
+    static void clearCurrent();
+    /// reset all contexts dis-associating them with their underlying
+    /// resources before a potential thread switch.
+    static void resetAllContexts();
+
+    /// make this GL context current - so it is implicit in subsequent GL calls
     void makeCurrent();
+    /// reset the GL context so this context is not implicit in subsequent GL calls.
     void resetCurrent();
     void swapBuffers();
     void sync();
diff --git a/vcl/generic/app/geninst.cxx b/vcl/generic/app/geninst.cxx
index cf2f301..5ac4936 100644
--- a/vcl/generic/app/geninst.cxx
+++ b/vcl/generic/app/geninst.cxx
@@ -21,8 +21,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "osl/module.hxx"
-#include "tools/solarmutex.hxx"
+#include <osl/module.hxx>
+#include <tools/solarmutex.hxx>
+#include <vcl/opengl/OpenGLContext.hxx>
 
 #include "generic/geninst.h"
 
@@ -53,7 +54,10 @@ void SalYieldMutex::release()
     if ( mnThreadId == osl::Thread::getCurrentIdentifier() )
     {
         if ( mnCount == 1 )
+        {
+            OpenGLContext::resetAllContexts();
             mnThreadId = 0;
+        }
         mnCount--;
     }
     m_mutex.release();
diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx
index 5e81c6b..63735b9 100644
--- a/vcl/osx/salinst.cxx
+++ b/vcl/osx/salinst.cxx
@@ -31,6 +31,7 @@
 #include "vcl/window.hxx"
 #include "vcl/timer.hxx"
 #include "vcl/svmain.hxx"
+#include "vcl/opengl/OpenGLContext.hxx"
 
 #include "osx/saldata.hxx"
 #include "osx/salinst.h"
@@ -269,7 +270,10 @@ void SalYieldMutex::release()
     if ( mnThreadId == osl::Thread::getCurrentIdentifier() )
     {
         if ( mnCount == 1 )
+        {
+            OpenGLContext::resetAllContexts();
             mnThreadId = 0;
+        }
         mnCount--;
     }
     m_mutex.release();
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 578cc02..81029c3 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -82,6 +82,9 @@ OpenGLContext::OpenGLContext():
     else
         pSVData->maGDIData.mpFirstContext = this;
     pSVData->maGDIData.mpLastContext = this;
+
+    // FIXME: better hope we call 'makeCurrent' soon to preserve
+    // the invariant that the last item is the current context.
 }
 
 OpenGLContext::~OpenGLContext()
@@ -1290,6 +1293,22 @@ void OpenGLContext::clearCurrent()
         pCurrentCtx->ReleaseFramebuffers();
 }
 
+void OpenGLContext::resetAllContexts()
+{
+    ImplSVData* pSVData = ImplGetSVData();
+
+    // release all framebuffers from the old context so we can re-attach the
+    // texture in the new context
+    for (OpenGLContext* l = pSVData->maGDIData.mpLastContext; l;
+         l = l->mpPrevContext)
+    {
+        l->ReleaseFramebuffers();
+        if (l->isCurrent())
+            l->resetCurrent();
+        assert (!l->mpNextContext || l->mpNextContext->mpPrevContext == l);
+    }
+}
+
 void OpenGLContext::makeCurrent()
 {
     ImplSVData* pSVData = ImplGetSVData();
@@ -1319,7 +1338,7 @@ void OpenGLContext::makeCurrent()
     }
 #endif
 
-    // move the context at the end of the contexts list
+    // move the context to the end of the contexts list
     static int nSwitch = 0;
     SAL_INFO("vcl.opengl", "******* CONTEXT SWITCH " << ++nSwitch << " *********");
     if( mpNextContext )
diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx
index 9e284eb..1091856 100644
--- a/vcl/win/source/app/salinst.cxx
+++ b/vcl/win/source/app/salinst.cxx
@@ -28,6 +28,7 @@
 
 #include <vcl/apptypes.hxx>
 #include <vcl/opengl/OpenGLHelper.hxx>
+#include <vcl/opengl/OpenGLContext.hxx>
 #include <vcl/timer.hxx>
 
 #include <opengl/salbmp.hxx>
@@ -148,6 +149,8 @@ void SalYieldMutex::release()
         {
             if ( mnCount == 1 )
             {
+                OpenGLContext::resetAllContexts();
+
                 // If we don't call these message, the Output from the
                 // Java clients doesn't come in the right order
                 GdiFlush();
commit 26ea69b37ebf0df035c494d7ac831cb15db1f1b3
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Jan 6 16:08:37 2015 +0000

    vcl: cleanup shared SalYieldMutex from GtkYieldMutex.
    
    Change-Id: I6ace72606ba666322c045d28bea713443c0fc45f

diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
index ceda303..3cabea3 100644
--- a/vcl/inc/unx/gtk/gtkinst.hxx
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
@@ -41,10 +41,7 @@ class GtkYieldMutex : public SalYieldMutex
     std::list<sal_uLong> aYieldStack;
 
 public:
-                        GtkYieldMutex();
-    virtual void        acquire() SAL_OVERRIDE;
-    virtual void        release() SAL_OVERRIDE;
-
+         GtkYieldMutex() {}
     void ThreadsEnter();
     void ThreadsLeave();
 };
diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx
index c2f56aa..7854adf 100644
--- a/vcl/unx/gtk/app/gtkinst.cxx
+++ b/vcl/unx/gtk/app/gtkinst.cxx
@@ -288,20 +288,6 @@ SalPrinter* GtkInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
 #endif
 }
 
-GtkYieldMutex::GtkYieldMutex()
-{
-}
-
-void GtkYieldMutex::acquire()
-{
-    SalYieldMutex::acquire();
-}
-
-void GtkYieldMutex::release()
-{
-    SalYieldMutex::release();
-}
-
 /*
  * These methods always occur in pairs
  * A ThreadsEnter is followed by a ThreadsLeave
commit 51d6e6dd676051c10b6299fa55e192aaf4f49339
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Jan 6 16:07:07 2015 +0000

    vcldemo: extend threaded rendering test.
    
    Change-Id: I81e31e1e7442fd0c6d8d720dbd0e9d5cb82bf52b

diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index 8ea37fd..8c46e59 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -14,6 +14,7 @@
 #include <com/sun/star/registry/XSimpleRegistry.hpp>
 #include <com/sun/star/ucb/UniversalContentBroker.hpp>
 
+#include <osl/time.h>
 #include <vcl/vclmain.hxx>
 #include <vcl/layout.hxx>
 #include <salhelper/thread.hxx>
@@ -1200,12 +1201,14 @@ class DemoWin : public WorkWindow
     bool testThreads;
 
     class RenderThread : public salhelper::Thread {
-        DemoWin &mrWin;
+        DemoWin  &mrWin;
+        TimeValue maDelay;
     public:
-        RenderThread(DemoWin &rWin)
+        RenderThread(DemoWin &rWin, sal_uInt32 nDelaySecs)
             : Thread("vcldemo render thread")
             , mrWin(rWin)
         {
+            maDelay.Seconds = nDelaySecs;
             launch();
         }
         virtual ~RenderThread()
@@ -1214,6 +1217,8 @@ class DemoWin : public WorkWindow
         }
         virtual void execute()
         {
+            osl_waitThread(&maDelay);
+
             SolarMutexGuard aGuard;
             fprintf (stderr, "render from a different thread\n");
             mrWin.Paint(Rectangle());
@@ -1242,7 +1247,10 @@ public:
         {
             if (testThreads)
             { // render this window asynchronously in a new thread
-                mxThread = new RenderThread(*this);
+                sal_uInt32 nDelaySecs = 0;
+                if (rMEvt.GetButtons() & MOUSE_RIGHT)
+                    nDelaySecs = 5;
+                mxThread = new RenderThread(*this, nDelaySecs);
             }
             else
             { // spawn another window
@@ -1388,6 +1396,12 @@ public:
                     bWidgets = true;
                 else if (aArg == "--threads")
                     bThreads = true;
+                else if (aArg.startsWith("--"))
+                {
+                    fprintf(stderr,"Unknown argument '%s'\n",
+                            rtl::OUStringToOString(aArg, RTL_TEXTENCODING_UTF8).getStr());
+                    return showHelp(aRenderer);
+                }
             }
 
             DemoWin aMainWin(aRenderer, bThreads);
commit 6c94733a8a7e8b0278e3d090180e08706978ba2f
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Tue Jan 6 15:09:53 2015 +0000

    vcldemo: add threading mode.
    
    Change-Id: I6ad5524c518a79cac7ec343398242515ef0bbb5f

diff --git a/vcl/Executable_vcldemo.mk b/vcl/Executable_vcldemo.mk
index 44f13b2..9d2e55e 100644
--- a/vcl/Executable_vcldemo.mk
+++ b/vcl/Executable_vcldemo.mk
@@ -25,12 +25,13 @@ $(eval $(call gb_Executable_set_include,vcldemo,\
 
 $(eval $(call gb_Executable_use_libraries,vcldemo,\
 	basegfx \
+    comphelper \
+    cppu \
+    cppuhelper \
     tl \
     sal \
+	salhelper \
     vcl \
-    cppu \
-    cppuhelper \
-    comphelper \
 ))
 
 $(eval $(call gb_Executable_add_exception_objects,vcldemo,\
diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index 1b5a709..8ea37fd 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -16,6 +16,7 @@
 
 #include <vcl/vclmain.hxx>
 #include <vcl/layout.hxx>
+#include <salhelper/thread.hxx>
 
 #include <tools/urlobj.hxx>
 #include <tools/stream.hxx>
@@ -1196,16 +1197,42 @@ class DemoWin : public WorkWindow
 {
     DemoRenderer &mrRenderer;
     bool underTesting;
+    bool testThreads;
+
+    class RenderThread : public salhelper::Thread {
+        DemoWin &mrWin;
+    public:
+        RenderThread(DemoWin &rWin)
+            : Thread("vcldemo render thread")
+            , mrWin(rWin)
+        {
+            launch();
+        }
+        virtual ~RenderThread()
+        {
+            join();
+        }
+        virtual void execute()
+        {
+            SolarMutexGuard aGuard;
+            fprintf (stderr, "render from a different thread\n");
+            mrWin.Paint(Rectangle());
+        }
+    };
+    rtl::Reference<RenderThread> mxThread;
+
 public:
-    DemoWin(DemoRenderer &rRenderer) :
+    DemoWin(DemoRenderer &rRenderer, bool bThreads) :
         WorkWindow(NULL, WB_APP | WB_STDWORK),
-        mrRenderer(rRenderer)
+        mrRenderer(rRenderer),
+        testThreads(bThreads)
     {
         mrRenderer.addInvalidate(this);
         underTesting = false;
     }
     virtual ~DemoWin()
     {
+        mxThread.clear();
         mrRenderer.removeInvalidate(this);
     }
     virtual void MouseButtonDown(const MouseEvent& rMEvt) SAL_OVERRIDE
@@ -1213,9 +1240,16 @@ public:
         mrRenderer.SetSizePixel(GetSizePixel());
         if (!mrRenderer.MouseButtonDown(rMEvt))
         {
-            DemoWin *pNewWin = new DemoWin(mrRenderer);
-            pNewWin->SetText("Another interactive VCL demo window");
-            pNewWin->Show();
+            if (testThreads)
+            { // render this window asynchronously in a new thread
+                mxThread = new RenderThread(*this);
+            }
+            else
+            { // spawn another window
+                DemoWin *pNewWin = new DemoWin(mrRenderer, testThreads);
+                pNewWin->SetText("Another interactive VCL demo window");
+                pNewWin->Show();
+            }
         }
     }
     virtual void KeyInput(const KeyEvent& rKEvt) SAL_OVERRIDE
@@ -1314,7 +1348,8 @@ class DemoApp : public Application
         fprintf(stderr,"         %s\n",
                 rtl::OUStringToOString(aRenderers, RTL_TEXTENCODING_UTF8).getStr());
         fprintf(stderr,"  --test <iterCount> - create benchmark data\n");
-        fprintf(stderr, "  --widgets         - launch the widget test.\n");
+        fprintf(stderr,"  --widgets          - launch the widget test.\n");
+        fprintf(stderr,"  --threads          - render from multiple threads.\n");
         fprintf(stderr, "\n");
         return 0;
     }
@@ -1326,7 +1361,7 @@ public:
     {
         try
         {
-            bool bWidgets = false;
+            bool bWidgets = false, bThreads = false;
             DemoRenderer aRenderer;
 
             for (sal_Int32 i = 0; i < GetCommandLineParamCount(); i++)
@@ -1351,9 +1386,11 @@ public:
                 }
                 else if (aArg == "--widgets")
                     bWidgets = true;
+                else if (aArg == "--threads")
+                    bThreads = true;
             }
 
-            DemoWin aMainWin(aRenderer);
+            DemoWin aMainWin(aRenderer, bThreads);
             boost::scoped_ptr<DemoWidgets> aWidgets;
 
             aMainWin.SetText("Interactive VCL demo #1");


More information about the Libreoffice-commits mailing list