[Libreoffice-commits] core.git: Branch 'private/mmeeks/opengl-backbuffer' - 178 commits - accessibility/inc accessibility/source bean/BUCK bean/com bean/pom.officebean.xml bin/gbuild-to-ide bin/mvn.py bridges/source BUCK .buckconfig .buckversion canvas/source chart2/source codemaker/source compilerplugins/clang configure.ac connectivity/source cppuhelper/source cui/source cui/uiconfig dbaccess/source dbaccess/util desktop/source download.lst embedserv/source extensions/source external/boost external/clucene external/glm external/icu external/libetonyek external/liborcus external/mdnsresponder external/Module_external.mk external/nss external/poppler external/python3 filter/Configuration_filter.mk filter/Library_gie.mk filter/source forms/source fpicker/source framework/source .gitignore helpcontent2 icon-themes/breeze icon-themes/crystal icon-themes/elementary icon-themes/galaxy icon-themes/hicontrast icon-themes/human icon-themes/industrial icon-themes/oxygen icon-themes/README icon-themes/sifr icon-themes/tango icon-themes/tango_testing idlc/inc idlc/source include/canvas include/com include/osl include/sal include/svl include/svx include/vcl javaunohelper/BUCK javaunohelper/pom.juh.xml jurt/BUCK jurt/pom.jurt.xml Makefile.fetch officecfg/registry oox/source readlicense_oo/license RepositoryExternal.mk ridljar/BUCK ridljar/pom.ridl.xml ridljar/pom.unoloader.xml ridljar/source sal/cpprt sal/inc sal/Library_sal.mk sal/osl sc/CppunitTest_sc_ucalc.mk sc/inc sc/qa sc/source sd/CppunitTest_sd_uimpress.mk sd/Library_sd.mk sd/source sfx2/source slideshow/source smoketest/README solenv/bin solenv/buck solenv/gbuild solenv/gcc-wrappers solenv/maven starmath/inc svl/source svtools/source svx/source sw/CppunitTest_sw_filters_test.mk sw/CppunitTest_sw_globalfilter.mk sw/CppunitTest_sw_ooxmlimport.mk sw/inc sw/Library_sw.mk sw/ooxmlexport_setup.mk sw/qa sw/source sysui/desktop toolkit/source translations ucb/source unoil/BUCK unoil/pom.unoil.xml vcl/generic vcl/headless vcl/inc vcl/Lib rary_vcl.mk vcl/opengl vcl/source vcl/unx vcl/win vcl/WinResTarget_vcl.mk vcl/workben wizards/com writerfilter/Library_writerfilter.mk writerfilter/source

Michael Meeks michael.meeks at collabora.com
Thu Dec 3 17:56:33 PST 2015


Rebased ref, commits from common ancestor:
commit 717c023c984e7810395751d5b0e25e1356403142
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Dec 4 01:50:05 2015 +0000

    Implement idle GL flushing.
    
    Change-Id: I1d3102149cba902e640cbd9bbf47ca66deedbe00

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index d280743..fad5a07 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -52,6 +52,8 @@ struct TextureCombo
     std::unique_ptr<OpenGLTexture> mpMask;
 };
 
+class OpenGLFlushIdle;
+
 class VCL_DLLPUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
 {
     friend class OpenGLTests;
@@ -73,6 +75,9 @@ protected:
     /// Is it someone else's context we shouldn't be fiddling with ?
     static bool IsForeignContext(const rtl::Reference<OpenGLContext> &xContext);
 
+    /// This idle handler is used to swap buffers after rendering.
+    OpenGLFlushIdle *mpFlush;
+
     // clipping
     vcl::Region maClipRegion;
     bool mbUseScissor;
@@ -347,8 +352,12 @@ public:
 
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override;
 
-    /// flush contents of the back-buffer to the screen & swap.
+    /// queue an idle flush of contents of the back-buffer to the screen
     virtual void flush() override;
+
+public:
+    /// do flush of contents of the back-buffer to the screen & swap.
+    void doFlush();
 };
 
 #endif
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 31813fb..13ba0c8 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -39,12 +39,33 @@
 
 #include <stdlib.h>
 
+class OpenGLFlushIdle : public Idle
+{
+    OpenGLSalGraphicsImpl *m_pImpl;
+public:
+    OpenGLFlushIdle( OpenGLSalGraphicsImpl *pImpl )
+        : Idle( "gl idle swap" )
+        , m_pImpl( pImpl )
+    {
+        SetPriority( SchedulerPriority::HIGHEST );
+    }
+    ~OpenGLFlushIdle()
+    {
+    }
+    virtual void Invoke() override
+    {
+        m_pImpl->doFlush();
+        Stop();
+    }
+};
+
 OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvider *pProvider)
     : mpContext(nullptr)
     , mrParent(rParent)
     , mpProvider(pProvider)
     , mpFramebuffer(nullptr)
     , mpProgram(nullptr)
+    , mpFlush(new OpenGLFlushIdle(this))
     , mbUseScissor(false)
     , mbUseStencil(false)
     , mnLineColor(SALCOLOR_NONE)
@@ -61,13 +82,10 @@ 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
+    if( !IsOffscreen() && mnDrawCountAtFlush != mnDrawCount )
+        VCL_GL_INFO( "Destroying un-flushed on-screen graphics" );
+
+    delete mpFlush;
 
     ReleaseContext();
 }
@@ -1946,6 +1964,20 @@ void OpenGLSalGraphicsImpl::flush()
     if( IsOffscreen() )
         return;
 
+    // outside of the application's event loop (e.g. IntroWindow)
+    // nothing would trigger paint event handling
+    // => fall back to synchronous painting
+    if( ImplGetSVData()->maAppData.mnDispatchLevel <= 0 )
+        doFlush();
+    else if( !mpFlush->IsActive() )
+        mpFlush->Start();
+}
+
+void OpenGLSalGraphicsImpl::doFlush()
+{
+    if( IsOffscreen() )
+        return;
+
     assert( mpWindowContext.is() );
 
     if( !maOffscreenTex )
commit b75087d098c4cdc44769c2bb02b6f8654dc20d37
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 30 16:22:11 2015 +0000

    Remove lots of paint debugging - squash me ...
    
    Change-Id: I968205786e7cd9857a0325b55d1a45d1adc4306c

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index b21eb12..31813fb 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -154,10 +154,6 @@ 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");
     }
 
@@ -438,7 +434,6 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
             mpContext->ReleaseFramebuffer( maOffscreenTex );
             maOffscreenTex = OpenGLTexture();
             VCL_GL_INFO( "re-size offscreen texture" );
-            SAL_DEBUG( "paint: " << this << " re-size offscreen texture" );
         }
     }
 
@@ -446,8 +441,6 @@ 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;
     }
@@ -1957,7 +1950,6 @@ void OpenGLSalGraphicsImpl::flush()
 
     if( !maOffscreenTex )
     {
-        SAL_DEBUG("paint: " << this << " flush and swap - no texture !");
         VCL_GL_INFO( "flushAndSwap - odd no texture !" );
         return;
     }
@@ -1965,12 +1957,9 @@ void OpenGLSalGraphicsImpl::flush()
     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;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index bc77397..fce0e69 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -63,12 +63,10 @@ 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();
commit 2aaa42e0856ca942ce4410be7fb51306a784ac65
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 30 16:15:03 2015 +0000

    Avoid excessive flushing by hold paint guard over window update.
    
    Change-Id: Id267e3e9245e987d98fe141d1356a7fc29d419a4

diff --git a/vcl/source/window/paint.cxx b/vcl/source/window/paint.cxx
index 6402639..34462e6 100644
--- a/vcl/source/window/paint.cxx
+++ b/vcl/source/window/paint.cxx
@@ -1290,6 +1290,8 @@ void Window::Update()
     if ( !mpWindowImpl->mbReallyVisible )
         return;
 
+    OutputDevice::PaintScope aScope (this);
+
     bool bFlush = false;
     if ( mpWindowImpl->mpFrameWindow->mpWindowImpl->mbPaintFrame )
     {
commit 4a6ae8e293a852978c2c64c30ffbf5c856e58f04
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 30 16:14:36 2015 +0000

    vcl: Don't flush if we're mid-rendering - to avoid partial contents.
    
    Change-Id: I320736051a7955044c6306a569253ca9371191e4

diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index 0607d21..f9006e3 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -2286,11 +2286,14 @@ void X11SalFrame::SetTitle( const OUString& rTitle )
 
 void X11SalFrame::Flush()
 {
-    SAL_DEBUG("flush " << this);
-    if( pGraphics_ )
-        pGraphics_->Flush();
-    if( pFreeGraphics_ )
-        pFreeGraphics_->Flush();
+    // Don't flush if we're still painting, just wait.
+    if ( GetPaintNesting() == 0 )
+    {
+        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 f643d4d..cfcaaa1c 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -2628,13 +2628,20 @@ void GtkSalFrame::SetPointerPos( long nX, long nY )
 void GtkSalFrame::Flush()
 {
     if( m_pGraphics )
-        m_pGraphics->Flush();
-
+    {
+        // Don't flush if we're still painting, just wait.
+        if ( GetPaintNesting() == 0 )
+        {
+            m_pGraphics->Flush();
 #if GTK_CHECK_VERSION(3,0,0)
-    gdk_display_flush( getGdkDisplay() );
+            gdk_display_flush( getGdkDisplay() );
 #else
-    XFlush (GDK_DISPLAY_XDISPLAY (getGdkDisplay()));
+            XFlush (GDK_DISPLAY_XDISPLAY (getGdkDisplay()));
 #endif
+        }
+        else
+            SAL_WARN("vcl.opengl", "avoid erroneous flush during paint");
+    }
 }
 
 #ifndef GDK_Open
commit 2fe0d4b1d2ff7d4afbd2e4c07a064a83be3a1e4d
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Nov 30 16:13:42 2015 +0000

    vcl: gtk frames should DeInitialize properly, to handle GL cleanup.
    
    Change-Id: Ie6a5464c28b89f08639939690052023e685a3d33

diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx
index dc1539c..f643d4d 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -847,9 +847,11 @@ void GtkSalFrame::InvalidateGraphics()
     if( m_pGraphics )
     {
 #if !GTK_CHECK_VERSION(3,0,0)
-        m_pGraphics->SetDrawable( None, m_nXScreen );
+        m_pGraphics->DeInit();
         m_pGraphics->SetWindow(nullptr);
 #endif
+        delete m_pGraphics;
+        m_pGraphics = nullptr;
         m_bGraphics = false;
     }
 }
@@ -923,9 +925,6 @@ GtkSalFrame::~GtkSalFrame()
         g_object_unref( G_OBJECT( m_pForeignParent ) );
     if( m_pForeignTopLevel )
         g_object_unref( G_OBJECT( m_pForeignTopLevel) );
-
-    delete m_pGraphics;
-    m_pGraphics = nullptr;
 }
 
 void GtkSalFrame::moveWindow( long nX, long nY )
commit d3209fa3cb3198c4ee9f26058b0aff5428d6dfd0
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 783bd31..0607d21 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 66b2d39..dc1539c 100644
--- a/vcl/unx/gtk/gtksalframe.cxx
+++ b/vcl/unx/gtk/gtksalframe.cxx
@@ -2628,6 +2628,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/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx
index 1462f25..36ff322 100644
--- a/vcl/win/gdi/salgdi.cxx
+++ b/vcl/win/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 e063763ef9826893e5b2d005b725347b6cb65d8d
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 e737e3a79ff6a97da2fdeae3899e72e06190342f
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 56f452987d71fb0714a2cba152a2bb6ccc624712
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 c09b1806bc7700036558c7e986bcddd34da314dd
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 7ae75c4..d03baf9 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 c31b43cdd4ebe969e111242ed33f608a966ae20e
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 f01f5e55fd57023a5105b41355201dd8944ac7e7
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 b962ebc4bd429538f7fc3c6eca7ff787d13efba5
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 f1d48a77c6918f4f123dc0b3d58de5b833e5525f
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 990d1f3fe9dada8ad292e8e98e3aee27b651797e
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/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx
index 366b81c..1462f25 100644
--- a/vcl/win/gdi/salgdi.cxx
+++ b/vcl/win/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 437f36ea8687b79e773faa78159ce019f50ee308
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 d5c4dea85791b4ca4bd6f4b56f764973e9c6af54
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 51d2dd74722c75388883e36dd5e7a30940eacdba
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 1fd41f43eb73c373cb94d32d82c5fb7a7e243367
Author: David Ostrovsky <david at ostrovsky.org>
Date:   Tue Dec 1 23:59:11 2015 +0100

    Add build toolchain to upload LibreOffice API to Maven Central
    
    Set up the toolchain to create sources and javadocs artifacts in
    addition to JARs created during the build. Use Buck build tool for
    that: [1]. This is a fork of Google's build tool Blaze, created by
    Xooglers at Facebook. This build tool (like Blaze itself) uses
    Python to write build files.
    
    Add needed tools and build files to install LibreOffice API artifacts
    to local Maven repository or deploy them to Maven Central.
    
    To build all needed artifacts LibreOffice must be built regularly
    with GNU make first. To build the rest of the API (sources and
    javadocs):
    
      $> buck build api
    
    To replace version number with upcoming release version:
    
      $> solenv/bin/version.py 5.1.0
    
    To install the API to local Maven repository:
    
      $> buck build api_install
    
    To deploy the API to Maven Central:
    
      $> buck build api_deploy
    
    Detailed documentation is added to document the prerequisites and
    the workflow to upload LibreOffice API to Maven Central.
    
    * [1] https://buckbuild.com
    
    Change-Id: Ibdd552a01110836703bc069abe829b9921491cac
    Reviewed-on: https://gerrit.libreoffice.org/20343
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/.buckconfig b/.buckconfig
new file mode 100644
index 0000000..5fa3abc
--- /dev/null
+++ b/.buckconfig
@@ -0,0 +1,13 @@
+[alias]
+  api = //:api
+  api_install = //solenv/maven:api_install
+  api_deploy = //solenv/maven:api_deploy
+
+[buildfile]
+  includes = //solenv/buck/build.defs
+
+[project]
+  ignore = .git,workdir,instdir
+
+[cache]
+  mode = dir
diff --git a/.buckversion b/.buckversion
new file mode 100644
index 0000000..3c60745
--- /dev/null
+++ b/.buckversion
@@ -0,0 +1 @@
+6659a474fb2ba6e921bb38c1b55d4c9ba6073cfa
diff --git a/.gitignore b/.gitignore
index 30f0bec..9a56535 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@
 #
 
 # where stuff is built
+/buck-out
 /instdir
 /instdir_for_build
 /workdir
@@ -75,6 +76,7 @@
 \#*
 *.kdev4
 .kdev_include_paths
+.buckd
 .directory
 .cproject
 .project
diff --git a/BUCK b/BUCK
new file mode 100644
index 0000000..66b0dbd
--- /dev/null
+++ b/BUCK
@@ -0,0 +1,59 @@
+prebuilt_jar(
+  name = 'juh',
+  binary_jar = 'instdir/program/classes/juh.jar',
+  visibility = ['PUBLIC'],
+)
+
+prebuilt_jar(
+  name = 'jurt',
+  binary_jar = 'instdir/program/classes/jurt.jar',
+  visibility = ['PUBLIC'],
+)
+
+prebuilt_jar(
+  name = 'officebean',
+  binary_jar = 'instdir/program/classes/officebean.jar',
+  visibility = ['PUBLIC'],
+)
+
+prebuilt_jar(
+  name = 'ridl',
+  binary_jar = 'instdir/program/classes/ridl.jar',
+  visibility = ['PUBLIC'],
+)
+
+prebuilt_jar(
+  name = 'unoil',
+  binary_jar = 'instdir/program/classes/unoil.jar',
+  visibility = ['PUBLIC'],
+)
+
+prebuilt_jar(
+  name = 'unoloader',
+  binary_jar = 'instdir/program/classes/unoloader.jar',
+  visibility = ['PUBLIC'],
+)
+
+zip_file(
+  name = 'api',
+  srcs = [
+   ':juh',
+   '//javaunohelper:juh-src',
+   '//javaunohelper:juh-javadoc',
+   ':jurt',
+   '//jurt:jurt-src',
+   '//jurt:jurt-javadoc',
+   ':officebean',
+   '//bean:officebean-src',
+   '//bean:officebean-javadoc',
+   ':ridl',
+   '//ridljar:ridl-src',
+   '//ridljar:ridl-javadoc',
+   ':unoil',
+   '//unoil:unoil-src',
+   '//unoil:unoil-javadoc',
+   ':unoloader',
+   '//ridljar/source/unoloader:unoloader-src',
+   '//ridljar/source/unoloader:unoloader-javadoc',
+  ]
+)
diff --git a/bean/BUCK b/bean/BUCK
new file mode 100644
index 0000000..94a235b
--- /dev/null
+++ b/bean/BUCK
@@ -0,0 +1,23 @@
+
+java_sources(
+  name = 'officebean-src',
+  srcs = glob(['com/**']),
+  visibility = ['PUBLIC'],
+)
+
+java_doc(
+  name = 'officebean-javadoc',
+  title = 'LibreOffice API',
+  pkgs = [
+    'com.sun.star.comp.beans',
+  ],
+  paths = ['.'],
+  srcs = glob(['com/**']),
+  deps = [
+    '//:juh',
+    '//:officebean',
+    '//:unoil',
+    '//:ridl',
+  ],
+  visibility = ['PUBLIC'],
+)
diff --git a/bean/com/sun/star/comp/beans/LocalOfficeWindow.java b/bean/com/sun/star/comp/beans/LocalOfficeWindow.java
index 1fc5768..5d18036 100644
--- a/bean/com/sun/star/comp/beans/LocalOfficeWindow.java
+++ b/bean/com/sun/star/comp/beans/LocalOfficeWindow.java
@@ -79,7 +79,7 @@ public class LocalOfficeWindow
      * Receives a notification about the connection has been closed.
      * This method has to set the connection to <code>null</code>.
      *
-     * @source The event object.
+     * @param source The event object.
      */
     public void disposing(EventObject source)
     {
diff --git a/bean/com/sun/star/comp/beans/OOoBean.java b/bean/com/sun/star/comp/beans/OOoBean.java
index 9400695..4d49de8 100644
--- a/bean/com/sun/star/comp/beans/OOoBean.java
+++ b/bean/com/sun/star/comp/beans/OOoBean.java
@@ -23,11 +23,9 @@ import com.sun.star.uno.UnoRuntime;
 // @requirement FUNC.PERF.LRN/0.6
 // @requirement FUNC.PERF.LOC/0.6
 // @requirement FUNC.PERF.FIX/0.6
+// @requirement FUNC.RES.OTH/0.2
+// No other resources are needed yet.
 /** This is the basic JavaBean for all OOo application modules.
-
-    @requirement FUNC.RES.OTH/0.2
-        No other resources are needed yet.
-
     @since OOo 2.0.0
  */
 public class OOoBean
@@ -80,7 +78,8 @@ public class OOoBean
     }
 
     // @requirement FUNC.PER/0.2
-    /** @internal
+    // @internal
+    /**
      */
     @Deprecated
     public void writeExternal( java.io.ObjectOutput aObjOut )
@@ -89,7 +88,8 @@ public class OOoBean
     }
 
     // @requirement FUNC.PER/0.2
-    /** @internal
+    // @internal
+    /**
      */
     @Deprecated
     public void readExternal( java.io.ObjectInput aObjIn )
@@ -155,9 +155,8 @@ public class OOoBean
         nOOoCheckCycle = nMilliSecs;
     }
 
+    // @internal
     /** Sets a connection to an OOo instance.
-
-        @internal
      */
     private synchronized void setOOoConnection(OfficeConnection iNewConnection)
             throws HasConnectionException, NoConnectionException {
@@ -927,7 +926,7 @@ public class OOoBean
     /** returns the <type scope="com::sun::star::frame">Frame</a>
         of the bean.
 
-        @returns
+        @return
             a Java class which implements all interfaces which the service
         <type scope="com::sun::star::frame">Frame</a> implements.
         Thus, methods can be called directly without queryInterface.
@@ -950,7 +949,7 @@ public class OOoBean
        // @requirement API.SIM.SEAP/0.2
     /** returns the <type scope="com::sun::star::frame::Controller"> of the bean.
 
-        @returns
+        @return
             a Java class which implements all interfaces which the service
         <type scope="com::sun::star::frame">Controller</a> implements.
         Thus, methods can be called directly without queryInterface.
@@ -978,7 +977,7 @@ public class OOoBean
        /** returns the <type scope="com::sun::star::document::OfficeDocument">
         of the bean.
 
-        @returns
+        @return
             a Java class which implements all interfaces which the service
         <type scope="com::sun::star::document">OfficeDocument</a>
         implements.
@@ -1362,10 +1361,9 @@ xLayoutManager.showElement("private:resource/menubar/menubar");
 
     // Helper Classes
 
-
+    // @internal
     /** Helper class to listen on the connection to learn when it dies.
 
-        @internal
      */
     private class EventListener
         extends Thread
diff --git a/javaunohelper/BUCK b/javaunohelper/BUCK
new file mode 100644
index 0000000..7f1120d
--- /dev/null
+++ b/javaunohelper/BUCK
@@ -0,0 +1,20 @@
+
+java_sources(
+  name = 'juh-src',
+  srcs = glob(['com/**']),
+  visibility = ['PUBLIC'],
+)
+
+java_doc(
+  name = 'juh-javadoc',
+  title = 'LibreOffice Makes it easier to use UNO with Java',
+  pkgs = [
+    'com.sun.star',
+  ],
+  paths = ['.'],
+  srcs = glob(['com/**']),
+  deps = [
+    '//:juh',
+  ],
+  visibility = ['PUBLIC'],
+)
diff --git a/jurt/BUCK b/jurt/BUCK
new file mode 100644
index 0000000..f2349aa
--- /dev/null
+++ b/jurt/BUCK
@@ -0,0 +1,21 @@
+
+java_sources(
+  name = 'jurt-src',
+  srcs = glob(['com/**']),
+  visibility = ['PUBLIC'],
+)
+
+java_doc(
+  name = 'jurt-javadoc',
+  title = 'LibreOffice Java Uno Runtime',
+  pkgs = [
+    'com.sun.star',
+  ],
+  paths = ['.'],
+  srcs = glob(['com/**']),
+  deps = [
+    '//:jurt',
+    '//:unoloader',
+  ],
+  visibility = ['PUBLIC'],
+)
diff --git a/ridljar/BUCK b/ridljar/BUCK
new file mode 100644
index 0000000..382287d
--- /dev/null
+++ b/ridljar/BUCK
@@ -0,0 +1,20 @@
+
+java_sources(
+  name = 'ridl-src',
+  srcs = glob(['com/**']),
+  visibility = ['PUBLIC'],
+)
+
+java_doc(
+  name = 'ridl-javadoc',
+  title = 'LibreOffice types for the Java Uno typesystem',
+  pkgs = [
+    'com.sun.star',
+  ],
+  paths = ['.'],
+  srcs = glob(['com/**']),
+  deps = [
+    '//:ridl',
+  ],
+  visibility = ['PUBLIC'],
+)
diff --git a/ridljar/source/unoloader/BUCK b/ridljar/source/unoloader/BUCK
new file mode 100644
index 0000000..2678130
--- /dev/null
+++ b/ridljar/source/unoloader/BUCK
@@ -0,0 +1,20 @@
+
+java_sources(
+  name = 'unoloader-src',
+  srcs = glob(['com/**']),
+  visibility = ['PUBLIC'],
+)
+
+java_doc(
+  name = 'unoloader-javadoc',
+  title = 'LibreOffice Uno loader',
+  pkgs = [
+    'com.sun.star.lib.unoloader',
+  ],
+  paths = ['.'],
+  srcs = glob(['com/**']),
+  deps = [
+    '//:ridl',
+  ],
+  visibility = ['PUBLIC'],
+)
diff --git a/solenv/bin/version.py b/solenv/bin/version.py
new file mode 100755
index 0000000..18c0441
--- /dev/null
+++ b/solenv/bin/version.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+from optparse import OptionParser
+import os.path
+import re
+import sys
+
+M = {
+  'juh': 'javaunohelper',
+  'jurt': 'jurt',
+  'officebean': 'bean',
+  'ridl': 'ridljar',
+  'unoil': 'unoil',
+  'unoloader': 'ridljar',
+}
+
+parser = OptionParser()
+_, args = parser.parse_args()
+
+if not len(args):
+  parser.error('not enough arguments')
+elif len(args) > 1:
+  parser.error('too many arguments')
+
+DEST = r'\g<1>%s\g<3>' % args[0]
+
+
+def replace_in_file(filename, src_pattern):
+  try:
+    f = open(filename, "r")
+    s = f.read()
+    f.close()
+    s = re.sub(src_pattern, DEST, s)
+    f = open(filename, "w")
+    f.write(s)
+    f.close()
+  except IOError as err:
+    print('error updating %s: %s' % (filename, err), file=sys.stderr)
+
+src_pattern = re.compile(r'^(\s*<version>)([-.@\w]+)(</version>\s*)$',
+                         re.MULTILINE)
+
+for a in ['juh', 'jurt', 'officebean', 'ridl', 'unoil', 'unoloader']:
+  replace_in_file(os.path.join(M[a], 'pom.%s.xml' % a), src_pattern)
+
+src_pattern = re.compile(r"^(LIBREOFFICE_VERSION = ')([-.@\w]+)(')$",
+                         re.MULTILINE)
+replace_in_file('solenv/maven/VERSION', src_pattern)
diff --git a/solenv/buck/build.defs b/solenv/buck/build.defs
new file mode 100644
index 0000000..b7b81ec
--- /dev/null
+++ b/solenv/buck/build.defs
@@ -0,0 +1,49 @@
+def java_sources(
+    name,
+    srcs,
+    visibility = []
+  ):
+  java_library(
+    name = name,
+    resources = srcs,
+    visibility = visibility,
+  )
+
+def java_doc(
+    name,
+    title,
+    pkgs,
+    paths,
+    srcs = [],
+    deps = [],
+    visibility = [],
+    do_it_wrong = False,
+  ):
+  if do_it_wrong:
+    sourcepath = paths
+  else:
+    sourcepath = ['$SRCDIR/' + n for n in paths]
+  genrule(
+    name = name,
+    cmd = ' '.join([
+      'while ! test -f .buckconfig; do cd ..; done;',
+      'javadoc',
+      '-quiet',
+      '-protected',
+      '-encoding UTF-8',
+      '-charset UTF-8',
+      '-notimestamp',
+      '-windowtitle "' + title + '"',
+      '-link http://docs.oracle.com/javase/7/docs/api',
+      '-subpackages ',
+      ':'.join(pkgs),
+      '-sourcepath ',
+      ':'.join(sourcepath),
+      ' -classpath ',
+      ':'.join(['$(location %s)' % n for n in deps]),
+      '-d $TMP',
+    ]) + ';jar cf $OUT -C $TMP .',
+    srcs = srcs,
+    out = name + '.jar',
+    visibility = visibility,
+)
diff --git a/solenv/maven/BUCK b/solenv/maven/BUCK
new file mode 100644
index 0000000..f5bca38
--- /dev/null
+++ b/solenv/maven/BUCK
@@ -0,0 +1,41 @@
+include_defs('//solenv/maven/VERSION')
+include_defs('//solenv/maven/package.defs')
+
+URL = 'https://oss.sonatype.org/content/repositories/snapshots' \
+    if LIBREOFFICE_VERSION.endswith('-SNAPSHOT') else \
+        'https://oss.sonatype.org/service/local/staging/deploy/maven2'
+
+maven_package(
+  repository = 'sonatype-nexus-staging',
+  url = URL,
+  version = LIBREOFFICE_VERSION,
+  jar = {
+    'juh': '//:juh',
+    'jurt': '//:jurt',
+    'officebean': '//:officebean',
+    'ridl': '//:ridl',
+    'unoil': '//:unoil',
+    'unoloader': '//:unoloader',
+  },
+  src = {
+    'juh': '//javaunohelper:juh-src',
+    'jurt': '//jurt:jurt-src',
+    'officebean': '//bean:officebean-src',
+    'ridl': '//ridljar:ridl-src',
+    'unoil': '//unoil:unoil-src',
+    'unoloader': '//ridljar/source/unoloader:unoloader-src',
+  },
+  doc = {
+    'juh': '//javaunohelper:juh-javadoc',
+    'jurt': '//jurt:jurt-javadoc',

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list