[Libreoffice-commits] core.git: Branch 'feature/opengl-vcl2' - 6 commits - include/vcl vcl/inc vcl/opengl vcl/source vcl/unx vcl/win
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Sat Nov 22 05:23:48 PST 2014
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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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 <lfrb at 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()
More information about the Libreoffice-commits
mailing list