include/vcl/opengl/OpenGLContext.hxx | 8 +++++++- 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 | 20 +++++++++++++++++--- 8 files changed, 58 insertions(+), 25 deletions(-)
New commits: commit 0bea1d80d10a1e3e9bebf958d622ff2fb480e886 Author: Michael Meeks <michael.me...@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 b93c12c..67570c1 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -199,8 +199,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 9979842..411cfba 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 138a79e..9d681ff 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() @@ -1289,6 +1292,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(); @@ -1318,7 +1337,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 3b52c4492c468ee5dfbb97382f53a28bdf8c0f4c Author: Michael Meeks <michael.me...@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 2165a1e..c80f146 100644 --- a/vcl/unx/gtk/app/gtkinst.cxx +++ b/vcl/unx/gtk/app/gtkinst.cxx @@ -276,20 +276,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 bc6f2ee84dcb66be6a0867d34ce212a2df65efdf Author: Michael Meeks <michael.me...@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 b4e5ed6..608007d 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -15,6 +15,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); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits