include/vcl/opengl/OpenGLContext.hxx |   11 +
 vcl/inc/opengl/win/gdiimpl.hxx       |    9 +
 vcl/inc/opengl/x11/gdiimpl.hxx       |    6 
 vcl/inc/openglgdiimpl.hxx            |   28 +++
 vcl/inc/salgdiimpl.hxx               |    2 
 vcl/inc/svdata.hxx                   |    3 
 vcl/inc/unx/x11/x11gdiimpl.h         |    1 
 vcl/inc/win/salgdi.h                 |    1 
 vcl/opengl/gdiimpl.cxx               |  253 +++++++++++++++++++++++++----------
 vcl/opengl/win/gdiimpl.cxx           |   30 ++++
 vcl/opengl/x11/gdiimpl.cxx           |   60 +++++---
 vcl/source/opengl/OpenGLContext.cxx  |   39 +++++
 vcl/unx/generic/gdi/salgdi.cxx       |    2 
 vcl/win/source/gdi/gdiimpl.cxx       |    4 
 vcl/win/source/gdi/gdiimpl.hxx       |    2 
 vcl/win/source/gdi/salgdi.cxx        |   10 -
 16 files changed, 352 insertions(+), 109 deletions(-)

New commits:
commit 07eea5d1b0eb0265f43c6d8d63d775a316f9b42a
Author: Louis-Francis Ratté-Boulianne <l...@collabora.com>
Date:   Sat Nov 22 08:11:33 2014 -0500

    vcl: Make sure the active framebuffer is the right one before drawing
    
    Change-Id: Icc30bee1d58dbf8f5e7b65ba90cfdf0c9135b464

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 85d2a1c..8f4c6c4 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -212,6 +212,9 @@ void OpenGLSalGraphicsImpl::PreDraw()
     // TODO: lfrb: make sure the render target has the right size
     if( mbOffscreen )
         CheckOffscreenTexture();
+    else
+        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+    CHECK_GL_ERROR();
     glViewport( 0, 0, GetWidth(), GetHeight() );
     ImplInitClipRegion();
 
commit aff5f1973421e661791a81a74d28e8a2e80cef8b
Author: Louis-Francis Ratté-Boulianne <l...@collabora.com>
Date:   Sat Nov 22 08:10:48 2014 -0500

    vcl: Re-flip native X11 widgets upside down in OpenGL backend
    
    Change-Id: I1819f8e3357dc2f805b0ecebca0659fe073ec611

diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index b04bab6..605cbd5 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -199,14 +199,14 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( 
X11Pixmap* pPixmap, X11Pixm
         glXBindTexImageEXT( pDisplay, pGlxMask, GLX_FRONT_LEFT_EXT, NULL );
         aMaskTexture.Unbind();
 
-        DrawTextureDiff( aTexture, aMaskTexture, aPosAry, !bInverted );
+        DrawTextureDiff( aTexture, aMaskTexture, aPosAry, bInverted );
 
         glXReleaseTexImageEXT( pDisplay, pGlxMask, GLX_FRONT_LEFT_EXT );
         glXDestroyPixmap( pDisplay, pGlxMask );
     }
     else
     {
-        DrawTexture( aTexture, aPosAry, !bInverted );
+        DrawTexture( aTexture, aPosAry, bInverted );
     }
 
     CHECK_GL_ERROR();
commit 11b2007fc5a827228822150a66b53997e67d0287
Author: Louis-Francis Ratté-Boulianne <l...@collabora.com>
Date:   Sat Nov 22 08:09:29 2014 -0500

    vcl: Improve precision and performance of clipping when region is a 
RegionBand
    
    Change-Id: I7a481ba86d03b0eb8f4b456e38cfa89b6cbc209d

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index a6495b7..ee7889e 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -24,6 +24,7 @@
 #include <vcl/dllapi.h>
 
 #include "opengl/texture.hxx"
+#include "regionband.hxx"
 
 #include <tools/poly.hxx>
 #include <vcl/opengl/OpenGLContext.hxx>
@@ -125,6 +126,7 @@ public:
     void DrawRect( const Rectangle& rRect );
     void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
     void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
+    void DrawRegionBand( const RegionBand& rRegion );
     void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, 
bool bInverted = false );
     void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool 
bInverted = false );
     void DrawTransformedTexture( OpenGLTexture& rTexture, OpenGLTexture& 
rMask, const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const 
basegfx::B2DPoint& rY );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index f7b8bdf..85d2a1c 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -247,7 +247,10 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const 
vcl::Region& rClip, GLuint nMa
 
     glClear( GL_STENCIL_BUFFER_BIT );
     BeginSolid( MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) );
-    DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
+    if( rClip.getRegionBand() )
+        DrawRegionBand( *rClip.getRegionBand() );
+    else
+        DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
     EndSolid();
 
     glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
@@ -793,6 +796,41 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const 
basegfx::B2DPolyPolygon& rPol
     CHECK_GL_ERROR();
 }
 
+void OpenGLSalGraphicsImpl::DrawRegionBand( const RegionBand& rRegion )
+{
+    RectangleVector aRects;
+    std::vector<GLfloat> aVertices;
+    rRegion.GetRegionRectangles( aRects );
+
+    if( aRects.empty() )
+        return;
+
+#define ADD_VERTICE(pt) \
+    aVertices.push_back( 2 * pt.X() / GetWidth() - 1.0 ); \
+    aVertices.push_back( 1.0 - (2 * pt.Y() / GetHeight()) );
+
+    for( size_t i = 0; i < aRects.size(); ++i )
+    {
+        aRects[i].Bottom() += 1;
+        aRects[i].Right() += 1;
+        ADD_VERTICE( aRects[i].TopLeft() );
+        ADD_VERTICE( aRects[i].TopRight() );
+        ADD_VERTICE( aRects[i].BottomLeft() );
+        ADD_VERTICE( aRects[i].BottomLeft() );
+        ADD_VERTICE( aRects[i].TopRight() );
+        ADD_VERTICE( aRects[i].BottomRight() );
+    }
+
+#undef ADD_VERTICE
+
+    glEnableVertexAttribArray( GL_ATTRIB_POS );
+    glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, 
&aVertices[0] );
+    glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
+    glDisableVertexAttribArray( GL_ATTRIB_POS );
+
+    CHECK_GL_ERROR();
+}
+
 void OpenGLSalGraphicsImpl::DrawTextureRect( OpenGLTexture& rTexture, const 
SalTwoRect& rPosAry, bool bInverted )
 {
     GLfloat aTexCoord[8];
commit 6563a9071d6da2cc92f4967da7be5f6f67154081
Author: Louis-Francis Ratté-Boulianne <l...@collabora.com>
Date:   Sat Nov 22 08:07:47 2014 -0500

    vcl: Track the GL context's clip region and update before drawing when 
needed
    
    Change-Id: Ibec92851dc87f6696ee55a8db10fe160cd97d09c

diff --git a/include/vcl/opengl/OpenGLContext.hxx 
b/include/vcl/opengl/OpenGLContext.hxx
index b790453..9be9c59 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -230,6 +230,7 @@ private:
 #endif
 
 public:
+    vcl::Region maClipRegion;
     int mnPainting;
 
     OpenGLContext* mpPrevContext;
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 7446903..a6495b7 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -38,6 +38,7 @@ protected:
     OpenGLContext* mpContext;
 
     // clipping
+    vcl::Region maClipRegion;
     bool mbUseScissor;
     bool mbUseStencil;
 
@@ -91,6 +92,7 @@ protected:
     GLuint mnRadialGradientEndColorUniform;
     GLuint mnRadialGradientCenterUniform;
 
+    void ImplInitClipRegion();
     void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
 
     bool CheckOffscreenTexture();
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 1151b73..f7b8bdf 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -213,13 +213,7 @@ void OpenGLSalGraphicsImpl::PreDraw()
     if( mbOffscreen )
         CheckOffscreenTexture();
     glViewport( 0, 0, GetWidth(), GetHeight() );
-    if( mbUseScissor )
-        glEnable( GL_SCISSOR_TEST );
-    if( mbUseStencil )
-    {
-        glStencilFunc( GL_EQUAL, 1, 0x1 );
-        glEnable( GL_STENCIL_TEST );
-    }
+    ImplInitClipRegion();
 
     CHECK_GL_ERROR();
 }
@@ -263,36 +257,44 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const 
vcl::Region& rClip, GLuint nMa
     CHECK_GL_ERROR();
 }
 
-bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
+void OpenGLSalGraphicsImpl::ImplInitClipRegion()
 {
-    SAL_INFO( "vcl.opengl", "::setClipRegion " << rClip );
-
-    if( rClip.IsEmpty() )
+    // make sure the context has the right clipping set
+    if( maClipRegion != mpContext->maClipRegion )
     {
-        ResetClipRegion();
-        return true;
+        mpContext->maClipRegion = maClipRegion;
+        if( maClipRegion.IsRectangle() )
+        {
+            Rectangle aRect( maClipRegion.GetBoundRect() );
+            glScissor( aRect.Left(), GetHeight() - aRect.Bottom() - 1, 
aRect.GetWidth() + 1, aRect.GetHeight() + 1 );
+        }
+        else if( !maClipRegion.IsEmpty() )
+        {
+            ImplSetClipBit( maClipRegion, 0x01 );
+        }
     }
 
-    if( rClip.IsRectangle() )
+    if( mbUseScissor )
+        glEnable( GL_SCISSOR_TEST );
+    if( mbUseStencil )
     {
-        Rectangle aRect( rClip.GetBoundRect() );
+        glStencilFunc( GL_EQUAL, 1, 0x1 );
+        glEnable( GL_STENCIL_TEST );
+    }
+}
+
+bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
+{
+    SAL_INFO( "vcl.opengl", "::setClipRegion " << rClip );
+    maClipRegion = rClip;
 
-        mbUseStencil = false;
+    mbUseStencil = false;
+    mbUseScissor = false;
+    if( maClipRegion.IsRectangle() )
         mbUseScissor = true;
-        maContext.makeCurrent();
-        glViewport( 0, 0, GetWidth(), GetHeight() );
-        glScissor( aRect.Left(), GetHeight() - aRect.Bottom() - 1, 
aRect.GetWidth(), aRect.GetHeight() );
-    }
-    else
-    {
+    else if ( !maClipRegion.IsEmpty() )
         mbUseStencil = true;
-        mbUseScissor = false;
-        maContext.makeCurrent();
-        glViewport( 0, 0, GetWidth(), GetHeight() );
-        ImplSetClipBit( rClip, 0x01 );
-    }
 
-    CHECK_GL_ERROR();
     return true;
 }
 
@@ -300,6 +302,7 @@ bool OpenGLSalGraphicsImpl::setClipRegion( const 
vcl::Region& rClip )
 void OpenGLSalGraphicsImpl::ResetClipRegion()
 {
     SAL_INFO( "vcl.opengl", "::ResetClipRegion" );
+    maClipRegion.SetEmpty();
     mbUseScissor = false;
     mbUseStencil = false;
 }
commit 385dd7da3aa1c202ec70e2c3213b6b70ab772108
Author: Louis-Francis Ratté-Boulianne <l...@collabora.com>
Date:   Sat Nov 22 08:04:23 2014 -0500

    vcl: Move the painting fence to the OpenGL context
    
    Change-Id: I462e68a1ad7a56fafe57504959cf169a70665f81

diff --git a/include/vcl/opengl/OpenGLContext.hxx 
b/include/vcl/opengl/OpenGLContext.hxx
index 9414dac..b790453 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -230,6 +230,8 @@ private:
 #endif
 
 public:
+    int mnPainting;
+
     OpenGLContext* mpPrevContext;
     OpenGLContext* mpNextContext;
 };
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index a1cd142..7446903 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -35,8 +35,6 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public 
SalGraphicsImpl
 {
 protected:
 
-    SalFrame* mpFrame;
-    int mnPainting;
     OpenGLContext* mpContext;
 
     // clipping
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6e6ea5f..1151b73 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -228,7 +228,7 @@ void OpenGLSalGraphicsImpl::PostDraw()
 {
     if( mbOffscreen )
         glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-    else if( mnPainting == 0 )
+    else if( mpContext->mnPainting == 0 )
         glFlush();
     if( mbUseScissor )
         glDisable( GL_SCISSOR_TEST );
@@ -1872,15 +1872,16 @@ bool OpenGLSalGraphicsImpl::drawGradient(const 
tools::PolyPolygon& rPolyPoly,
 
 void OpenGLSalGraphicsImpl::beginPaint()
 {
-    mnPainting++;
     SAL_INFO( "vcl.opengl", "BEGIN PAINT " << this );
+    mpContext->mnPainting++;
 }
 
 void OpenGLSalGraphicsImpl::endPaint()
 {
-    mnPainting--;
     SAL_INFO( "vcl.opengl", "END PAINT " << this );
-    if( mnPainting == 0 )
+    mpContext->mnPainting--;
+    assert( mpContext->mnPainting >= 0 );
+    if( mpContext->mnPainting == 0 && !mbOffscreen )
     {
         mpContext->makeCurrent();
         glFlush();
diff --git a/vcl/source/opengl/OpenGLContext.cxx 
b/vcl/source/opengl/OpenGLContext.cxx
index 9bbe1e2..caf3d30 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -53,6 +53,7 @@ OpenGLContext::OpenGLContext():
     mbRequestLegacyContext(false),
     mbUseDoubleBufferedRendering(true),
     mbRequestVirtualDevice(false),
+    mnPainting(0),
     mpPrevContext(NULL),
     mpNextContext(NULL)
 {
commit e26c8fdd1922282ef5f0ce97b503ef9d7bb9907b
Author: Louis-Francis Ratté-Boulianne <l...@collabora.com>
Date:   Sat Nov 22 07:58:38 2014 -0500

    vcl: Always use the same OpenGL context when drawing in a window
    
    Change-Id: Ief0e947149c133aaa8e81973e088c4df6432bfdc

diff --git a/include/vcl/opengl/OpenGLContext.hxx 
b/include/vcl/opengl/OpenGLContext.hxx
index c5e53e8..9414dac 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -174,6 +174,9 @@ public:
     bool init( HDC hDC, HWND hWnd );
 #endif
 
+    void AddRef();
+    void DeRef();
+
     void makeCurrent();
     void resetCurrent();
     void swapBuffers();
@@ -218,12 +221,17 @@ private:
     SystemChildWindow* m_pChildWindow;
     boost::scoped_ptr<SystemChildWindow> m_pChildWindowGC;
     bool mbInitialized;
+    int  mnRefCount;
     bool mbRequestLegacyContext;
     bool mbUseDoubleBufferedRendering;
     bool mbRequestVirtualDevice;
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
     bool mbPixmap; // is a pixmap instead of a window
 #endif
+
+public:
+    OpenGLContext* mpPrevContext;
+    OpenGLContext* mpNextContext;
 };
 
 #endif
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index 557e58a..66a0333 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -15,6 +15,8 @@
 #include "openglgdiimpl.hxx"
 #include "win/salgdi.h"
 
+class OpenGLContext;
+
 class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl
 {
     friend class WinLayout;
@@ -24,9 +26,16 @@ private:
 public:
     WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics);
 
+    virtual void Init() SAL_OVERRIDE;
+
 protected:
     virtual GLfloat GetWidth() const SAL_OVERRIDE;
     virtual GLfloat GetHeight() const SAL_OVERRIDE;
+    virtual bool    IsOffscreen() const SAL_OVERRIDE;
+
+    virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
+    virtual bool CompareWinContext( OpenGLContext* pContext ) SAL_OVERRIDE;
+    virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE;
 
 public:
     virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* 
pSrcGraphics ) SAL_OVERRIDE;
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index d25d5d0..f5e5bfb 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -28,12 +28,16 @@ public:
 protected:
     GLfloat GetWidth() const SAL_OVERRIDE;
     GLfloat GetHeight() const SAL_OVERRIDE;
+    bool    IsOffscreen() const SAL_OVERRIDE;
+
+    virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
+    virtual bool CompareWinContext( OpenGLContext* pContext ) SAL_OVERRIDE;
+    virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE;
 
 public:
     // implementation of X11GraphicsImpl
 
     virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* 
pSrcGraphics ) SAL_OVERRIDE;
-    void Init() SAL_OVERRIDE;
     bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) 
SAL_OVERRIDE;
     bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, 
int nY ) SAL_OVERRIDE;
 };
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 5a7382b..a1cd142 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -35,9 +35,9 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public 
SalGraphicsImpl
 {
 protected:
 
-    OpenGLContext maContext;
     SalFrame* mpFrame;
     int mnPainting;
+    OpenGLContext* mpContext;
 
     // clipping
     bool mbUseScissor;
@@ -144,21 +144,35 @@ public:
     // get the height of the device
     virtual GLfloat GetHeight() const = 0;
 
+    // check whether this instance is used for offscreen rendering
+    virtual bool IsOffscreen() const = 0;
+
     // operations to do before painting
     virtual void PreDraw();
 
     // operations to do after painting
     virtual void PostDraw();
 
-    // enable/disable offscreen rendering
-    virtual void SetOffscreen( bool bOffscreen );
+protected:
+    bool AcquireContext( bool bOffscreen );
+    bool ReleaseContext();
+
+    // create a new context for window rendering
+    virtual OpenGLContext* CreateWinContext() = 0;
 
+    // check whether the given context can be used by this instance
+    virtual bool CompareWinContext( OpenGLContext* pContext ) = 0;
+
+    // create a new context for window rendering
+    virtual OpenGLContext* CreatePixmapContext() = 0;
 
 public:
     OpenGLSalGraphicsImpl();
     virtual ~OpenGLSalGraphicsImpl ();
 
-    OpenGLContext& GetOpenGLContext() { return maContext; }
+    OpenGLContext& GetOpenGLContext() { return *mpContext; }
+
+    virtual void Init() SAL_OVERRIDE;
 
     virtual void freeResources() SAL_OVERRIDE;
 
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 2fd7f56..e92c65f 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -44,6 +44,8 @@ public:
 
     virtual ~SalGraphicsImpl();
 
+    virtual void Init() = 0;
+
     virtual void freeResources() = 0;
 
     virtual bool setClipRegion( const vcl::Region& ) = 0;
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index c1d9eed..212e036 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -89,6 +89,7 @@ class SalI18NImeStatus;
 class DockingManager;
 class VclEventListeners2;
 class SalData;
+class OpenGLContext;
 
 namespace vcl { class DisplayConnection; class SettingsConfigItem; class 
DeleteOnDeinitBase; }
 
@@ -161,6 +162,8 @@ struct ImplSVGDIData
     OutputDevice*           mpLastPrnGraphics;  // Last OutputDevice with a 
InfoPrinter Graphics
     VirtualDevice*          mpFirstVirDev;      // First VirtualDevice
     VirtualDevice*          mpLastVirDev;       // Last VirtualDevice
+    OpenGLContext*          mpFirstContext;     // First OpenGLContext
+    OpenGLContext*          mpLastContext;      // Last OpenGLContext
     Printer*                mpFirstPrinter;     // First Printer
     Printer*                mpLastPrinter;      // Last Printer
     ImplPrnQueueList*       mpPrinterQueueList; // List of all printer queue
diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h
index 239d217..22859c3 100644
--- a/vcl/inc/unx/x11/x11gdiimpl.h
+++ b/vcl/inc/unx/x11/x11gdiimpl.h
@@ -17,7 +17,6 @@ class X11GraphicsImpl
 public:
     virtual ~X11GraphicsImpl() {};
 
-    virtual void Init() = 0;
     virtual bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) = 
0;
     virtual bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, 
int nX, int nY ) = 0;
 };
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 1af7807..443c1c2 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -181,6 +181,7 @@ public:
 class WinSalGraphics : public SalGraphics
 {
     friend class WinSalGraphicsImpl;
+    friend class WinOpenGLSalGraphicsImpl;
     friend class ScopedFont;
     friend class OpenGLCompatibleDC;
     friend class WinLayout;
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 54be610..6e6ea5f 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -31,6 +31,7 @@
 
 #include <vcl/opengl/OpenGLHelper.hxx>
 #include "salgdi.hxx"
+#include "svdata.hxx"
 #include "opengl/salbmp.hxx"
 
 #include <glm/glm.hpp>
@@ -63,8 +64,7 @@
                  1.0f )
 
 OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
-    : mpFrame(NULL)
-    , mnPainting(0)
+    : mpContext(0)
     , mbUseScissor(false)
     , mbUseStencil(false)
     , mbOffscreen(false)
@@ -109,11 +109,106 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
 
 OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
 {
+    ReleaseContext();
+}
+
+bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
+{
+    ImplSVData* pSVData = ImplGetSVData();
+
+    if( mpContext )
+        mpContext->DeRef();
+
+    if( bOffscreen )
+    {
+        mpContext = CreatePixmapContext();
+        return (mpContext != NULL);
+    }
+
+    OpenGLContext* pContext = pSVData->maGDIData.mpLastContext;
+    while( pContext )
+    {
+        // check if this context can be used by this SalGraphicsImpl instance
+        if( CompareWinContext( pContext )  )
+            break;
+        pContext = pContext->mpPrevContext;
+    }
+
+    if( pContext )
+        pContext->AddRef();
+    else
+        pContext = CreateWinContext();
+
+    mpContext = pContext;
+    return (mpContext != NULL);
+}
+
+bool OpenGLSalGraphicsImpl::ReleaseContext()
+{
+    if( mpContext )
+        mpContext->DeRef();
+    mpContext = NULL;
+    return true;
+}
+
+void OpenGLSalGraphicsImpl::Init()
+{
+    const bool bOffscreen = IsOffscreen();
+
+    // check if we can simply re-use the same context
+    if( mpContext )
+    {
+        if( bOffscreen != mbOffscreen || ( !mbOffscreen && CompareWinContext( 
mpContext ) ) )
+            ReleaseContext();
+    }
+
+    if( !mpContext && !AcquireContext( bOffscreen ) )
+    {
+        SAL_WARN( "vcl.opengl", "Couldn't acquire context for SalGraphics" );
+        return;
+    }
+
+    mpContext->makeCurrent();
+
+    if( mbOffscreen == bOffscreen )
+    {
+        // Nothing more to do for onscreen case
+        if( !mbOffscreen )
+            return;
+
+        // Already enabled and same size
+        if( maOffscreenTex.GetWidth()  == GetWidth() &&
+            maOffscreenTex.GetHeight() == GetHeight() )
+            return;
+    }
+    else
+    {
+        mbOffscreen = bOffscreen;
+        if( bOffscreen )
+            glGenFramebuffers( 1, &mnFramebufferId );
+        else
+            glDeleteFramebuffers( 1, &mnFramebufferId );
+    }
+
+    // Create/update attached offscreen texture
+    if( mbOffscreen )
+    {
+        glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
+        maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
+        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
GL_TEXTURE_2D, maOffscreenTex.Id(), 0 );
+        GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
+        if( nStatus != GL_FRAMEBUFFER_COMPLETE )
+            SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
+        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+        CHECK_GL_ERROR();
+    }
 }
 
 void OpenGLSalGraphicsImpl::PreDraw()
 {
-    maContext.makeCurrent();
+    assert( mpContext && mpContext->isInitialized() );
+
+    mpContext->makeCurrent();
     // TODO: lfrb: make sure the render target has the right size
     if( mbOffscreen )
         CheckOffscreenTexture();
@@ -273,46 +368,17 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor 
/*nROPColor*/ )
 {
 }
 
-// enable/disbale offscreen rendering
-void OpenGLSalGraphicsImpl::SetOffscreen( bool bOffscreen )
-{
-    if( bOffscreen == mbOffscreen )
-    {
-        // Already disabled
-        if( !mbOffscreen )
-            return;
-
-        // Already enabled and same size
-        if( maOffscreenTex.GetWidth()  == GetWidth() &&
-            maOffscreenTex.GetHeight() == GetHeight() )
-            return;
-    }
-    else
-    {
-        mbOffscreen = bOffscreen;
-        if( bOffscreen )
-            glGenFramebuffers( 1, &mnFramebufferId );
-        else
-            glDeleteFramebuffers( 1, &mnFramebufferId );
-    }
-
-    if( mbOffscreen )
-    {
-        glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
-        maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
-        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
GL_TEXTURE_2D, maOffscreenTex.Id(), 0 );
-        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-    }
-
-    CHECK_GL_ERROR();
-}
-
 bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
 {
     glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
 
     if( maOffscreenTex.IsUnique() )
+    {
+        GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
+        if( nStatus != GL_FRAMEBUFFER_COMPLETE )
+            SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
         return true;
+    }
 
     SalTwoRect aPosAry;
     aPosAry.mnSrcX = aPosAry.mnDestX = 0;
@@ -1816,7 +1882,7 @@ void OpenGLSalGraphicsImpl::endPaint()
     SAL_INFO( "vcl.opengl", "END PAINT " << this );
     if( mnPainting == 0 )
     {
-        maContext.makeCurrent();
+        mpContext->makeCurrent();
         glFlush();
     }
 }
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index 67a192e..55b3c5a 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -68,4 +68,34 @@ GLfloat WinOpenGLSalGraphicsImpl::GetHeight() const
     return 1;
 }
 
+bool WinOpenGLSalGraphicsImpl::IsOffscreen() const
+{
+    WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() );
+    return ( pFrame == NULL );
+}
+
+OpenGLContext* WinOpenGLSalGraphicsImpl::CreateWinContext()
+{
+    OpenGLContext* pContext = new OpenGLContext();
+    pContext->requestSingleBufferedRendering();
+    pContext->init( mrParent.mhLocalDC, mrParent.mhWnd );
+    return pContext;
+}
+
+bool WinOpenGLSalGraphicsImpl::CompareWinContext( OpenGLContext* pContext )
+{
+    if( !pContext || !pContext->isInitialized() )
+        return false;
+    return ( pContext->getOpenGLWindow().hWnd == mrParent.mhWnd );
+}
+
+OpenGLContext* WinOpenGLSalGraphicsImpl::CreatePixmapContext()
+{
+    OpenGLContext* pContext = new OpenGLContext();
+    pContext->requestVirtualDevice();
+    pContext->requestSingleBufferedRendering();
+    pContext->init( mrParent.mhLocalDC, mrParent.mhWnd );
+    return pContext;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 838be1b..b04bab6 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -59,31 +59,53 @@ GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const
     return 1;
 }
 
-void X11OpenGLSalGraphicsImpl::Init()
+bool X11OpenGLSalGraphicsImpl::IsOffscreen() const
 {
     X11WindowProvider *pProvider = 
dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
-
-    // Called after eg. a vdev re-size where we need to update the underlying 
pixmap
-    maContext.resetToReInitialize();
-    if (pProvider)
-    {
-        Window aWin = pProvider->GetX11Window();
-        maContext.init( mrParent.GetXDisplay(), aWin, 
mrParent.m_nXScreen.getXScreen());
-        SetOffscreen( false );
-    }
+    if( pProvider )
+        return false;
     else if( mrParent.m_pVDev )
-    {
-        maContext.init( mrParent.GetXDisplay(), 
mrParent.m_pVDev->GetDrawable(),
-                        mrParent.m_pVDev->GetWidth(), 
mrParent.m_pVDev->GetHeight(),
-                        mrParent.m_nXScreen.getXScreen() );
-        SetOffscreen( true );
-    }
+        return true;
     else
     {
         SAL_WARN( "vcl.opengl", "what happened here?" );
+        return true;
     }
 }
 
+OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext()
+{
+    X11WindowProvider *pProvider = 
dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+
+    if( !pProvider )
+        return NULL;
+    Window aWin = pProvider->GetX11Window();
+    OpenGLContext* pContext = new OpenGLContext();
+    pContext->init( mrParent.GetXDisplay(), aWin,
+                    mrParent.m_nXScreen.getXScreen() );
+    return pContext;
+}
+
+bool X11OpenGLSalGraphicsImpl::CompareWinContext( OpenGLContext* pContext )
+{
+    X11WindowProvider *pProvider = 
dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+
+    if( !pProvider || !pContext->isInitialized() )
+        return false;
+    return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
+}
+
+OpenGLContext* X11OpenGLSalGraphicsImpl::CreatePixmapContext()
+{
+    if( mrParent.m_pVDev == NULL )
+        return NULL;
+    OpenGLContext* pContext = new OpenGLContext();
+    pContext->init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
+                    mrParent.m_pVDev->GetWidth(), 
mrParent.m_pVDev->GetHeight(),
+                    mrParent.m_nXScreen.getXScreen() );
+    return pContext;
+}
+
 void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, 
SalGraphics* pSrcGraphics )
 {
     OpenGLSalGraphicsImpl *pImpl = pSrcGraphics ? dynamic_cast< 
OpenGLSalGraphicsImpl* >(pSrcGraphics->GetImpl()) : static_cast< 
OpenGLSalGraphicsImpl *>(mrParent.GetImpl());
@@ -104,7 +126,7 @@ bool X11OpenGLSalGraphicsImpl::FillPixmapFromScreen( 
X11Pixmap* pPixmap, int nX,
         return false;
 
     // make sure everything is synced up before reading back
-    maContext.makeCurrent();
+    mpContext->makeCurrent();
     glXWaitX();
 
     // TODO: lfrb: What if offscreen?
diff --git a/vcl/source/opengl/OpenGLContext.cxx 
b/vcl/source/opengl/OpenGLContext.cxx
index d1c1b72..9bbe1e2 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -27,6 +27,8 @@
 #include <win/saldata.hxx>
 #endif
 
+#include "svdata.hxx"
+
 using namespace com::sun::star;
 
 // TODO use rtl::Static instead of 'static'
@@ -47,13 +49,26 @@ OpenGLContext::OpenGLContext():
     mpWindow(NULL),
     m_pChildWindow(NULL),
     mbInitialized(false),
+    mnRefCount(1),
     mbRequestLegacyContext(false),
     mbUseDoubleBufferedRendering(true),
-    mbRequestVirtualDevice(false)
+    mbRequestVirtualDevice(false),
+    mpPrevContext(NULL),
+    mpNextContext(NULL)
 {
 #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
     mbPixmap = false;
 #endif
+
+    ImplSVData* pSVData = ImplGetSVData();
+    if( pSVData->maGDIData.mpLastContext )
+    {
+        pSVData->maGDIData.mpLastContext->mpNextContext = this;
+        mpPrevContext = pSVData->maGDIData.mpLastContext;
+    }
+    else
+        pSVData->maGDIData.mpFirstContext = this;
+    pSVData->maGDIData.mpLastContext = this;
 }
 
 OpenGLContext::~OpenGLContext()
@@ -67,6 +82,16 @@ OpenGLContext::~OpenGLContext()
         wglDeleteContext( m_aGLWin.hRC );
         ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC );
     }
+    ImplSVData* pSVData = ImplGetSVData();
+    if( mpPrevContext )
+        mpPrevContext->mpNextContext = mpNextContext;
+    else
+        pSVData->maGDIData.mpFirstContext = mpNextContext;
+    if( mpNextContext )
+        mpNextContext->mpPrevContext = mpPrevContext;
+    else
+        pSVData->maGDIData.mpLastContext = mpPrevContext;
+
 #elif defined( MACOSX )
     OpenGLWrapper::resetCurrent();
 #elif defined( IOS ) || defined( ANDROID )
@@ -89,6 +114,17 @@ OpenGLContext::~OpenGLContext()
 #endif
 }
 
+void OpenGLContext::AddRef()
+{
+    mnRefCount++;
+}
+
+void OpenGLContext::DeRef()
+{
+    if( --mnRefCount == 0 )
+        delete this;
+}
+
 void OpenGLContext::requestLegacyContext()
 {
     mbRequestLegacyContext = true;
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 34df86d..3c1a727 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -150,7 +150,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, 
SalX11Screen nXScreen )
 
     if( hDrawable_ )
     {
-        dynamic_cast<X11GraphicsImpl&>(*mpImpl.get()).Init();
+        mpImpl->Init();
         // TODO: moggi: FIXME nTextPixel_     = GetPixel( nTextColor_ );
     }
 }
diff --git a/vcl/win/source/gdi/gdiimpl.cxx b/vcl/win/source/gdi/gdiimpl.cxx
index 8a4b390..e17b3e1 100644
--- a/vcl/win/source/gdi/gdiimpl.cxx
+++ b/vcl/win/source/gdi/gdiimpl.cxx
@@ -294,6 +294,10 @@ WinSalGraphicsImpl::~WinSalGraphicsImpl()
 
 }
 
+void WinSalGraphicsImpl::Init()
+{
+}
+
 void WinSalGraphicsImpl::freeResources()
 {
 }
diff --git a/vcl/win/source/gdi/gdiimpl.hxx b/vcl/win/source/gdi/gdiimpl.hxx
index ded35ac..65e9d3f 100644
--- a/vcl/win/source/gdi/gdiimpl.hxx
+++ b/vcl/win/source/gdi/gdiimpl.hxx
@@ -52,6 +52,8 @@ public:
 
     virtual ~WinSalGraphicsImpl();
 
+    virtual void Init() SAL_OVERRIDE;
+
     virtual void freeResources() SAL_OVERRIDE;
 
     virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 678067d..05279d1 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -482,15 +482,7 @@ void WinSalGraphics::InitGraphics()
     ::SetTextAlign( getHDC(), TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
     ::SetBkMode( getHDC(), WIN32_TRANSPARENT );
     ::SetROP2( getHDC(), R2_COPYPEN );
-
-    OpenGLSalGraphicsImpl* pImpl = 
dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get());
-    if (pImpl)
-    {
-        if (mbVirDev)
-            pImpl->GetOpenGLContext().requestVirtualDevice();
-        pImpl->GetOpenGLContext().requestSingleBufferedRendering();
-        pImpl->GetOpenGLContext().init(mhLocalDC, mhWnd);
-    }
+    mpImpl->Init();
 }
 
 void WinSalGraphics::DeInitGraphics()
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to