[Libreoffice-commits] core.git: Branch 'private/mmeeks/opengl-backbuffer' - 858 commits - accessibility/inc accessibility/source android/source avmedia/source basctl/source basctl/uiconfig basebmp/inc basebmp/source basebmp/test basegfx/source basic/inc basic/qa basic/source bin/find-unused-defines.awk bin/find-unused-typedefs.py bin/find-unused-typedefs.sh bin/gbuild-to-ide bin/get-bugzilla-attachments-by-mimetype bin/rename-sw-abbreviations.sh bridges/Library_cpp_uno.mk bridges/source canvas/source chart2/qa chart2/source chart2/uiconfig codemaker/source comphelper/qa comphelper/source compilerplugins/clang config_host/config_mingw.h.in config_host/config_vcl.h.in config_host.mk.in configmgr/source configure.ac connectivity/Library_mork.mk connectivity/Library_odbc.mk connectivity/source cppcanvas/source cppuhelper/Module_cppuhelper.mk cppuhelper/qa cppuhelper/source cppu/qa cppu/source cui/source cui/uiconfig dbaccess/source dbaccess/uiconfig desktop/CppunitTest_desktop_lib.mk desktop/qa deskt op/source distro-configs/Jenkins download.lst drawinglayer/source dtrans/source editeng/source embeddedobj/source embedserv/source extensions/Library_updatecheckui.mk extensions/Library_updatefeed.mk extensions/Library_updchk.mk extensions/source external/cairo external/clucene external/glyphy external/jpeg-turbo external/libetonyek external/libmwaw external/libxml2 external/libxslt external/mdds external/Module_external.mk extras/source filter/Configuration_filter.mk filter/source forms/source formula/source fpicker/source framework/dtd framework/inc framework/Library_fwk.mk framework/source framework/uiconfig framework/UIConfig_startmodule.mk framework/util .gitignore helpcompiler/inc helpcompiler/source helpcontent2 hwpfilter/source i18nlangtag/source i18npool/inc i18npool/qa i18npool/source icon-themes/breeze icon-themes/galaxy icon-themes/tango idlc/inc idl/inc idl/source include/basebmp include/basic include/canvas include/com include/comphelper include/cppu include/cppuhelper include/editeng include/filter include/formula include/framework include/LibreOfficeKit include/oox include/opencl include/package include/registry include/rtl include/sal include/sax include/sfx2 include/sot include/svl include/svtools include/svx include/toolkit include/tools include/ucbhelper include/unotools include/vbahelper include/vcl include/xmloff instsetoo_native/CustomTarget_setup.mk io/source io/test javaunohelper/source jurt/com jvmaccess/source jvmfwk/plugins jvmfwk/source l10ntools/inc l10ntools/source Library_merged.mk libreofficekit/qa libreofficekit/source lingucomponent/source linguistic/source lotuswordpro/source Makefile.fetch Makefile.in mysqlc/source odk/examples odk/source offapi/com officecfg/registry oox/inc oox/source package/inc package/source postprocess/packimages pyuno/source qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/runner qadevOOo/tests readlicense_oo/license README.md registry/source remotebridges/examples reportdesign/source reportdesign/ uiconfig RepositoryExternal.mk RepositoryFixes.mk rsc/inc sal/osl sal/qa sax/source sc/inc sc/Library_scqahelper.mk sc/Module_sc.mk scp2/source sc/qa scripting/source sc/source sc/uiconfig sc/workben sdext/source sd/inc sd/Library_sd.mk sd/Library_sdui.mk sd/qa sd/sdi sd/source sd/uiconfig sd/util sd/xml setup_native/scripts setup_native/source sfx2/sdi sfx2/source sfx2/uiconfig shell/CppunitTest_shell_zip.mk shell/inc shell/source slideshow/Library_OGLTrans.mk slideshow/opengl slideshow/Package_opengl.mk slideshow/source smoketest/Executable_libtest.mk smoketest/README solenv/bin solenv/gbuild soltools/mkdepend sot/source starmath/inc starmath/source starmath/uiconfig stoc/source store/source svl/source svtools/source svx/inc svx/Library_svx.mk svx/Module_svx.mk svx/source svx/uiconfig svx/util sw/AllLangResTarget_sw.mk sw/inc sw/Library_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sysui/desktop test/source toolkit/source tools/source translations ucbhelper/source ucb/source unotools/s ource unoxml/source unusedcode.easy uui/source vbahelper/source vcl/generic vcl/glyphy vcl/headless vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_gtk3.mk vcl/opengl vcl/osx vcl/qa vcl/quartz vcl/source vcl/uiconfig vcl/UIConfig_vcl.mk vcl/unx vcl/win vcl/workben winaccessibility/inc winaccessibility/source wizards/com wizards/source writerfilter/source writerperfect/inc writerperfect/qa writerperfect/source xmerge/source xmlhelp/source xmloff/inc xmloff/source xmlscript/source xmlsecurity/inc xmlsecurity/source

Michael Meeks michael.meeks at collabora.com
Mon Nov 30 04:10:31 PST 2015


Rebased ref, commits from common ancestor:
commit c6d3598f2fb9e5f46f5df2c997ac7c09813ee7b9
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 27 18:56:54 2015 +0000

    vcl: move begin/end paint counting to SalGraphics where it fits nicely.
    
    Also elide dupliate swap / flushes - if no rendering occurred between times.

diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 36efe03..92d4d11 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -248,7 +248,6 @@ private:
 
 public:
     vcl::Region maClipRegion;
-    int mnPainting;
 
     // Don't hold references to ourselves:
     OpenGLContext *mpPrevContext;
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 2bf3f07..68a5170 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -612,8 +612,9 @@ public:
      */
     class PaintScope {
         VclPtr<OutputDevice> mpDev;
+        void                *mpDebug;
     public:
-        PaintScope(OutputDevice *);
+        explicit PaintScope(OutputDevice *);
         ~PaintScope();
         void flush();
     };
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 87000c3..d280743 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -347,12 +347,8 @@ public:
 
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override;
 
-    virtual OpenGLContext *beginPaint() override;
-    virtual void           endPaint() override;
-
     /// flush contents of the back-buffer to the screen & swap.
-    void flushAndSwap();
-private:
+    virtual void flush() override;
 };
 
 #endif
diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index 14fb2fa..c8ae6b2 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -253,6 +253,13 @@ public:
         { return m_pProc ? long(m_pProc( m_pWindow, const_cast<SalFrame*>(this), nEvent, pEvent )) : 0; }
 
     bool PaintsBlocked() const { return m_bPaintsBlocked; }
+
+    // track painting, and flush when its done.
+    void                        BeginPaint();
+    void                        EndPaint();
+    sal_uInt32                  GetPaintNesting() { return m_nPaintNesting; }
+private:
+    sal_uInt32                  m_nPaintNesting;
 };
 
 #endif // INCLUDED_VCL_INC_SALFRAME_HXX
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 62f714f..045ae48 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -438,11 +438,11 @@ public:
                                     sal_uInt8 nTransparency,
                                     const OutputDevice *pOutDev );
 
-    virtual OpenGLContext      *BeginPaint() { return nullptr; }
-    virtual void                EndPaint()   { }
-
     virtual SystemGraphicsData  GetGraphicsData() const = 0;
 
+    /// Push any pending rendering to the screen.
+    virtual void                Flush();
+
 #if ENABLE_CAIRO_CANVAS
 
     /// Check whether cairo will work
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 1a1c3ef..7a6858f 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -212,8 +212,8 @@ public:
 
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0;
 
-    virtual OpenGLContext *beginPaint() { return nullptr; }
-    virtual void           endPaint()   { }
+    /// flush and hence render any pending rendering commands
+    virtual void flush() { }
 };
 
 #endif
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index ea7da0b..9212a99 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -263,9 +263,6 @@ public:
     virtual css::uno::Any           GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const basegfx::B2ISize& rSize) const override;
     virtual SystemFontData          GetSysFontData( int nFallbackLevel ) const override;
 
-    virtual OpenGLContext          *BeginPaint() override;
-    virtual void                    EndPaint() override;
-
     bool TryRenderCachedNativeControl(ControlCacheKey& aControlCacheKey,
                                       int nX, int nY);
 
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 25a416b..4fb8414 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -436,9 +436,6 @@ public:
 
     virtual SystemGraphicsData GetGraphicsData() const override;
 
-    virtual OpenGLContext     *BeginPaint() override;
-    virtual void               EndPaint() override;
-
     /// Update settings based on the platform values
     static void updateSettingsNative( AllSettings& rSettings );
 };
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index a87c05c..b21eb12 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -154,6 +154,10 @@ void OpenGLSalGraphicsImpl::Init()
             mpContext->ReleaseFramebuffer( maOffscreenTex );
         }
         maOffscreenTex = OpenGLTexture();
+        SAL_DEBUG("paint: " << this << " size mismatch - delete texture " <<
+                  maOffscreenTex.GetWidth() << " x " <<
+                  maOffscreenTex.GetHeight() << " vs. " <<
+                  GetWidth() << " x " << GetHeight());
         VCL_GL_INFO("::Init - re-size offscreen texture");
     }
 
@@ -232,10 +236,15 @@ void OpenGLSalGraphicsImpl::PostDraw()
     else
         assert( mpWindowContext.is() );
 
-    if( mpContext->mnPainting == 0 )
+    // FIXME: we should flush when something is drawn outside paint really.
+    if( !IsOffscreen() )
     {
-        if (!IsOffscreen())
-            flushAndSwap();
+        SalFrame *pFrame = dynamic_cast< SalFrame * >(mpProvider);
+        if( pFrame && pFrame->GetPaintNesting() == 0 )
+        {
+            VCL_GL_INFO( "uncontrolled rendering: catch and stop me." );
+            flush();
+        }
     }
 
     OpenGLZone::leave();
@@ -429,6 +438,7 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
             mpContext->ReleaseFramebuffer( maOffscreenTex );
             maOffscreenTex = OpenGLTexture();
             VCL_GL_INFO( "re-size offscreen texture" );
+            SAL_DEBUG( "paint: " << this << " re-size offscreen texture" );
         }
     }
 
@@ -436,6 +446,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
     {
         VCL_GL_INFO( "create texture of size "
                      << GetWidth() << " x " << GetHeight() );
+        SAL_DEBUG( "paint: " << this << " create texture of size "
+                   << GetWidth() << " x " << GetHeight() );
         maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
         bClearTexture = true;
     }
@@ -1936,26 +1948,29 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
     return true;
 }
 
-OpenGLContext *OpenGLSalGraphicsImpl::beginPaint()
+void OpenGLSalGraphicsImpl::flush()
 {
-    AcquireContext();
-    if( mpContext.is() )
-        mpContext->mnPainting++;
-    return mpContext.get();
-}
+    if( IsOffscreen() )
+        return;
 
-void OpenGLSalGraphicsImpl::flushAndSwap()
-{
-    assert( !IsOffscreen() );
     assert( mpWindowContext.is() );
-    assert( mpContext.is() );
 
     if( !maOffscreenTex )
     {
+        SAL_DEBUG("paint: " << this << " flush and swap - no texture !");
         VCL_GL_INFO( "flushAndSwap - odd no texture !" );
         return;
     }
 
+    if (mnDrawCountAtFlush == mnDrawCount)
+    {
+        VCL_GL_INFO( "eliding redundant flushAndSwap, no drawing since last!" );
+        SAL_DEBUG( "paint: " << this << " eliding redundant flushAndSwap, no drawing since last!" );
+        return;
+    }
+
+    SAL_DEBUG("paint: " << this << " flush and swap");
+
     mnDrawCountAtFlush = mnDrawCount;
 
     OpenGLZone aZone;
@@ -2044,19 +2059,6 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
     VCL_GL_INFO( "flushAndSwap - end." );
 }
 
-void OpenGLSalGraphicsImpl::endPaint()
-{
-    assert( !IsOffscreen() );
-
-    AcquireContext();
-    if( mpContext.is() )
-    {
-        mpContext->mnPainting--;
-        if( mpContext->mnPainting == 0 )
-            flushAndSwap();
-    }
-}
-
 bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext)
 {
     // so far a blunt heuristic: vcl uses shiny new contexts.
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index c540eef5..bc77397 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -33,6 +33,7 @@ SalFrame::SalFrame()
     : m_bPaintsBlocked(false)
     , m_pWindow(nullptr)
     , m_pProc(nullptr)
+    , m_nPaintNesting( 0 )
 {
 }
 
@@ -41,6 +42,8 @@ SalFrame::SalFrame()
 
 SalFrame::~SalFrame()
 {
+    // don't destroy graphics while mid-paint.
+    assert(m_nPaintNesting == 0);
 }
 
 void SalFrame::SetCallback( vcl::Window* pWindow, SALFRAMEPROC pProc )
@@ -56,6 +59,21 @@ void SalFrame::Flush( const Rectangle& )
     Flush();
 }
 
+void SalFrame::BeginPaint()
+{
+    m_nPaintNesting++;
+    assert (m_nPaintNesting > 0);
+    SAL_DEBUG("paint: " << this << " begin " << m_nPaintNesting);
+}
+
+void SalFrame::EndPaint()
+{
+    SAL_DEBUG("paint: " << this << " end " << m_nPaintNesting);
+    assert (m_nPaintNesting > 0);
+    if (--m_nPaintNesting == 0)
+        Flush();
+}
+
 void SalFrame::SetRepresentedURL( const OUString& )
 {
     // currently this is Mac only functionality
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index 6d04c1e..7dcb3a7 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -65,7 +65,7 @@ SalFrameGeometry SalFrame::GetGeometry()
 
 SalGraphics::SalGraphics()
 :   m_nLayout( SalLayoutFlags::NONE ),
-    m_bAntiAliasB2DDraw(false)
+    m_bAntiAliasB2DDraw( false )
 {
     // read global RTL settings
     if( AllSettings::GetLayoutRTL() )
@@ -76,6 +76,13 @@ SalGraphics::~SalGraphics()
 {
 }
 
+void SalGraphics::Flush()
+{
+    SalGraphicsImpl* pImpl = GetImpl();
+    if (pImpl)
+        pImpl->flush();
+}
+
 rtl::Reference<OpenGLContext> SalGraphics::GetOpenGLContext() const
 {
     OpenGLSalGraphicsImpl *pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(GetImpl());
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 09fac7b..93f91bc 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -65,7 +65,6 @@ OpenGLContext::OpenGLContext():
     mpFirstFramebuffer(nullptr),
     mpLastFramebuffer(nullptr),
     mpCurrentProgram(nullptr),
-    mnPainting(0),
     mpPrevContext(nullptr),
     mpNextContext(nullptr)
 {
@@ -1199,9 +1198,6 @@ void OpenGLContext::reset()
 
     OpenGLZone aZone;
 
-    // don't reset a context in the middle of stack frames rendering to it
-    assert( mnPainting == 0 );
-
     // reset the clip region
     maClipRegion.SetEmpty();
 
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index 1779002..fc5418c 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -846,11 +846,23 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
 }
 
 OutputDevice::PaintScope::PaintScope(OutputDevice *pDev)
-    : mpDev( pDev )
 {
-    SalGraphics *mpGraphics = mpDev->GetGraphics();
-    if (mpGraphics)
-        mpGraphics->BeginPaint();
+    vcl::Window *pWindow = dynamic_cast<vcl::Window *>(pDev);
+
+    if (!pWindow) // no point on a non-window
+    {
+        mpDebug = NULL;
+        return;
+    }
+
+    mpDev = pDev;
+
+    SalFrame *pFrame = pWindow->ImplGetFrame();
+    mpDebug = pFrame;
+    if (pFrame)
+        pFrame->BeginPaint();
+    else
+        SAL_WARN("vcl.gdi", "paintscope: no frame for window " << pWindow);
 }
 
 OutputDevice::PaintScope::~PaintScope()
@@ -861,10 +873,16 @@ OutputDevice::PaintScope::~PaintScope()
 /// Flush all the queued rendering commands to the screen for this context.
 void OutputDevice::PaintScope::flush()
 {
-    SalGraphics *mpGraphics = mpDev->GetGraphics();
-    if (mpGraphics)
-        mpGraphics->EndPaint();
-}
+    /// SAL_DEBUG kill this method - why a separate flush ? -> fold me into ~PaintScope.
+    vcl::Window *pWindow = static_cast<vcl::Window *>(mpDev.get());
 
+    SalFrame *pFrame = pWindow->ImplGetFrame();
+    if (!pFrame || pWindow->isDisposed())
+        SAL_WARN("vcl.gdi", "Very odd, window disposed while painting");
+    else
+        assert (pFrame == mpDebug);
+
+    pFrame->EndPaint();
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 8901512..254400e 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -788,6 +788,8 @@ bool Window::AcquireGraphics() const
     // try harder if no wingraphics was available directly
     if ( !mpGraphics )
     {
+        assert ("this is utterly lame !" || false);
+
         // find another output device in the same frame
         OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
         while ( pReleaseOutDev )
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 1241439..d98466a 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -557,16 +557,6 @@ bool X11SalGraphics::drawGradient(const tools::PolyPolygon& rPoly, const Gradien
     return mxImpl->drawGradient(rPoly, rGradient);
 }
 
-OpenGLContext *X11SalGraphics::BeginPaint()
-{
-    return mxImpl->beginPaint();
-}
-
-void X11SalGraphics::EndPaint()
-{
-    return mxImpl->endPaint();
-}
-
 SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const
 {
     if (m_pFrame)
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index c0e3e75..6b1bbff 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -2286,6 +2286,11 @@ void X11SalFrame::SetTitle( const OUString& rTitle )
 
 void X11SalFrame::Flush()
 {
+    SAL_DEBUG("flush " << this);
+    if( pGraphics_ )
+        pGraphics_->Flush();
+    if( pFreeGraphics_ )
+        pFreeGraphics_->Flush();
     XFlush( GetDisplay()->GetDisplay() );
 }
 
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index c5c01a4..c318db9 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -2623,6 +2623,9 @@ void GtkSalFrame::SetPointerPos( long nX, long nY )
 
 void GtkSalFrame::Flush()
 {
+    if( m_pGraphics )
+        m_pGraphics->Flush();
+
 #if GTK_CHECK_VERSION(3,0,0)
     gdk_display_flush( getGdkDisplay() );
 #else
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 1462f25..36ff322 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -1046,14 +1046,4 @@ SystemGraphicsData WinSalGraphics::GetGraphicsData() const
     return aRes;
 }
 
-OpenGLContext *WinSalGraphics::BeginPaint()
-{
-    return mpImpl->beginPaint();
-}
-
-void WinSalGraphics::EndPaint()
-{
-    return mpImpl->endPaint();
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 47a0142a831c5dc78b95e85e13aa6dba4ce267b9
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Nov 26 21:47:35 2015 +0000

    More smoketest notes.
    
    Change-Id: I52bd1555e572c75feb0fc96368b6e61802d9d65c

diff --git a/smoketest/README b/smoketest/README
index b1d250d..30dceb6 100644
--- a/smoketest/README
+++ b/smoketest/README
@@ -12,4 +12,7 @@ data/Basic/Standard.
 macro and waits for a dispatchFinished from the macro's execution. To
 debug this best load workdir/Zip/smoketestdoc.sxw - and hit 'start
 smoketest' - this will launch a number of components and build a
-suitable report in the form of a table.
\ No newline at end of file
+suitable report in the form of a table.
+
+	The StarBasic smoketests also log their output, this ends up
+in instdir/user/temp/smoketest.log.
commit f1fd51628cd90864c6a4ea163261371432bde9c4
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Sat Nov 21 16:19:08 2015 +0000

    vcl rebase cleanup; also assertions on non-flushed SalGraphics.
    
    Change-Id: I41443640e00c69891e4a95ced84b97b8b4626cd8

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index c391853..87000c3 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -89,6 +89,8 @@ protected:
     SalColor mnFillColor;
 #ifdef DBG_UTIL
     bool mProgramIsSolidColor;
+    sal_uInt32 mnDrawCount;
+    sal_uInt32 mnDrawCountAtFlush;
 #endif
     SalColor mProgramSolidColor;
     double mProgramSolidTransparency;
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index bf7ab78..a87c05c 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -51,6 +51,8 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr
     , mnFillColor(SALCOLOR_NONE)
 #ifdef DBG_UTIL
     , mProgramIsSolidColor(false)
+    , mnDrawCount(0)
+    , mnDrawCountAtFlush(0)
 #endif
     , mProgramSolidColor(SALCOLOR_NONE)
     , mProgramSolidTransparency(0.0)
@@ -59,6 +61,14 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr
 
 OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
 {
+#ifdef DBG_UTIL
+    if( !IsOffscreen() )
+    {
+        // Check that all SalGraphics have flushed before being destroyed
+        assert( mnDrawCountAtFlush == mnDrawCount );
+    }
+#endif
+
     ReleaseContext();
 }
 
@@ -144,7 +154,7 @@ void OpenGLSalGraphicsImpl::Init()
             mpContext->ReleaseFramebuffer( maOffscreenTex );
         }
         maOffscreenTex = OpenGLTexture();
-        VCL_GL_INFO("vcl.opengl", "::Init - re-size offscreen texture");
+        VCL_GL_INFO("::Init - re-size offscreen texture");
     }
 
     if( !IsOffscreen() )
@@ -173,6 +183,8 @@ void OpenGLSalGraphicsImpl::PreDraw()
 {
     OpenGLZone::enter();
 
+    mnDrawCount++;
+
     if( !AcquireContext() )
     {
         SAL_WARN( "vcl.opengl", "Couldn't acquire context" );
@@ -239,7 +251,7 @@ void OpenGLSalGraphicsImpl::freeResources()
     // TODO Delete shaders, programs and textures if not shared
     if( mpContext.is() && mpContext->isInitialized() )
     {
-        VCL_GL_INFO( "vcl.opengl", "freeResources" );
+        VCL_GL_INFO( "freeResources" );
         mpContext->makeCurrent();
         mpContext->ReleaseFramebuffer( maOffscreenTex );
     }
@@ -406,7 +418,7 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
 {
     bool bClearTexture = false;
 
-    VCL_GL_INFO( "vcl.opengl", "Check Offscreen texture" );
+    VCL_GL_INFO( "Check Offscreen texture" );
 
     // Always create the offscreen texture
     if( maOffscreenTex )
@@ -416,13 +428,13 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
         {
             mpContext->ReleaseFramebuffer( maOffscreenTex );
             maOffscreenTex = OpenGLTexture();
-            VCL_GL_INFO( "vcl.opengl", "re-size offscreen texture" );
+            VCL_GL_INFO( "re-size offscreen texture" );
         }
     }
 
     if( !maOffscreenTex )
     {
-        VCL_GL_INFO( "vcl.opengl", "create texture of size "
+        VCL_GL_INFO( "create texture of size "
                      << GetWidth() << " x " << GetHeight() );
         maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
         bClearTexture = true;
@@ -1940,25 +1952,27 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     if( !maOffscreenTex )
     {
-        VCL_GL_INFO( "vcl.opengl", "flushAndSwap - odd no texture !" );
+        VCL_GL_INFO( "flushAndSwap - odd no texture !" );
         return;
     }
 
+    mnDrawCountAtFlush = mnDrawCount;
+
     OpenGLZone aZone;
 
-    VCL_GL_INFO( "vcl.opengl", "flushAndSwap" );
+    VCL_GL_INFO( "flushAndSwap" );
 
     // Interesting ! -> this destroys a context [ somehow ] ...
     mpWindowContext->makeCurrent();
     CHECK_GL_ERROR();
 
-    VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquire default frame buffer" );
+    VCL_GL_INFO( "flushAndSwap - acquire default frame buffer" );
 
     mpWindowContext->AcquireDefaultFramebuffer();
     glBindFramebuffer( GL_FRAMEBUFFER, 0 ); // FIXME: paranoid double check.
     CHECK_GL_ERROR();
 
-    VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquired default frame buffer" );
+    VCL_GL_INFO( "flushAndSwap - acquired default frame buffer" );
 
     glDisable( GL_SCISSOR_TEST ); // FIXME: paranoia ...
     CHECK_GL_ERROR();
@@ -1975,20 +1989,20 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(),
                         0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() );
-    VCL_GL_INFO( "vcl.opengl", "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() );
+    VCL_GL_INFO( "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() );
 
     OpenGLProgram *pProgram =
         mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" );
     if( !pProgram )
-        VCL_GL_INFO( "vcl.opengl", "Can't compile simple copying shader !" );
+        VCL_GL_INFO( "Can't compile simple copying shader !" );
     else
     {
         pProgram->Use(); // FIXME: paranoia ...
-        VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." );
+        VCL_GL_INFO( "done paranoid re-use." );
         pProgram->SetTexture( "sampler", maOffscreenTex );
         maOffscreenTex.Bind(); // FIXME: paranoia ...
 
-        VCL_GL_INFO( "vcl.opengl", "bound bits etc." );
+        VCL_GL_INFO( "bound bits etc." );
 
         GLfloat aTexCoord[8];
         maOffscreenTex.GetCoord( aTexCoord, aPosAry, false );
@@ -2027,7 +2041,7 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
                 usleep(500 * 1000);
         }
     }
-    VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." );
+    VCL_GL_INFO( "flushAndSwap - end." );
 }
 
 void OpenGLSalGraphicsImpl::endPaint()
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 5cb1aea..09fac7b 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -1372,7 +1372,7 @@ void OpenGLContext::prepareForYield()
 {
     ImplSVData* pSVData = ImplGetSVData();
 
-    VCL_GL_INFO("vcl.opengl", "clearCurrent - detachframebuffers");
+    VCL_GL_INFO("clearCurrent - detachframebuffers");
 
     // release all framebuffers from the old context so we can re-attach the
     // texture in the new context
@@ -1541,9 +1541,9 @@ bool OpenGLContext::BindFramebuffer( OpenGLFramebuffer* pFramebuffer )
         else
             OpenGLFramebuffer::Unbind();
 
-        VCL_GL_INFO( "vcl.opengl", "before assign pFramebuffer" );
+        VCL_GL_INFO( "before assign pFramebuffer" );
         mpCurrentFramebuffer = pFramebuffer;
-        VCL_GL_INFO( "vcl.opengl", "after assign pFramebuffer" );
+        VCL_GL_INFO( "after assign pFramebuffer" );
     }
 
     return true;
commit adccc35fb6a3fb8f2644560de750e782c20d7748
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 16 18:18:36 2015 +0000

    Get Double-buffered context creation working on linux.
    
    Change-Id: I3db1d6792fcd51577f047b82029124ec825ea319

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index cd5c1a8..bf7ab78 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -166,6 +166,7 @@ void OpenGLSalGraphicsImpl::DeInit()
     // get a shiny new context in AcquireContext:: next PreDraw.
     if( mpContext.is() && !IsOffscreen() )
         mpContext->reset();
+    mpContext.clear();
 }
 
 void OpenGLSalGraphicsImpl::PreDraw()
@@ -1967,7 +1968,6 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
     glViewport( 0, 0, GetWidth(), GetHeight() );
     CHECK_GL_ERROR();
 
-    glDrawBuffer(GL_BACK);
     glClearColor((float)rand()/RAND_MAX, (float)rand()/RAND_MAX,
                  (float)rand()/RAND_MAX, 1.0);
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
@@ -1979,50 +1979,54 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     OpenGLProgram *pProgram =
         mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" );
-    pProgram->Use(); // FIXME: paranoia ...
-    VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." );
-    pProgram->SetTexture( "sampler", maOffscreenTex );
-    maOffscreenTex.Bind(); // FIXME: paranoia ...
+    if( !pProgram )
+        VCL_GL_INFO( "vcl.opengl", "Can't compile simple copying shader !" );
+    else
+    {
+        pProgram->Use(); // FIXME: paranoia ...
+        VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." );
+        pProgram->SetTexture( "sampler", maOffscreenTex );
+        maOffscreenTex.Bind(); // FIXME: paranoia ...
 
-    VCL_GL_INFO( "vcl.opengl", "bound bits etc." );
+        VCL_GL_INFO( "vcl.opengl", "bound bits etc." );
 
-    GLfloat aTexCoord[8];
-    maOffscreenTex.GetCoord( aTexCoord, aPosAry, false );
-    pProgram->SetTextureCoord( aTexCoord );
+        GLfloat aTexCoord[8];
+        maOffscreenTex.GetCoord( aTexCoord, aPosAry, false );
+        pProgram->SetTextureCoord( aTexCoord );
 
-    long nX1( aPosAry.mnDestX );
-    long nY1( aPosAry.mnDestY );
-    long nX2( nX1 + aPosAry.mnDestWidth );
-    long nY2( nY1 + aPosAry.mnDestHeight );
-    const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
-                                 { nX2, nY1 }, { nX2, nY2 }};
+        long nX1( aPosAry.mnDestX );
+        long nY1( aPosAry.mnDestY );
+        long nX2( nX1 + aPosAry.mnDestWidth );
+        long nY2( nY1 + aPosAry.mnDestHeight );
+        const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
+                                     { nX2, nY1 }, { nX2, nY2 }};
 
-    sal_uInt32 nPoints = 4;
-    std::vector<GLfloat> aVertices(nPoints * 2);
-    sal_uInt32 i, j;
+        sal_uInt32 nPoints = 4;
+        std::vector<GLfloat> aVertices(nPoints * 2);
+        sal_uInt32 i, j;
 
-    for( i = 0, j = 0; i < nPoints; i++, j += 2 )
-    {
-        aVertices[j]   = GLfloat(aPoints[i].mnX);
-        aVertices[j+1] = GLfloat(aPoints[i].mnY);
-    }
+        for( i = 0, j = 0; i < nPoints; i++, j += 2 )
+        {
+            aVertices[j]   = GLfloat(aPoints[i].mnX);
+            aVertices[j+1] = GLfloat(aPoints[i].mnY);
+        }
 
-    pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0);
-    pProgram->SetVertices( &aVertices[0] );
-    if (!getenv("NO_COPY"))
-        glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+        pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0);
+        pProgram->SetVertices( &aVertices[0] );
+        if (!getenv("NO_COPY"))
+            glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
 
-    pProgram->Clean();
+        pProgram->Clean();
 
-    glBindTexture( GL_TEXTURE_2D, 0 );
+        glBindTexture( GL_TEXTURE_2D, 0 );
 
-    if (!getenv("NO_SWAP"))
-    {
-        mpWindowContext->swapBuffers();
-        if (!getenv("NO_SLEEP"))
-            usleep(500 * 1000);
+        if (!getenv("NO_SWAP"))
+        {
+            mpWindowContext->swapBuffers();
+            if (!getenv("NO_SLEEP"))
+                usleep(500 * 1000);
+        }
     }
-
     VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." );
 }
 
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index c3c505f..5cb1aea 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -700,9 +700,7 @@ bool GLWindow::HasGLXExtension( const char* name ) const
 bool OpenGLContext::ImplInit()
 {
     if (!m_aGLWin.dpy)
-    {
         return false;
-    }
 
     OpenGLZone aZone;
 
@@ -716,11 +714,10 @@ bool OpenGLContext::ImplInit()
     if (!g_vShareList.empty())
         pSharedCtx = g_vShareList.front();
 
-#ifdef DBG_UTIL
     if (glXCreateContextAttribsARB && !mbRequestLegacyContext)
     {
         int best_fbc = -1;
-        GLXFBConfig* pFBC = getFBConfig(m_aGLWin.dpy, m_aGLWin.win, best_fbc, mbUseDoubleBufferedRendering, true);
+        GLXFBConfig* pFBC = getFBConfig(m_aGLWin.dpy, m_aGLWin.win, best_fbc, mbUseDoubleBufferedRendering, false);
         if (!pFBC)
             return false;
 
@@ -728,24 +725,28 @@ bool OpenGLContext::ImplInit()
         {
             int pContextAttribs[] =
             {
+#if 0 // defined(DBG_UTIL)
                 GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
                 GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+#endif
                 None
+
             };
             m_aGLWin.ctx = glXCreateContextAttribsARB(m_aGLWin.dpy, pFBC[best_fbc], pSharedCtx, /* direct, not via X */ GL_TRUE, pContextAttribs);
             SAL_INFO_IF(m_aGLWin.ctx, "vcl.opengl", "created a 3.2 core context");
         }
         else
             SAL_WARN("vcl.opengl", "unable to find correct FBC");
-
     }
-#endif
 
     if (!m_aGLWin.ctx)
     {
         if (!m_aGLWin.vi)
            return false;
 
+        SAL_WARN("vcl.opengl", "attempting to create a non-double-buffered "
+                               "visual matching the context");
+
         m_aGLWin.ctx = glXCreateContext(m_aGLWin.dpy,
                 m_aGLWin.vi,
                 pSharedCtx,
commit d4b35c09d8ac20c19046142485b3507b845dbd62
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 16 13:42:28 2015 +0000

    Try to de-bong horrors around vdev creation.
    
    This used to create multiple GL Contexts' for the same drawable [!]
    And then release them again, etc. a flicker frenzy for vdevs.
    
    Change-Id: Ia2d79fea3db6ded75e278b8dda80da7d91186c8e

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index f95b98f..cd5c1a8 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -121,6 +121,11 @@ bool OpenGLSalGraphicsImpl::ReleaseContext()
 
 void OpenGLSalGraphicsImpl::Init()
 {
+    // Our init phase is strange ::Init is called twice for vdevs.
+    // the first time around with a NULL geometry provider.
+    if( !mpProvider )
+        return;
+
     // check if we can simply re-use the same context
     if( mpContext.is() )
     {
@@ -142,11 +147,12 @@ void OpenGLSalGraphicsImpl::Init()
         VCL_GL_INFO("vcl.opengl", "::Init - re-size offscreen texture");
     }
 
-    if( mpWindowContext.is() )
-        mpWindowContext->reset();
-
     if( !IsOffscreen() )
+    {
+        if( mpWindowContext.is() )
+            mpWindowContext->reset();
         mpWindowContext = CreateWinContext();
+    }
 }
 
 // Currently only used to get windows ordering right.
@@ -208,6 +214,11 @@ void OpenGLSalGraphicsImpl::PostDraw()
 
     assert (maOffscreenTex);
 
+    if( IsOffscreen() )
+        assert( !mpWindowContext.is() );
+    else
+        assert( mpWindowContext.is() );
+
     if( mpContext->mnPainting == 0 )
     {
         if (!IsOffscreen())
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index abcf635..1241439 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -156,6 +156,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
     // TODO: moggi: FIXME nTextPixel_     = GetPixel( nTextColor_ );
 }
 
+// Initialize the SalGraphics, if @pFrame is NULL - this is a vdev.
 void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
                            SalX11Screen nXScreen )
 {
@@ -165,8 +166,8 @@ void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
     m_pFrame    = pFrame;
     m_pVDev     = nullptr;
 
-    bWindow_    = true;
-    bVirDev_    = false;
+    bWindow_    = pFrame;
+    bVirDev_    = !pFrame;
 
     SetDrawable( aTarget, nXScreen );
     mxImpl->Init();
diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx
index f7da84f..404f6eb 100644
--- a/vcl/unx/gtk/gtkinst.cxx
+++ b/vcl/unx/gtk/gtkinst.cxx
@@ -328,7 +328,7 @@ SalVirtualDevice* GtkInstance::CreateVirtualDevice( SalGraphics *pG,
     GtkSalGraphics *pGtkSalGraphics = dynamic_cast<GtkSalGraphics*>(pG);
     assert(pGtkSalGraphics);
     return CreateX11VirtualDevice(pG, nDX, nDY, eFormat, pGd,
-            new GtkSalGraphics(pGtkSalGraphics->GetGtkFrame(), pGtkSalGraphics->GetGtkWidget()));
+            new GtkSalGraphics(NULL, pGtkSalGraphics->GetGtkWidget()));
 #endif
 }
 
commit 764fc9df049979c32638db53c6f097a21996fa2a
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 16 12:21:47 2015 +0000

    More debugging work; potentially multiple contexts created for same window.
    
    Change-Id: Ibb785f87122980bbc259590c193bbf01e64a285b

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6d745c1..f95b98f 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -144,7 +144,9 @@ void OpenGLSalGraphicsImpl::Init()
 
     if( mpWindowContext.is() )
         mpWindowContext->reset();
-    mpWindowContext = CreateWinContext();
+
+    if( !IsOffscreen() )
+        mpWindowContext = CreateWinContext();
 }
 
 // Currently only used to get windows ordering right.
@@ -204,6 +206,8 @@ void OpenGLSalGraphicsImpl::PostDraw()
 #endif
     }
 
+    assert (maOffscreenTex);
+
     if( mpContext->mnPainting == 0 )
     {
         if (!IsOffscreen())
@@ -392,8 +396,22 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
 
     VCL_GL_INFO( "vcl.opengl", "Check Offscreen texture" );
 
+    // Always create the offscreen texture
+    if( maOffscreenTex )
+    {
+        if( maOffscreenTex.GetWidth()  != GetWidth() ||
+            maOffscreenTex.GetHeight() != GetHeight() )
+        {
+            mpContext->ReleaseFramebuffer( maOffscreenTex );
+            maOffscreenTex = OpenGLTexture();
+            VCL_GL_INFO( "vcl.opengl", "re-size offscreen texture" );
+        }
+    }
+
     if( !maOffscreenTex )
     {
+        VCL_GL_INFO( "vcl.opengl", "create texture of size "
+                     << GetWidth() << " x " << GetHeight() );
         maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
         bClearTexture = true;
     }
@@ -418,8 +436,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
         if( bClearTexture )
         {
             glDrawBuffer( GL_COLOR_ATTACHMENT0 );
-            GLuint clearColor[4] = { 0, 0, 0, 0 };
-            glClearBufferuiv( GL_COLOR, 0, clearColor );
+            GLfloat clearColor[4] = { 1.0, 0, 0, 0 };
+            glClearBufferfv( GL_COLOR, 0, clearColor );
             // FIXME: use glClearTexImage if we have it ?
         }
     }
@@ -1905,6 +1923,7 @@ OpenGLContext *OpenGLSalGraphicsImpl::beginPaint()
 void OpenGLSalGraphicsImpl::flushAndSwap()
 {
     assert( !IsOffscreen() );
+    assert( mpWindowContext.is() );
     assert( mpContext.is() );
 
     if( !maOffscreenTex )
@@ -1917,7 +1936,6 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     VCL_GL_INFO( "vcl.opengl", "flushAndSwap" );
 
-    glFlush();
     // Interesting ! -> this destroys a context [ somehow ] ...
     mpWindowContext->makeCurrent();
     CHECK_GL_ERROR();
@@ -1938,6 +1956,7 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
     glViewport( 0, 0, GetWidth(), GetHeight() );
     CHECK_GL_ERROR();
 
+    glDrawBuffer(GL_BACK);
     glClearColor((float)rand()/RAND_MAX, (float)rand()/RAND_MAX,
                  (float)rand()/RAND_MAX, 1.0);
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
@@ -1945,6 +1964,7 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(),
                         0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() );
+    VCL_GL_INFO( "vcl.opengl", "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() );
 
     OpenGLProgram *pProgram =
         mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" );
@@ -1987,16 +2007,11 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     if (!getenv("NO_SWAP"))
     {
-        glFlush();
         mpWindowContext->swapBuffers();
-        glFlush();
         if (!getenv("NO_SLEEP"))
-            usleep(500000);
+            usleep(500 * 1000);
     }
 
-    // Should get a more sensible context (this one) next time.
-    mpContext.clear();
-
     VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." );
 }
 
commit cdd413b987a6b7388d73cab18b27a429c5c61603
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 13 22:57:43 2015 +0000

    More horrific debugging experience ...
    
    Change-Id: Iaf703f5297e20de24ca748571bb12b708b5a252a

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 3d1c50c..6d745c1 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -139,6 +139,7 @@ void OpenGLSalGraphicsImpl::Init()
             mpContext->ReleaseFramebuffer( maOffscreenTex );
         }
         maOffscreenTex = OpenGLTexture();
+        VCL_GL_INFO("vcl.opengl", "::Init - re-size offscreen texture");
     }
 
     if( mpWindowContext.is() )
@@ -222,6 +223,7 @@ void OpenGLSalGraphicsImpl::freeResources()
     // TODO Delete shaders, programs and textures if not shared
     if( mpContext.is() && mpContext->isInitialized() )
     {
+        VCL_GL_INFO( "vcl.opengl", "freeResources" );
         mpContext->makeCurrent();
         mpContext->ReleaseFramebuffer( maOffscreenTex );
     }
@@ -388,6 +390,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
 {
     bool bClearTexture = false;
 
+    VCL_GL_INFO( "vcl.opengl", "Check Offscreen texture" );
+
     if( !maOffscreenTex )
     {
         maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
@@ -409,6 +413,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
     else
     {
         mpFramebuffer = mpContext->AcquireFramebuffer( maOffscreenTex );
+        CHECK_GL_ERROR();
+
         if( bClearTexture )
         {
             glDrawBuffer( GL_COLOR_ATTACHMENT0 );
@@ -418,6 +424,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
         }
     }
 
+    assert( maOffscreenTex );
+
     CHECK_GL_ERROR();
     return true;
 }
@@ -1899,22 +1907,32 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
     assert( !IsOffscreen() );
     assert( mpContext.is() );
 
+    if( !maOffscreenTex )
+    {
+        VCL_GL_INFO( "vcl.opengl", "flushAndSwap - odd no texture !" );
+        return;
+    }
+
     OpenGLZone aZone;
 
     VCL_GL_INFO( "vcl.opengl", "flushAndSwap" );
 
-    glBindTexture( GL_TEXTURE_2D, 0 );
-
     glFlush();
+    // Interesting ! -> this destroys a context [ somehow ] ...
     mpWindowContext->makeCurrent();
     CHECK_GL_ERROR();
 
+    VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquire default frame buffer" );
+
     mpWindowContext->AcquireDefaultFramebuffer();
+    glBindFramebuffer( GL_FRAMEBUFFER, 0 ); // FIXME: paranoid double check.
     CHECK_GL_ERROR();
 
-    glDisable( GL_SCISSOR_TEST );
+    VCL_GL_INFO( "vcl.opengl", "flushAndSwap - acquired default frame buffer" );
+
+    glDisable( GL_SCISSOR_TEST ); // FIXME: paranoia ...
     CHECK_GL_ERROR();
-    glDisable( GL_STENCIL_TEST );
+    glDisable( GL_STENCIL_TEST ); // FIXME: paranoia ...
     CHECK_GL_ERROR();
 
     glViewport( 0, 0, GetWidth(), GetHeight() );
@@ -1930,8 +1948,12 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     OpenGLProgram *pProgram =
         mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" );
-
+    pProgram->Use(); // FIXME: paranoia ...
+    VCL_GL_INFO( "vcl.opengl", "done paranoid re-use." );
     pProgram->SetTexture( "sampler", maOffscreenTex );
+    maOffscreenTex.Bind(); // FIXME: paranoia ...
+
+    VCL_GL_INFO( "vcl.opengl", "bound bits etc." );
 
     GLfloat aTexCoord[8];
     maOffscreenTex.GetCoord( aTexCoord, aPosAry, false );
@@ -1961,6 +1983,8 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     pProgram->Clean();
 
+    glBindTexture( GL_TEXTURE_2D, 0 );
+
     if (!getenv("NO_SWAP"))
     {
         glFlush();
@@ -1970,6 +1994,9 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
             usleep(500000);
     }
 
+    // Should get a more sensible context (this one) next time.
+    mpContext.clear();
+
     VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." );
 }
 
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 2d4cb40..b540e96 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -349,6 +349,10 @@ void OpenGLTexture::Bind()
         glBindTexture( GL_TEXTURE_2D, mpImpl->mnTexture );
         CHECK_GL_ERROR();
     }
+    else
+        VCL_GL_INFO( "OpenGLTexture::Binding invalid texture" );
+
+    CHECK_GL_ERROR();
 }
 
 void OpenGLTexture::Unbind()
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index c3ad82c51..c3c505f 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -1371,6 +1371,8 @@ void OpenGLContext::prepareForYield()
 {
     ImplSVData* pSVData = ImplGetSVData();
 
+    VCL_GL_INFO("vcl.opengl", "clearCurrent - detachframebuffers");
+
     // release all framebuffers from the old context so we can re-attach the
     // texture in the new context
     rtl::Reference<OpenGLContext> pCurrentCtx = pSVData->maGDIData.mpLastContext;
@@ -1537,7 +1539,10 @@ bool OpenGLContext::BindFramebuffer( OpenGLFramebuffer* pFramebuffer )
             pFramebuffer->Bind();
         else
             OpenGLFramebuffer::Unbind();
+
+        VCL_GL_INFO( "vcl.opengl", "before assign pFramebuffer" );
         mpCurrentFramebuffer = pFramebuffer;
+        VCL_GL_INFO( "vcl.opengl", "after assign pFramebuffer" );
     }
 
     return true;
commit c70f629be25702808cda62c712ffd5b7bf9995c9
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 13 21:25:44 2015 +0000

    More tweakables ... no joy.
    
    Change-Id: I994023668a9251809ec10520829a3df5e6e3a819

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 8fcb3d6..3d1c50c 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -1889,6 +1889,8 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
 OpenGLContext *OpenGLSalGraphicsImpl::beginPaint()
 {
     AcquireContext();
+    if( mpContext.is() )
+        mpContext->mnPainting++;
     return mpContext.get();
 }
 
@@ -1954,15 +1956,18 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0);
     pProgram->SetVertices( &aVertices[0] );
-    glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+    if (!getenv("NO_COPY"))
+        glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
 
     pProgram->Clean();
 
     if (!getenv("NO_SWAP"))
     {
+        glFlush();
         mpWindowContext->swapBuffers();
         glFlush();
-        usleep(500000);
+        if (!getenv("NO_SLEEP"))
+            usleep(500000);
     }
 
     VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." );
@@ -1973,9 +1978,12 @@ void OpenGLSalGraphicsImpl::endPaint()
     assert( !IsOffscreen() );
 
     AcquireContext();
-    if( mpContext.is() &&
-        mpContext->mnPainting == 0 )
-        flushAndSwap();
+    if( mpContext.is() )
+    {
+        mpContext->mnPainting--;
+        if( mpContext->mnPainting == 0 )
+            flushAndSwap();
+    }
 }
 
 bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext)
diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index 768e725..3538572 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -1105,10 +1105,17 @@ public:
             {
                 mnStartTime = getTimeNow();
                 for (int i = 0; i < r->getTestRepeatCount(); i++)
+                {
+                    OutputDevice::PaintScope aScope(&rDev);
                     r->RenderRegion(rDev, aWholeWin, aCtx);
+                }
                 addTime(mnSelectedRenderer, getTimeNow() - mnStartTime);
-            } else
+            }
+            else
+            {
+                OutputDevice::PaintScope aScope(&rDev);
                 r->RenderRegion(rDev, aWholeWin, aCtx);
+            }
         }
         else
         {
@@ -1128,11 +1135,20 @@ public:
                     {
                         mnStartTime = getTimeNow();
                         for (int j = 0; j < r->getTestRepeatCount() * THUMB_REPEAT_FACTOR; j++)
+                        {
+                            OutputDevice::PaintScope aScope(&rDev);
                             r->RenderRegion(rDev, aRegions[i], aCtx);
+                        }
                         addTime(i, (getTimeNow() - mnStartTime) / THUMB_REPEAT_FACTOR);
-                    } else
+                    }
+                    else
+                    {
                         for (int j = 0; j < r->getTestRepeatCount(); j++)
+                        {
+                            OutputDevice::PaintScope aScope(&rDev);
                             r->RenderRegion(rDev, aRegions[i], aCtx);
+                        }
+                    }
                 }
                 else
                 {
commit 5e5eeeae5db72c774133bfca11a4f7ae88bcfd55
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 13 21:11:18 2015 +0000

    STAGE <N> - starting to see something.
    
    Change-Id: Iee7261e724e7ec3f834ae246cdf94f6a46605fec

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index f1f19e1..8fcb3d6 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -37,6 +37,8 @@
 
 #include <vector>
 
+#include <stdlib.h>
+
 OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvider *pProvider)
     : mpContext(nullptr)
     , mrParent(rParent)
@@ -100,7 +102,12 @@ bool OpenGLSalGraphicsImpl::AcquireContext( )
         pContext = pContext->mpPrevContext;
     }
 
-    mpContext = pContext ? pContext : GetDefaultContext();
+    if( mpContext.is() )
+        mpContext = pContext;
+    else if( mpWindowContext.is() )
+        mpContext = mpWindowContext;
+    else
+        mpContext = GetDefaultContext();
 
     return mpContext.is();
 }
@@ -199,10 +206,7 @@ void OpenGLSalGraphicsImpl::PostDraw()
     if( mpContext->mnPainting == 0 )
     {
         if (!IsOffscreen())
-        {
-            SAL_DEBUG("PostDraw flush ?");
             flushAndSwap();
-        }
     }
 
     OpenGLZone::leave();
@@ -382,8 +386,13 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
 
 bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
 {
+    bool bClearTexture = false;
+
     if( !maOffscreenTex )
+    {
         maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
+        bClearTexture = true;
+    }
 
     if( !maOffscreenTex.IsUnique() )
     {
@@ -400,6 +409,13 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
     else
     {
         mpFramebuffer = mpContext->AcquireFramebuffer( maOffscreenTex );
+        if( bClearTexture )
+        {
+            glDrawBuffer( GL_COLOR_ATTACHMENT0 );
+            GLuint clearColor[4] = { 0, 0, 0, 0 };
+            glClearBufferuiv( GL_COLOR, 0, clearColor );
+            // FIXME: use glClearTexImage if we have it ?
+        }
     }
 
     CHECK_GL_ERROR();
@@ -1872,7 +1888,6 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
 
 OpenGLContext *OpenGLSalGraphicsImpl::beginPaint()
 {
-    SAL_DEBUG( "want to rid ourselves of this method" );
     AcquireContext();
     return mpContext.get();
 }
@@ -1886,22 +1901,33 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     VCL_GL_INFO( "vcl.opengl", "flushAndSwap" );
 
-//    glFlush(); - not needed
+    glBindTexture( GL_TEXTURE_2D, 0 );
+
+    glFlush();
     mpWindowContext->makeCurrent();
     CHECK_GL_ERROR();
 
     mpWindowContext->AcquireDefaultFramebuffer();
     CHECK_GL_ERROR();
 
+    glDisable( GL_SCISSOR_TEST );
+    CHECK_GL_ERROR();
+    glDisable( GL_STENCIL_TEST );
+    CHECK_GL_ERROR();
+
     glViewport( 0, 0, GetWidth(), GetHeight() );
-    ImplInitClipRegion();
     CHECK_GL_ERROR();
 
-    SalTwoRect aPosAry(0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(),
-                       0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight());
+    glClearColor((float)rand()/RAND_MAX, (float)rand()/RAND_MAX,
+                 (float)rand()/RAND_MAX, 1.0);
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
+    CHECK_GL_ERROR();
+
+    SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(),
+                        0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() );
 
     OpenGLProgram *pProgram =
-        mpContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" );
+        mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" );
 
     pProgram->SetTexture( "sampler", maOffscreenTex );
 
@@ -1932,7 +1958,14 @@ void OpenGLSalGraphicsImpl::flushAndSwap()
 
     pProgram->Clean();
 
-    mpContext->swapBuffers();
+    if (!getenv("NO_SWAP"))
+    {
+        mpWindowContext->swapBuffers();
+        glFlush();
+        usleep(500000);
+    }
+
+    VCL_GL_INFO( "vcl.opengl", "flushAndSwap - end." );
 }
 
 void OpenGLSalGraphicsImpl::endPaint()
commit 61dcd416b539eb6582646e9403d2cbbb541ed0b4
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 13 15:50:39 2015 +0000

    STEP #4 - paint guards & compilation.
    
    Change-Id: I57addc1d7d948f7e614526f24cf32181313bda1e

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index a146c86..2bf3f07 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -609,13 +609,9 @@ public:
     /**
      * Instantiate across a paint operation to defer flushing
      * to the end.
-     *
-     * NB. holding a handle avoids problems with
-     * the underlying SalGraphics and it's implementation
-     * changing.
      */
     class PaintScope {
-        void *pHandle;
+        VclPtr<OutputDevice> mpDev;
     public:
         PaintScope(OutputDevice *);
         ~PaintScope();
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 418850b..c391853 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -160,9 +160,6 @@ protected:
     /// retrieve the default context for offscreen rendering
     static rtl::Reference<OpenGLContext> GetDefaultContext();
 
-    /// flush contents of the back-buffer to the screen & swap.
-    void FlushAndSwap();
-
     /// create a new context for rendering to the underlying window
     virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0;
 
@@ -350,6 +347,9 @@ public:
 
     virtual OpenGLContext *beginPaint() override;
     virtual void           endPaint() override;
+
+    /// flush contents of the back-buffer to the screen & swap.
+    void flushAndSwap();
 private:
 };
 
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 1bef26b..1a1c3ef 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -213,7 +213,7 @@ public:
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0;
 
     virtual OpenGLContext *beginPaint() { return nullptr; }
-    virtual OpenGLContext *endPaint()   { }
+    virtual void           endPaint()   { }
 };
 
 #endif
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 04da6ed..ea7da0b 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -264,6 +264,7 @@ public:
     virtual SystemFontData          GetSysFontData( int nFallbackLevel ) const override;
 
     virtual OpenGLContext          *BeginPaint() override;
+    virtual void                    EndPaint() override;
 
     bool TryRenderCachedNativeControl(ControlCacheKey& aControlCacheKey,
                                       int nX, int nY);
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 4ff01fa..25a416b 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -437,6 +437,7 @@ public:
     virtual SystemGraphicsData GetGraphicsData() const override;
 
     virtual OpenGLContext     *BeginPaint() override;
+    virtual void               EndPaint() override;
 
     /// Update settings based on the platform values
     static void updateSettingsNative( AllSettings& rSettings );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index b1ee0ce..f1f19e1 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -135,7 +135,7 @@ void OpenGLSalGraphicsImpl::Init()
     }
 
     if( mpWindowContext.is() )
-        mpWindowContext.reset();
+        mpWindowContext->reset();
     mpWindowContext = CreateWinContext();
 }
 
@@ -201,7 +201,7 @@ void OpenGLSalGraphicsImpl::PostDraw()
         if (!IsOffscreen())
         {
             SAL_DEBUG("PostDraw flush ?");
-            FlushAndSwap();
+            flushAndSwap();
         }
     }
 
@@ -1877,13 +1877,15 @@ OpenGLContext *OpenGLSalGraphicsImpl::beginPaint()
     return mpContext.get();
 }
 
-void OpenGLSalGraphicsImpl::FlushAndSwap()
+void OpenGLSalGraphicsImpl::flushAndSwap()
 {
     assert( !IsOffscreen() );
     assert( mpContext.is() );
 
     OpenGLZone aZone;
 
+    VCL_GL_INFO( "vcl.opengl", "flushAndSwap" );
+
 //    glFlush(); - not needed
     mpWindowContext->makeCurrent();
     CHECK_GL_ERROR();
@@ -1904,20 +1906,21 @@ void OpenGLSalGraphicsImpl::FlushAndSwap()
     pProgram->SetTexture( "sampler", maOffscreenTex );
 
     GLfloat aTexCoord[8];
-    maOffscreenTex.GetCoord( aTexCoord, rPosAry, false );
+    maOffscreenTex.GetCoord( aTexCoord, aPosAry, false );
     pProgram->SetTextureCoord( aTexCoord );
 
-    long nX1( rPosAry.mnDestX );
-    long nY1( rPosAry.mnDestY );
-    long nX2( nX1 + rPosAry.mnDestWidth );
-    long nY2( nY1 + rPosAry.mnDestHeight );
+    long nX1( aPosAry.mnDestX );
+    long nY1( aPosAry.mnDestY );
+    long nX2( nX1 + aPosAry.mnDestWidth );
+    long nY2( nY1 + aPosAry.mnDestHeight );
     const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
                                  { nX2, nY1 }, { nX2, nY2 }};
 
+    sal_uInt32 nPoints = 4;
     std::vector<GLfloat> aVertices(nPoints * 2);
     sal_uInt32 i, j;
 
-    for( i = 0, j = 0; i < 4; i++, j += 2 )
+    for( i = 0, j = 0; i < nPoints; i++, j += 2 )
     {
         aVertices[j]   = GLfloat(aPoints[i].mnX);
         aVertices[j+1] = GLfloat(aPoints[i].mnY);
@@ -1939,7 +1942,7 @@ void OpenGLSalGraphicsImpl::endPaint()
     AcquireContext();
     if( mpContext.is() &&
         mpContext->mnPainting == 0 )
-        FlushAndSwap();
+        flushAndSwap();
 }
 
 bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext)
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index 10875ca..5a7fa28 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -1083,55 +1083,4 @@ GLXFBConfig OpenGLHelper::GetPixmapFBConfig( Display* pDisplay, bool& bInverted
 
 #endif
 
-OutputDevice::PaintScope::PaintScope(OutputDevice *pDev)
-    : pHandle( nullptr )
-{
-    if( pDev->mpGraphics || pDev->AcquireGraphics() )
-    {
-        OpenGLContext *pContext = pDev->mpGraphics->BeginPaint();
-/*
-        if( pContext )
-        {
-            assert( pContext->mnPainting >= 0 );
-            pContext->mnPainting++;
-            pContext->acquire();
-            pHandle = static_cast<void *>( pContext );
-        }
-*/
-    }
-}
-
-/**
- * Flush all the queued rendering commands to the screen for this context.
- */
-void OutputDevice::PaintScope::flush()
-{
-    if( pDev->mpGraphics || pDev->AcquireGraphics() )
-        pDev->mpGraphics->EndPaint();
-
-#if 0
-    if( pHandle )
-    {
-        OpenGLContext *pContext = static_cast<OpenGLContext *>( pHandle );
-        pHandle = nullptr;
-        pContext->mnPainting--;
-        assert( pContext->mnPainting >= 0 );
-        if( pContext->mnPainting == 0 )
-        {
-            pContext->makeCurrent();
-            pContext->AcquireDefaultFramebuffer();
-            glFlush();
-            pContext->swapBuffers();
-            CHECK_GL_ERROR();
-        }
-        pContext->release();
-    }
-#endif
-}
-
-OutputDevice::PaintScope::~PaintScope()
-{
-    flush();
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx
index b343f50..1779002 100644
--- a/vcl/source/outdev/outdev.cxx
+++ b/vcl/source/outdev/outdev.cxx
@@ -845,4 +845,26 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
     return bDrawn;
 }
 
+OutputDevice::PaintScope::PaintScope(OutputDevice *pDev)
+    : mpDev( pDev )
+{
+    SalGraphics *mpGraphics = mpDev->GetGraphics();
+    if (mpGraphics)
+        mpGraphics->BeginPaint();
+}
+
+OutputDevice::PaintScope::~PaintScope()
+{
+    flush();
+}
+
+/// Flush all the queued rendering commands to the screen for this context.
+void OutputDevice::PaintScope::flush()
+{
+    SalGraphics *mpGraphics = mpDev->GetGraphics();
+    if (mpGraphics)
+        mpGraphics->EndPaint();
+}
+
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 738d59b..abcf635 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -561,6 +561,11 @@ OpenGLContext *X11SalGraphics::BeginPaint()
     return mxImpl->beginPaint();
 }
 
+void X11SalGraphics::EndPaint()
+{
+    return mxImpl->endPaint();
+}
+
 SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const
 {
     if (m_pFrame)
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 366b81c..1462f25 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -1051,4 +1051,9 @@ OpenGLContext *WinSalGraphics::BeginPaint()
     return mpImpl->beginPaint();
 }
 
+void WinSalGraphics::EndPaint()
+{
+    return mpImpl->endPaint();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit e61d5564fcce97bdbb6dba898135926761a7a10a
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 13 14:31:09 2015 +0000

    Stage #3 - first cut at flushing the whole buffer across ...

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 7ac3496..418850b 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -160,6 +160,9 @@ protected:
     /// retrieve the default context for offscreen rendering
     static rtl::Reference<OpenGLContext> GetDefaultContext();
 
+    /// flush contents of the back-buffer to the screen & swap.
+    void FlushAndSwap();
+
     /// create a new context for rendering to the underlying window
     virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0;
 
@@ -346,6 +349,7 @@ public:
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override;
 
     virtual OpenGLContext *beginPaint() override;
+    virtual void           endPaint() override;
 private:
 };
 
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 98c3b8f..62f714f 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -439,6 +439,7 @@ public:
                                     const OutputDevice *pOutDev );
 
     virtual OpenGLContext      *BeginPaint() { return nullptr; }
+    virtual void                EndPaint()   { }
 
     virtual SystemGraphicsData  GetGraphicsData() const = 0;
 
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 3324012..1bef26b 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -213,6 +213,7 @@ public:
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0;
 
     virtual OpenGLContext *beginPaint() { return nullptr; }
+    virtual OpenGLContext *endPaint()   { }
 };
 
 #endif
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 25cb53a..b1ee0ce 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -133,6 +133,10 @@ void OpenGLSalGraphicsImpl::Init()
         }
         maOffscreenTex = OpenGLTexture();
     }
+
+    if( mpWindowContext.is() )
+        mpWindowContext.reset();
+    mpWindowContext = CreateWinContext();
 }
 
 // Currently only used to get windows ordering right.
@@ -173,19 +177,13 @@ void OpenGLSalGraphicsImpl::PreDraw()
 
 void OpenGLSalGraphicsImpl::PostDraw()
 {
-    if( mpContext->mnPainting == 0 )
-    {
-        if (!IsOffscreen()) ...
-#warning "Trigger re-rendering of the window if we have one"
-        glFlush();
-    }
     if( mbUseScissor )
     {
         glDisable( GL_SCISSOR_TEST );
         CHECK_GL_ERROR();
     }
-   if( mbUseStencil )
-   {
+    if( mbUseStencil )
+    {
         glDisable( GL_STENCIL_TEST );
         CHECK_GL_ERROR();
     }
@@ -197,6 +195,16 @@ void OpenGLSalGraphicsImpl::PostDraw()
         mProgramIsSolidColor = false;
 #endif
     }
+
+    if( mpContext->mnPainting == 0 )
+    {
+        if (!IsOffscreen())
+        {
+            SAL_DEBUG("PostDraw flush ?");
+            FlushAndSwap();
+        }
+    }
+
     OpenGLZone::leave();
 }
 
@@ -1864,10 +1872,76 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
 
 OpenGLContext *OpenGLSalGraphicsImpl::beginPaint()
 {
+    SAL_DEBUG( "want to rid ourselves of this method" );
     AcquireContext();
     return mpContext.get();
 }
 
+void OpenGLSalGraphicsImpl::FlushAndSwap()
+{
+    assert( !IsOffscreen() );
+    assert( mpContext.is() );
+
+    OpenGLZone aZone;
+
+//    glFlush(); - not needed
+    mpWindowContext->makeCurrent();
+    CHECK_GL_ERROR();
+
+    mpWindowContext->AcquireDefaultFramebuffer();
+    CHECK_GL_ERROR();
+
+    glViewport( 0, 0, GetWidth(), GetHeight() );
+    ImplInitClipRegion();
+    CHECK_GL_ERROR();
+
+    SalTwoRect aPosAry(0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(),
+                       0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight());
+
+    OpenGLProgram *pProgram =
+        mpContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" );
+
+    pProgram->SetTexture( "sampler", maOffscreenTex );
+
+    GLfloat aTexCoord[8];
+    maOffscreenTex.GetCoord( aTexCoord, rPosAry, false );
+    pProgram->SetTextureCoord( aTexCoord );
+
+    long nX1( rPosAry.mnDestX );
+    long nY1( rPosAry.mnDestY );
+    long nX2( nX1 + rPosAry.mnDestWidth );
+    long nY2( nY1 + rPosAry.mnDestHeight );
+    const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
+                                 { nX2, nY1 }, { nX2, nY2 }};
+
+    std::vector<GLfloat> aVertices(nPoints * 2);
+    sal_uInt32 i, j;
+
+    for( i = 0, j = 0; i < 4; i++, j += 2 )
+    {
+        aVertices[j]   = GLfloat(aPoints[i].mnX);
+        aVertices[j+1] = GLfloat(aPoints[i].mnY);
+    }
+
+    pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0);
+    pProgram->SetVertices( &aVertices[0] );
+    glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+
+    pProgram->Clean();
+
+    mpContext->swapBuffers();
+}
+
+void OpenGLSalGraphicsImpl::endPaint()
+{
+    assert( !IsOffscreen() );
+
+    AcquireContext();
+    if( mpContext.is() &&
+        mpContext->mnPainting == 0 )
+        FlushAndSwap();
+}
+
 bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext)
 {
     // so far a blunt heuristic: vcl uses shiny new contexts.
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index c7cbfa3..10875ca 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -1089,6 +1089,7 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev)
     if( pDev->mpGraphics || pDev->AcquireGraphics() )
     {
         OpenGLContext *pContext = pDev->mpGraphics->BeginPaint();
+/*
         if( pContext )
         {
             assert( pContext->mnPainting >= 0 );
@@ -1096,6 +1097,7 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev)
             pContext->acquire();
             pHandle = static_cast<void *>( pContext );
         }
+*/
     }
 }
 
@@ -1104,6 +1106,10 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev)
  */
 void OutputDevice::PaintScope::flush()
 {
+    if( pDev->mpGraphics || pDev->AcquireGraphics() )
+        pDev->mpGraphics->EndPaint();
+
+#if 0
     if( pHandle )
     {
         OpenGLContext *pContext = static_cast<OpenGLContext *>( pHandle );
@@ -1120,6 +1126,7 @@ void OutputDevice::PaintScope::flush()
         }
         pContext->release();
     }
+#endif
 }
 
 OutputDevice::PaintScope::~PaintScope()
commit cfdfe8f75794b87f1ee4eb754864d256c9ae2a9f
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 13 12:26:52 2015 +0000

    Step #2 - kill mbOffscreen.
    
    Change-Id: Ib844155cca41cd4a75bf0273c7b32a99dfb9870e

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 9eb4353..7ac3496 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -57,7 +57,13 @@ class VCL_DLLPUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
     friend class OpenGLTests;
 protected:
 
+    /// This context is solely for blitting @maOffscreenTex
+    rtl::Reference<OpenGLContext> mpWindowContext;
+
+    /// This context is whatever is most convenient to render
+    /// to @maOffscreenTex with.
     rtl::Reference<OpenGLContext> mpContext;
+
     SalGraphics& mrParent;
     /// Pointer to the SalFrame or SalVirtualDevice
     SalGeometryProvider* mpProvider;
@@ -72,7 +78,11 @@ protected:
     bool mbUseScissor;
     bool mbUseStencil;
 
-    bool mbOffscreen;
+    /**
+     * All rendering happens to this off-screen texture. For
+     * non-virtual devices, ie. windows - we will blit it and
+     * swapBuffers later.
+     */
     OpenGLTexture maOffscreenTex;
 
     SalColor mnLineColor;
@@ -131,8 +141,10 @@ public:
     // get the height of the device
     GLfloat GetHeight() const { return mpProvider ? mpProvider->GetHeight() : 1; }
 
-    // check whether this instance is used for offscreen (Virtual Device)
-    // rendering ie. does it need its own context.
+    /**
+     * check whether this instance is used for offscreen (Virtual Device)
+     * rendering ie. does it need its own context.
+     */
     bool IsOffscreen() const { return mpProvider == nullptr || mpProvider->IsOffScreen(); }
 
     // operations to do before painting
@@ -145,10 +157,10 @@ protected:
     bool AcquireContext();
     bool ReleaseContext();
 
-    // retrieve the default context for offscreen rendering
+    /// retrieve the default context for offscreen rendering
     static rtl::Reference<OpenGLContext> GetDefaultContext();
 
-    /// create a new context for window rendering
+    /// create a new context for rendering to the underlying window
     virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0;
 
     /// check whether the given context can be used for off-screen rendering
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 452d064..25cb53a 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -45,7 +45,6 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr
     , mpProgram(nullptr)
     , mbUseScissor(false)
     , mbUseStencil(false)
-    , mbOffscreen(false)
     , mnLineColor(SALCOLOR_NONE)
     , mnFillColor(SALCOLOR_NONE)
 #ifdef DBG_UTIL
@@ -79,10 +78,9 @@ bool OpenGLSalGraphicsImpl::AcquireContext( )
 
     // We always prefer to bind our VirtualDevice / offscreen graphics
     // to the current OpenGLContext - to avoid switching contexts.
-    if (mpContext.is() && mbOffscreen)
+    if (mpContext.is() && OpenGLContext::hasCurrent() && !mpContext->isCurrent())
     {
-        if (OpenGLContext::hasCurrent() && !mpContext->isCurrent())
-            mpContext.clear();
+        mpContext.clear();
     }
 
     if( mpContext.is() )
@@ -116,8 +114,6 @@ bool OpenGLSalGraphicsImpl::ReleaseContext()
 
 void OpenGLSalGraphicsImpl::Init()
 {
-    mbOffscreen = IsOffscreen();
-
     // check if we can simply re-use the same context
     if( mpContext.is() )
     {
@@ -165,10 +161,7 @@ void OpenGLSalGraphicsImpl::PreDraw()
     mpContext->makeCurrent();
     CHECK_GL_ERROR();
 
-    if( !mbOffscreen )
-        mpContext->AcquireDefaultFramebuffer();
-    else
-        CheckOffscreenTexture();
+    CheckOffscreenTexture();
     CHECK_GL_ERROR();
 
     glViewport( 0, 0, GetWidth(), GetHeight() );
@@ -180,8 +173,12 @@ void OpenGLSalGraphicsImpl::PreDraw()
 
 void OpenGLSalGraphicsImpl::PostDraw()
 {
-    if( !mbOffscreen && mpContext->mnPainting == 0 )
+    if( mpContext->mnPainting == 0 )
+    {
+        if (!IsOffscreen()) ...
+#warning "Trigger re-rendering of the window if we have one"
         glFlush();
+    }
     if( mbUseScissor )
     {
         glDisable( GL_SCISSOR_TEST );
@@ -211,7 +208,7 @@ void OpenGLSalGraphicsImpl::ApplyProgramMatrices(float fPixelOffset)
 void OpenGLSalGraphicsImpl::freeResources()
 {
     // TODO Delete shaders, programs and textures if not shared
-    if( mbOffscreen && mpContext.is() && mpContext->isInitialized() )
+    if( mpContext.is() && mpContext->isInitialized() )
     {
         mpContext->makeCurrent();
         mpContext->ReleaseFramebuffer( maOffscreenTex );
@@ -1536,17 +1533,9 @@ void OpenGLSalGraphicsImpl::DoCopyBits( const SalTwoRect& rPosAry, OpenGLSalGrap
         return;
     }
 
-    if( rImpl.mbOffscreen )
-    {
-        PreDraw();
-        DrawTexture( rImpl.maOffscreenTex, rPosAry );
-        PostDraw();
-        return;
-    }
-
-    SAL_WARN( "vcl.opengl", "*** NOT IMPLEMENTED *** copyBits" );
-    // TODO: Copy from one FBO to the other (glBlitFramebuffer)
-    //       ie. copying from one visible window to another visible window
+    PreDraw();
+    DrawTexture( rImpl.maOffscreenTex, rPosAry );
+    PostDraw();
 }
 
 void OpenGLSalGraphicsImpl::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
@@ -1875,10 +1864,8 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
 
 OpenGLContext *OpenGLSalGraphicsImpl::beginPaint()
 {
-    if( mbOffscreen || !AcquireContext() )
-        return nullptr;
-    else
-        return mpContext.get();
+    AcquireContext();
+    return mpContext.get();
 }
 
 bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference<OpenGLContext> &xContext)
commit 87279c541ee2027155bf7381413b2e2e582367ba
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Nov 13 12:00:59 2015 +0000

    Step #1 - de-virtualize UseContext
    
    Change-Id: If343746b6544d77fec76ee89351cd7262d1bf350

diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index ecefede..8102d2e 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -31,7 +31,6 @@ public:
 
 protected:
     virtual rtl::Reference<OpenGLContext> CreateWinContext() override;
-    virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) override;
 
     bool RenderTextureCombo(TextureCombo& rCombo, int nX, int nY);
 
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index f07468d..eccd0ef 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -29,7 +29,6 @@ public:
 
 protected:
     virtual rtl::Reference<OpenGLContext> CreateWinContext() override;
-    virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) override;
 
     bool RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY, TextureCombo& rCombo);
 
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 667b2ec..9eb4353 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -131,7 +131,8 @@ public:
     // get the height of the device
     GLfloat GetHeight() const { return mpProvider ? mpProvider->GetHeight() : 1; }
 
-    // check whether this instance is used for offscreen rendering
+    // check whether this instance is used for offscreen (Virtual Device)
+    // rendering ie. does it need its own context.
     bool IsOffscreen() const { return mpProvider == nullptr || mpProvider->IsOffScreen(); }
 
     // operations to do before painting
@@ -147,11 +148,15 @@ protected:
     // retrieve the default context for offscreen rendering
     static rtl::Reference<OpenGLContext> GetDefaultContext();
 
-    // create a new context for window rendering
+    /// create a new context for window rendering
     virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0;
 
-    // check whether the given context can be used by this instance
-    virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) = 0;
+    /// check whether the given context can be used for off-screen rendering
+    bool UseContext( const rtl::Reference<OpenGLContext> &pContext )
+    {
+        return pContext->isInitialized() &&  // not released by the OS etc.
+               IsForeignContext( pContext ); // a genuine VCL context.
+    }
 
 public:
     OpenGLSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider *pProvider);
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 3771d3c..452d064 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -97,15 +97,12 @@ bool OpenGLSalGraphicsImpl::AcquireContext( )
     while( pContext )
     {
         // check if this context can be used by this SalGraphicsImpl instance
-        if( UseContext( pContext )  )
+        if( UseContext( pContext ) )
             break;
         pContext = pContext->mpPrevContext;
     }
 
-    if( pContext )
-        mpContext = pContext;
-    else
-        mpContext = mbOffscreen ? GetDefaultContext() : CreateWinContext();
+    mpContext = pContext ? pContext : GetDefaultContext();
 
     return mpContext.is();
 }
@@ -124,14 +121,12 @@ void OpenGLSalGraphicsImpl::Init()
     // check if we can simply re-use the same context
     if( mpContext.is() )
     {
-        if( !mpContext->isInitialized() ||
-            !UseContext( mpContext ) )
+        if( !UseContext( mpContext ) )
             ReleaseContext();
     }
 
-    // reset the offscreen texture
-    if( !mbOffscreen ||
-        maOffscreenTex.GetWidth()  != GetWidth() ||
+    // Always create the offscreen texture
+    if( maOffscreenTex.GetWidth()  != GetWidth() ||
         maOffscreenTex.GetHeight() != GetHeight() )
     {
         if( maOffscreenTex && // don't work to release empty textures
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index f57c82d..666cdbf 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -29,21 +29,10 @@ void WinOpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics*
 rtl::Reference<OpenGLContext> WinOpenGLSalGraphicsImpl::CreateWinContext()
 {
     rtl::Reference<OpenGLContext> pContext = OpenGLContext::Create();
-    pContext->requestSingleBufferedRendering();
     pContext->init( mrParent.mhLocalDC, mrParent.mhWnd );
     return pContext;
 }
 
-bool WinOpenGLSalGraphicsImpl::UseContext( const rtl::Reference<OpenGLContext> &pContext )
-{
-    if( !pContext.is() || !pContext->isInitialized() || IsForeignContext( pContext ) )
-        return false;
-    if( IsOffscreen() )
-        return true;
-    return pContext->getOpenGLWindow().hWnd == mrParent.mhWnd &&
-           pContext->getOpenGLWindow().hDC == mrParent.mhLocalDC;
-}
-
 void WinOpenGLSalGraphicsImpl::Init()
 {
     if ( !IsOffscreen() && mpContext.is() && mpContext->isInitialized() &&
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 2418bc6..595ca45c 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -58,18 +58,6 @@ rtl::Reference<OpenGLContext> X11OpenGLSalGraphicsImpl::CreateWinContext()
     return pContext;
 }
 
-bool X11OpenGLSalGraphicsImpl::UseContext( const rtl::Reference<OpenGLContext> &pContext )
-{
-    X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
-
-    if( !pContext->isInitialized() || IsForeignContext( pContext ) )
-        return false;
-    if( !pProvider )
-        return pContext->getOpenGLWindow().win != None;
-    else
-        return pContext->getOpenGLWindow().win == pProvider->GetX11Window();
-}
-
 void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
 {
     OpenGLSalGraphicsImpl *pImpl = pSrcGraphics ? static_cast< OpenGLSalGraphicsImpl* >(pSrcGraphics->GetImpl()) : static_cast< OpenGLSalGraphicsImpl *>(mrParent.GetImpl());
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 4a68ab8..c3ad82c51 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -124,11 +124,6 @@ void OpenGLContext::requestLegacyContext()
     mbRequestLegacyContext = true;
 }
 
-void OpenGLContext::requestSingleBufferedRendering()
-{
-    mbUseDoubleBufferedRendering = false;
-}
-
 #if defined( _WIN32 )
 static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
commit 2d49006f7cb04d7b3b71481f1f3aecf0f6d70dff
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Nov 30 12:01:07 2015 +0000

    uninitialized m_pGraphics -> cppcanvas_emfplus kaboom
    
    Change-Id: I370f63ed12e187684332112b9510a9892a665129

diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index 6da958d..c5c01a4 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -494,6 +494,7 @@ void GtkSalFrame::doKeyCallback( guint state,
 
 GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
+    , m_pGraphics(nullptr)
 {
     getDisplay()->registerFrame( this );
     m_bDefaultPos       = true;
@@ -507,6 +508,7 @@ GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
 
 GtkSalFrame::GtkSalFrame( SystemParentData* pSysData )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
+    , m_pGraphics(nullptr)
 {
     getDisplay()->registerFrame( this );
     // permanently ignore errors from our unruly children ...
commit 367dc08f9a7e34fe108c289a59548716e9abdf54
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Nov 30 13:52:34 2015 +0200

    Use -ldl -pthread only on Linux
    
    Change-Id: I968449ac3c12011cb32bf9c29db66ad2ae4553f1

diff --git a/smoketest/Executable_libtest.mk b/smoketest/Executable_libtest.mk
index 3b3bd16..4ba29ee 100644
--- a/smoketest/Executable_libtest.mk
+++ b/smoketest/Executable_libtest.mk
@@ -17,10 +17,12 @@ $(eval $(call gb_Executable_use_libraries,libtest,\
 	$(gb_UWINAPI) \
 ))
 
+ifeq ($(OS),LINUX)
 $(eval $(call gb_Executable_add_libs,libtest,\
 	-ldl \
 	-pthread \
 ))
+endif
 
 $(eval $(call gb_Executable_add_exception_objects,libtest,\
 	smoketest/libtest \
commit ac95a8b2e9e68111a24aa20c04eb18fba4a5c6e9
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Mon Nov 30 12:30:35 2015 +0100

    Move uses of SwFrame pointer-to-member after definition of class SwFrame
    
    ...to avoid trouble with MSVC's pointer-to-member model, where the details of a
    pointer-to-member depend on details of the pointed-to class type.
    
    Change-Id: Id5b3be1696794d23fbad96f047d114e27395b134

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 12bc2c6..e942315 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -94,98 +94,6 @@ typedef struct _xmlTextWriter *xmlTextWriterPtr;
 #define FRM_HEADFOOT    0x0018
 #define FRM_BODYFTNC    0x00a0
 
-class SwFrame;
-typedef long (SwFrame:: *SwFrameGet)() const;
-typedef bool (SwFrame:: *SwFrameMax)( long );
-typedef void (SwFrame:: *SwFrameMakePos)( const SwFrame*, const SwFrame*, bool );
-typedef long (*SwOperator)( long, long );
-typedef void (SwFrame:: *SwFrameSet)( long, long );
-
-struct SwRectFnCollection
-{
-    SwRectGet     fnGetTop;
-    SwRectGet     fnGetBottom;
-    SwRectGet     fnGetLeft;
-    SwRectGet     fnGetRight;
-    SwRectGet     fnGetWidth;
-    SwRectGet     fnGetHeight;
-    SwRectPoint   fnGetPos;
-
-    SwRectSet     fnSetTop;
-    SwRectSet     fnSetBottom;
-    SwRectSet     fnSetLeft;
-    SwRectSet     fnSetRight;
-    SwRectSet     fnSetWidth;
-    SwRectSet     fnSetHeight;
-
-    SwRectSet     fnSubTop;
-    SwRectSet     fnAddBottom;
-    SwRectSet     fnSubLeft;
-    SwRectSet     fnAddRight;
-    SwRectSet     fnAddWidth;
-    SwRectSet     fnAddHeight;
-
-    SwRectSet     fnSetPosX;
-    SwRectSet     fnSetPosY;
-
-    SwFrameGet      fnGetTopMargin;
-    SwFrameGet      fnGetBottomMargin;
-    SwFrameGet      fnGetLeftMargin;
-    SwFrameGet      fnGetRightMargin;
-    SwFrameSet      fnSetXMargins;
-    SwFrameSet      fnSetYMargins;
-    SwFrameGet      fnGetPrtTop;
-    SwFrameGet      fnGetPrtBottom;
-    SwFrameGet      fnGetPrtLeft;
-    SwFrameGet      fnGetPrtRight;
-    SwRectDist      fnTopDist;
-    SwRectDist      fnBottomDist;
-    SwFrameMax      fnSetLimit;
-    SwRectMax       fnOverStep;
-
-    SwRectSetPos    fnSetPos;
-    SwFrameMakePos  fnMakePos;
-    SwOperator      fnXDiff;
-    SwOperator      fnYDiff;
-    SwOperator      fnYInc;
-
-    SwRectSetTwice  fnSetLeftAndWidth;
-    SwRectSetTwice  fnSetTopAndHeight;
-};
-
-typedef SwRectFnCollection* SwRectFn;
-
-extern SwRectFn fnRectHori, fnRectVert, fnRectB2T, fnRectVL2R, fnRectVertL2R;
-#define SWRECTFN( pFrame )    bool bVert = pFrame->IsVertical(); \
-                            bool bRev = pFrame->IsReverse(); \
-                            bool bVertL2R = pFrame->IsVertLR(); \
-                            SwRectFn fnRect = bVert ? \
-                                ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \
-                                ( bRev ? fnRectB2T : fnRectHori );
-#define SWRECTFNX( pFrame )   bool bVertX = pFrame->IsVertical(); \
-                            bool bRevX = pFrame->IsReverse(); \
-                            bool bVertL2RX = pFrame->IsVertLR(); \
-                            SwRectFn fnRectX = bVertX ? \
-                                ( bRevX ? fnRectVL2R : ( bVertL2RX ? fnRectVertL2R : fnRectVert ) ): \
-                                ( bRevX ? fnRectB2T : fnRectHori );
-#define SWREFRESHFN( pFrame ) { if( bVert != pFrame->IsVertical() || \
-                                  bRev  != pFrame->IsReverse() ) \
-                                bVert = pFrame->IsVertical(); \
-                                bRev = pFrame->IsReverse(); \
-                                bVertL2R = pFrame->IsVertLR(); \
-                                fnRect = bVert ? \
-                                    ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \
-                                    ( bRev ? fnRectB2T : fnRectHori ); }
-#define SWRECTFN2( pFrame )   bool bVert = pFrame->IsVertical(); \
-                bool bVertL2R = pFrame->IsVertLR(); \
-                            bool bNeighb = pFrame->IsNeighbourFrame(); \
-                            SwRectFn fnRect = bVert == bNeighb ? \
-                                fnRectHori : ( bVertL2R ? fnRectVertL2R : fnRectVert );
-
-#define POS_DIFF( aFrame1, aFrame2 ) \
-            ( (aFrame1.*fnRect->fnGetTop)() != (aFrame2.*fnRect->fnGetTop)() || \
-            (aFrame1.*fnRect->fnGetLeft)() != (aFrame2.*fnRect->fnGetLeft)() )
-
 // for GetNextLeaf/GetPrevLeaf.
 enum MakePageType
 {
@@ -1173,6 +1081,97 @@ public:
     }
 };
 
+typedef long (SwFrame:: *SwFrameGet)() const;
+typedef bool (SwFrame:: *SwFrameMax)( long );
+typedef void (SwFrame:: *SwFrameMakePos)( const SwFrame*, const SwFrame*, bool );
+typedef long (*SwOperator)( long, long );
+typedef void (SwFrame:: *SwFrameSet)( long, long );
+
+struct SwRectFnCollection
+{
+    SwRectGet     fnGetTop;
+    SwRectGet     fnGetBottom;
+    SwRectGet     fnGetLeft;
+    SwRectGet     fnGetRight;
+    SwRectGet     fnGetWidth;
+    SwRectGet     fnGetHeight;
+    SwRectPoint   fnGetPos;
+
+    SwRectSet     fnSetTop;
+    SwRectSet     fnSetBottom;
+    SwRectSet     fnSetLeft;
+    SwRectSet     fnSetRight;
+    SwRectSet     fnSetWidth;
+    SwRectSet     fnSetHeight;
+
+    SwRectSet     fnSubTop;
+    SwRectSet     fnAddBottom;
+    SwRectSet     fnSubLeft;
+    SwRectSet     fnAddRight;
+    SwRectSet     fnAddWidth;
+    SwRectSet     fnAddHeight;
+
+    SwRectSet     fnSetPosX;
+    SwRectSet     fnSetPosY;
+
+    SwFrameGet      fnGetTopMargin;
+    SwFrameGet      fnGetBottomMargin;
+    SwFrameGet      fnGetLeftMargin;
+    SwFrameGet      fnGetRightMargin;
+    SwFrameSet      fnSetXMargins;
+    SwFrameSet      fnSetYMargins;
+    SwFrameGet      fnGetPrtTop;
+    SwFrameGet      fnGetPrtBottom;
+    SwFrameGet      fnGetPrtLeft;
+    SwFrameGet      fnGetPrtRight;
+    SwRectDist      fnTopDist;
+    SwRectDist      fnBottomDist;
+    SwFrameMax      fnSetLimit;
+    SwRectMax       fnOverStep;
+
+    SwRectSetPos    fnSetPos;
+    SwFrameMakePos  fnMakePos;
+    SwOperator      fnXDiff;
+    SwOperator      fnYDiff;
+    SwOperator      fnYInc;
+
+    SwRectSetTwice  fnSetLeftAndWidth;
+    SwRectSetTwice  fnSetTopAndHeight;
+};
+
+typedef SwRectFnCollection* SwRectFn;
+
+extern SwRectFn fnRectHori, fnRectVert, fnRectB2T, fnRectVL2R, fnRectVertL2R;
+#define SWRECTFN( pFrame )    bool bVert = pFrame->IsVertical(); \
+                            bool bRev = pFrame->IsReverse(); \
+                            bool bVertL2R = pFrame->IsVertLR(); \
+                            SwRectFn fnRect = bVert ? \
+                                ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \
+                                ( bRev ? fnRectB2T : fnRectHori );
+#define SWRECTFNX( pFrame )   bool bVertX = pFrame->IsVertical(); \
+                            bool bRevX = pFrame->IsReverse(); \
+                            bool bVertL2RX = pFrame->IsVertLR(); \
+                            SwRectFn fnRectX = bVertX ? \
+                                ( bRevX ? fnRectVL2R : ( bVertL2RX ? fnRectVertL2R : fnRectVert ) ): \
+                                ( bRevX ? fnRectB2T : fnRectHori );
+#define SWREFRESHFN( pFrame ) { if( bVert != pFrame->IsVertical() || \
+                                  bRev  != pFrame->IsReverse() ) \
+                                bVert = pFrame->IsVertical(); \
+                                bRev = pFrame->IsReverse(); \
+                                bVertL2R = pFrame->IsVertLR(); \
+                                fnRect = bVert ? \
+                                    ( bRev ? fnRectVL2R : ( bVertL2R ? fnRectVertL2R : fnRectVert ) ): \
+                                    ( bRev ? fnRectB2T : fnRectHori ); }
+#define SWRECTFN2( pFrame )   bool bVert = pFrame->IsVertical(); \
+                bool bVertL2R = pFrame->IsVertLR(); \
+                            bool bNeighb = pFrame->IsNeighbourFrame(); \
+                            SwRectFn fnRect = bVert == bNeighb ? \
+                                fnRectHori : ( bVertL2R ? fnRectVertL2R : fnRectVert );
+
+#define POS_DIFF( aFrame1, aFrame2 ) \
+            ( (aFrame1.*fnRect->fnGetTop)() != (aFrame2.*fnRect->fnGetTop)() || \
+            (aFrame1.*fnRect->fnGetLeft)() != (aFrame2.*fnRect->fnGetLeft)() )
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit ef242ae01047f6b8a0a9012e4e40509dd1c03145
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 30 11:04:01 2015 +0000

    vcl: move gtk+ to sharing the same SalGraphics per SalFrame.
    
    This makes the code consistent with other: Mac, Unx, Windows
    backends, and allows us to cache an OpenGL back-buffer on the
    SalGraphics - as per Mac.
    
    The lifecycle of a SalFrame and a SalGraphics should be
    consistent for real OS graphics now.
    
    Change-Id: I11fea2ce1c1386b1c6b0161a718e5c909c81612c
    Reviewed-on: https://gerrit.libreoffice.org/20283
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 472aae7..d1203a3 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -62,19 +62,6 @@ typedef ::Window GdkNativeWindow;
 
 class GtkSalFrame : public SalFrame, public X11WindowProvider
 {
-    static const int nMaxGraphics = 2;
-
-    struct GraphicsHolder
-    {
-        GtkSalGraphics*     pGraphics;
-        bool                bInUse;
-        GraphicsHolder()
-                : pGraphics( nullptr ),
-                  bInUse( false )
-        {}
-        ~GraphicsHolder();
-    };
-
     struct IMHandler
     {
 
@@ -187,7 +174,8 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider
     std::list< GtkSalFrame* >       m_aChildren;
     GdkWindowState                  m_nState;
     SystemEnvData                   m_aSystemData;
-    GraphicsHolder                  m_aGraphics[ nMaxGraphics ];
+    GtkSalGraphics                 *m_pGraphics;
+    bool                            m_bGraphics;
     sal_uInt16                      m_nKeyModifiers;
     GdkCursor                      *m_pCurrentCursor;
     GdkVisibilityState              m_nVisibility;
diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index 923581d..6da958d 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -492,11 +492,6 @@ void GtkSalFrame::doKeyCallback( guint state,
         CallCallback( SALEVENT_KEYUP, &aEvent );
 }
 
-GtkSalFrame::GraphicsHolder::~GraphicsHolder()
-{
-    delete pGraphics;
-}
-
 GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
 {
@@ -845,15 +840,13 @@ void GtkSalFrame::EnsureAppMenuWatch()
 
 void GtkSalFrame::InvalidateGraphics()
 {
-    for (unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); ++i)
+    if( m_pGraphics )
     {
-        if( !m_aGraphics[i].pGraphics )
-            continue;
 #if !GTK_CHECK_VERSION(3,0,0)
-        m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen );
-        m_aGraphics[i].pGraphics->SetWindow(nullptr);
+        m_pGraphics->SetDrawable( None, m_nXScreen );
+        m_pGraphics->SetWindow(nullptr);
 #endif
-        m_aGraphics[i].bInUse = false;
+        m_bGraphics = false;
     }
 }
 
@@ -926,6 +919,9 @@ GtkSalFrame::~GtkSalFrame()
         g_object_unref( G_OBJECT( m_pForeignParent ) );
     if( m_pForeignTopLevel )
         g_object_unref( G_OBJECT( m_pForeignTopLevel) );
+
+    delete m_pGraphics;
+    m_pGraphics = NULL;
 }
 
 void GtkSalFrame::moveWindow( long nX, long nY )
@@ -1172,6 +1168,9 @@ void GtkSalFrame::InitCommon()
     m_aSystemData.pAppContext   = nullptr;
     m_aSystemData.pShellWidget  = m_aSystemData.pWidget;
 
+    m_bGraphics = false;
+    m_pGraphics = NULL;
+
     // fake an initial geometry, gets updated via configure event or SetPosSize
     if( m_bDefaultPos || m_bDefaultSize )
     {
@@ -1596,45 +1595,32 @@ void GtkSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle )
 
 SalGraphics* GtkSalFrame::AcquireGraphics()
 {
-    if( m_pWindow )
+    if( m_bGraphics )
+        return nullptr;
+
+    if( !m_pGraphics )
     {
-        for( int i = 0; i < nMaxGraphics; i++ )
-        {
-            if( ! m_aGraphics[i].bInUse )
-            {
-                m_aGraphics[i].bInUse = true;
-                if( ! m_aGraphics[i].pGraphics )
-                {
 #if GTK_CHECK_VERSION(3,0,0)
-                    m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow );
-                    if( !m_aFrame.get() )
-                    {
-                        AllocateFrame();
-                        TriggerPaintEvent();
-                    }
-                    m_aGraphics[i].pGraphics->setDevice( m_aFrame );
+        m_pGraphics = new GtkSalGraphics( this, m_pWindow );
+        if( !m_aFrame.get() )
+        {
+            AllocateFrame();
+            TriggerPaintEvent();
+        }
+        m_pGraphics->setDevice( m_aFrame );
 #else // common case:
-                    m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow, m_nXScreen );
+        m_pGraphics = new GtkSalGraphics( this, m_pWindow, m_nXScreen );
 #endif
-                }
-                return m_aGraphics[i].pGraphics;
-            }
-        }
     }
-
-    return nullptr;
+    m_bGraphics = true;
+    return m_pGraphics;
 }
 
 void GtkSalFrame::ReleaseGraphics( SalGraphics* pGraphics )
 {
-    for( int i = 0; i < nMaxGraphics; i++ )
-    {
-        if( m_aGraphics[i].pGraphics == pGraphics )
-        {
-            m_aGraphics[i].bInUse = false;
-            break;
-        }
-    }
+    (void) pGraphics;
+    assert( pGraphics == m_pGraphics );
+    m_bGraphics = false;
 }
 
 bool GtkSalFrame::PostEvent(ImplSVEvent* pData)
@@ -1978,13 +1964,8 @@ void GtkSalFrame::AllocateFrame()
         m_aFrame->clear( basebmp::Color( 255, 127, 0 ) );
 #endif
 
-        // update device in existing graphics
-        for( unsigned int i = 0; i < SAL_N_ELEMENTS( m_aGraphics ); ++i )
-        {
-            if( !m_aGraphics[i].pGraphics )
-                continue;
-            m_aGraphics[i].pGraphics->setDevice( m_aFrame );
-        }
+        if( m_pGraphics )
+            m_pGraphics->setDevice( m_aFrame );
     }
 #endif
 }
@@ -2835,7 +2816,7 @@ void GtkSalFrame::UpdateSettings( AllSettings& rSettings )
     if( ! m_pWindow )
         return;
 
-    GtkSalGraphics* pGraphics = static_cast<GtkSalGraphics*>(m_aGraphics[0].pGraphics);
+    GtkSalGraphics* pGraphics = m_pGraphics;
     bool bFreeGraphics = false;
     if( ! pGraphics )
     {
@@ -2914,9 +2895,8 @@ void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Scre
     }
 
     // free xrender resources
-    for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ )
-        if( m_aGraphics[i].bInUse )
-            m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen );
+    if( m_pGraphics )
+        m_pGraphics->SetDrawable( None, m_nXScreen );
 
     // first deinit frame
     if( m_pIMHandler )
@@ -2957,13 +2937,10 @@ void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Scre
     }
 
     // update graphics
-    for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ )
+    if( m_pGraphics )
     {
-        if( m_aGraphics[i].bInUse )
-        {
-            m_aGraphics[i].pGraphics->SetDrawable( widget_get_xid(m_pWindow), m_nXScreen );
-            m_aGraphics[i].pGraphics->SetWindow( m_pWindow );
-        }
+        m_pGraphics->SetDrawable( widget_get_xid(m_pWindow), m_nXScreen );
+        m_pGraphics->SetWindow( m_pWindow );
     }
 
     if( ! m_aTitle.isEmpty() )
commit 268e4e90f9696998333026ac45b52c4f349d0069
Author: Noel Grandin <noel at peralex.com>
Date:   Mon Nov 30 13:03:32 2015 +0200

    allocate and initialise FormatEntry table at compile-time
    
    no need to init this at runtime, it's purely static data
    
    Change-Id: I73ff5b0d8f273d7ee925f485f3ed712f117f5b40

diff --git a/dtrans/source/win32/ftransl/ftransl.cxx b/dtrans/source/win32/ftransl/ftransl.cxx
index 968c2f6..6a17ca4 100644
--- a/dtrans/source/win32/ftransl/ftransl.cxx
+++ b/dtrans/source/win32/ftransl/ftransl.cxx
@@ -69,25 +69,35 @@ namespace MODULE_PRIVATE
     }
 }
 
-FormatEntry::FormatEntry()
+struct FormatEntry
 {
-}
+   FormatEntry() {}
+
+   FormatEntry(
+        const char *mime_content_type,
+        const char *human_presentable_name,
+        const char *native_format_name,
+        CLIPFORMAT std_clipboard_format_id,
+        css::uno::Type const & cppu_type
+    );
+
+    css::datatransfer::DataFlavor aDataFlavor;
+    OUString                      aNativeFormatName;
+    sal_Int32                     aStandardFormatId;
+};
 
 FormatEntry::FormatEntry(
-    const char* mime_content_type,
-    const char* human_presentable_name,
-    const char* native_format_name,
+    const char *mime_content_type,
+    const char *human_presentable_name,
+    const char *native_format_name,
     CLIPFORMAT std_clipboard_format_id,
     css::uno::Type const & cppu_type)
+  : aDataFlavor( OUString::createFromAscii(mime_content_type),  OUString::createFromAscii(human_presentable_name), cppu_type)
 {
-    aDataFlavor.MimeType             = OUString::createFromAscii(mime_content_type);
-    aDataFlavor.HumanPresentableName = OUString::createFromAscii(human_presentable_name);
-    aDataFlavor.DataType             = cppu_type;
-
     if (native_format_name)
-        aNativeFormatName = OUString::createFromAscii(native_format_name);
+        aNativeFormatName =  OUString::createFromAscii(native_format_name);
     else
-        aNativeFormatName = OUString::createFromAscii(human_presentable_name);
+        aNativeFormatName =  OUString::createFromAscii(human_presentable_name);
 
     aStandardFormatId = std_clipboard_format_id;
 }
@@ -97,7 +107,6 @@ FormatEntry::FormatEntry(
 CDataFormatTranslator::CDataFormatTranslator( const Reference< XComponentContext >& rxContext ) :
     m_xContext( rxContext )
 {
-    initTranslationTable( );
 }
 
 Any SAL_CALL CDataFormatTranslator::getSystemDataTypeFromDataFlavor( const DataFlavor& aDataFlavor )
@@ -212,258 +221,257 @@ Sequence< OUString > SAL_CALL CDataFormatTranslator::getSupportedServiceNames( )
 // format number we can stop if we find the first
 // CF_INVALID
 
-void SAL_CALL CDataFormatTranslator::initTranslationTable()
-{
+static const std::vector< FormatEntry > g_TranslTable {
     //SotClipboardFormatId::DIF
-    m_TranslTable.push_back(FormatEntry("application/x-openoffice-dif;windows_formatname=\"DIF\"", "DIF", "DIF", CF_DIF, CPPUTYPE_DEFAULT));
+        FormatEntry("application/x-openoffice-dif;windows_formatname=\"DIF\"", "DIF", "DIF", CF_DIF, CPPUTYPE_DEFAULT),
     // SotClipboardFormatId::BITMAP
 
     // #i124085# CF_DIBV5 disabled, leads to problems at export. To fully support, using
     // an own mime-type may be necessary. I have tried that, but saw no real advantages
     // with different apps when exchanging bitmap-based data. So, disabled for now. At
     // the same time increased png format exchange for better interoperability
-    //m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIBV5, CPPUTYPE_DEFAULT));
+    //    FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIBV5, CPPUTYPE_DEFAULT),
 
-    m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIB, CPPUTYPE_DEFAULT));
-    m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_BITMAP, CPPUTYPE_DEFAULT));
+        FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIB, CPPUTYPE_DEFAULT),
+        FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_BITMAP, CPPUTYPE_DEFAULT),
     // SotClipboardFormatId::STRING
-    m_TranslTable.push_back(FormatEntry("text/plain;charset=utf-16", "Unicode-Text", "", CF_UNICODETEXT, CppuType_String));
+        FormatEntry("text/plain;charset=utf-16", "Unicode-Text", "", CF_UNICODETEXT, CppuType_String),
     // Format Locale - for internal use
-    m_TranslTable.push_back(FormatEntry("application/x-openoffice-locale;windows_formatname=\"Locale\"", "Locale", "Locale", CF_LOCALE, CPPUTYPE_DEFAULT));
+        FormatEntry("application/x-openoffice-locale;windows_formatname=\"Locale\"", "Locale", "Locale", CF_LOCALE, CPPUTYPE_DEFAULT),
     // SOT_FORMAT_WMF
-    m_TranslTable.push_back(FormatEntry("application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", "Windows MetaFile", "Image WMF", CF_METAFILEPICT, CPPUTYPE_DEFAULT));
+        FormatEntry("application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", "Windows MetaFile", "Image WMF", CF_METAFILEPICT, CPPUTYPE_DEFAULT),
     // SOT_FORMAT_EMF
-    m_TranslTable.push_back(FormatEntry("application/x-openoffice-emf;windows_formatname=\"Image EMF\"", "Windows Enhanced MetaFile", "Image EMF", CF_ENHMETAFILE, CPPUTYPE_DEFAULT));
+        FormatEntry("application/x-openoffice-emf;windows_formatname=\"Image EMF\"", "Windows Enhanced MetaFile", "Image EMF", CF_ENHMETAFILE, CPPUTYPE_DEFAULT),
     // SotClipboardFormatId::FILE_LIST

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list