summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-26 09:22:25 -0500
committerMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-12-02 08:34:51 +0100
commitd6b51a87b482b69097100b9a2ce7ba85005e20ac (patch)
treec29780d4f11e703e0f2b571cd2094ae998d7b7bf /vcl
parent83c97b2a1c1a8d0531b6048fb27cf117b0da24e0 (diff)
vcl: Use the current OpenGL context for VirtualDevice and Bitmap if possible
Conflicts: include/vcl/opengl/OpenGLContext.hxx vcl/inc/openglgdiimpl.hxx vcl/opengl/gdiimpl.cxx vcl/opengl/x11/gdiimpl.cxx vcl/source/opengl/OpenGLContext.cxx Change-Id: I17f6ce66fb8b5bc027d35b4016ae56c24ee0a738
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/Library_vclplug_gen.mk1
-rw-r--r--vcl/inc/opengl/framebuffer.hxx45
-rw-r--r--vcl/inc/opengl/salbmp.hxx1
-rw-r--r--vcl/inc/opengl/texture.hxx3
-rw-r--r--vcl/inc/opengl/win/gdiimpl.hxx2
-rw-r--r--vcl/inc/opengl/x11/gdiimpl.hxx2
-rw-r--r--vcl/inc/opengl/x11/salvd.hxx55
-rw-r--r--vcl/inc/openglgdiimpl.hxx15
-rw-r--r--vcl/inc/svdata.hxx2
-rw-r--r--vcl/inc/unx/salgdi.h4
-rw-r--r--vcl/inc/unx/salvd.h15
-rw-r--r--vcl/opengl/framebuffer.cxx70
-rw-r--r--vcl/opengl/gdiimpl.cxx134
-rw-r--r--vcl/opengl/salbmp.cxx17
-rw-r--r--vcl/opengl/scale.cxx35
-rw-r--r--vcl/opengl/win/gdiimpl.cxx2
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx64
-rw-r--r--vcl/opengl/x11/salvd.cxx102
-rw-r--r--vcl/source/gdi/salgdilayout.cxx2
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx127
-rw-r--r--vcl/unx/generic/gdi/gdiimpl.cxx10
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx14
-rw-r--r--vcl/unx/generic/gdi/salvd.cxx151
24 files changed, 597 insertions, 277 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 3113497dc7d8..737a0310c2fd 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -126,6 +126,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/opengl/gdiimpl \
vcl/opengl/salbmp \
vcl/opengl/scale \
+ vcl/opengl/framebuffer \
vcl/opengl/texture \
vcl/source/opengl/OpenGLContext \
vcl/source/opengl/OpenGLHelper \
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 76be2c1e2cf1..29695e965539 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -107,6 +107,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
vcl/unx/x11/x11sys \
vcl/unx/x11/xlimits \
vcl/opengl/x11/gdiimpl \
+ vcl/opengl/x11/salvd \
))
# ultimately we want to split the x11 dependencies out
diff --git a/vcl/inc/opengl/framebuffer.hxx b/vcl/inc/opengl/framebuffer.hxx
new file mode 100644
index 000000000000..4ccc1c5728ea
--- /dev/null
+++ b/vcl/inc/opengl/framebuffer.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
+#define INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
+
+#include <GL/glew.h>
+#include <vcl/dllapi.h>
+
+#include <opengl/texture.hxx>
+
+class VCL_PLUGIN_PUBLIC OpenGLFramebuffer
+{
+private:
+ GLuint mnId;
+ OpenGLTexture maAttachedTexture;
+
+public:
+ OpenGLFramebuffer();
+ virtual ~OpenGLFramebuffer();
+
+ GLuint Id() const { return mnId; };
+
+ void Bind();
+ void Unbind();
+
+ bool IsFree() const;
+ bool IsAttached( const OpenGLTexture& rTexture ) const;
+ void AttachTexture( const OpenGLTexture& rTexture );
+ void DetachTexture();
+
+public:
+ OpenGLFramebuffer* mpPrevFramebuffer;
+ OpenGLFramebuffer* mpNextFramebuffer;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index 20b0e6137f14..bc232b123380 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -39,6 +39,7 @@ class BitmapPalette;
class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap
{
private:
+ OpenGLContext* mpContext;
OpenGLTexture maTexture;
bool mbDirtyTexture;
BitmapPalette maPalette;
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index eb003cfe5b96..ad4738a6948d 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -22,6 +22,9 @@
#include <GL/glew.h>
#include <vcl/dllapi.h>
+#include <vcl/salgtype.hxx>
+
+#include <tools/gen.hxx>
class ImplOpenGLTexture
{
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index de25d2325866..da1a2780e8e2 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -32,7 +32,7 @@ protected:
virtual bool IsOffscreen() const SAL_OVERRIDE;
virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
- virtual bool CompareWinContext( OpenGLContext* pContext ) SAL_OVERRIDE;
+ virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE;
virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE;
public:
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index f5e5bfb4f2f4..53ebe5b30722 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -31,8 +31,8 @@ protected:
bool IsOffscreen() const SAL_OVERRIDE;
virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
- virtual bool CompareWinContext( OpenGLContext* pContext ) SAL_OVERRIDE;
virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE;
+ virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE;
public:
// implementation of X11GraphicsImpl
diff --git a/vcl/inc/opengl/x11/salvd.hxx b/vcl/inc/opengl/x11/salvd.hxx
new file mode 100644
index 000000000000..0d7143b2b01f
--- /dev/null
+++ b/vcl/inc/opengl/x11/salvd.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
+#define INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
+
+#include <prex.h>
+#include <postx.h>
+
+#include <unx/saltype.h>
+#include <salvd.hxx>
+
+class SalDisplay;
+class X11OpenGLSalGraphics;
+
+class X11OpenGLSalVirtualDevice : public SalVirtualDevice
+{
+ SalDisplay *mpDisplay;
+ X11SalGraphics *mpGraphics;
+ bool mbGraphics; // is Graphics used
+ SalX11Screen mnXScreen;
+ int mnWidth;
+ int mnHeight;
+ sal_uInt16 mnDepth;
+
+public:
+ X11OpenGLSalVirtualDevice( SalGraphics *pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData );
+ virtual ~X11OpenGLSalVirtualDevice();
+
+ SalDisplay * GetDisplay() const { return mpDisplay; }
+ sal_uInt16 GetDepth() const { return mnDepth; }
+ int GetWidth() const { return mnWidth; }
+ int GetHeight() const { return mnHeight; }
+ SalX11Screen GetXScreenNumber() const { return mnXScreen; }
+
+ virtual SalGraphics* AcquireGraphics() SAL_OVERRIDE;
+ virtual void ReleaseGraphics( SalGraphics* pGraphics ) SAL_OVERRIDE;
+
+ // Set new size, without saving the old contents
+ virtual bool SetSize( long nNewDX, long nNewDY ) SAL_OVERRIDE;
+ virtual void GetSize( long& rWidth, long& rHeight ) SAL_OVERRIDE;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index bc813f180862..ac42527399fc 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -23,6 +23,7 @@
#include "salgdiimpl.hxx"
#include <vcl/dllapi.h>
+#include "opengl/framebuffer.hxx"
#include "opengl/texture.hxx"
#include "regionband.hxx"
@@ -39,6 +40,7 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
protected:
boost::shared_ptr<OpenGLContext> mpContext;
+ OpenGLFramebuffer* mpFramebuffer;
// clipping
vcl::Region maClipRegion;
@@ -46,7 +48,6 @@ protected:
bool mbUseStencil;
bool mbOffscreen;
- GLuint mnFramebufferId;
OpenGLTexture maOffscreenTex;
SalColor mnLineColor;
@@ -158,23 +159,23 @@ public:
virtual void PostDraw();
protected:
- bool AcquireContext( bool bOffscreen );
+ bool AcquireContext();
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
+ // create a new context for offscreen rendering
virtual OpenGLContext* CreatePixmapContext() = 0;
+ // check whether the given context can be used by this instance
+ virtual bool UseContext( OpenGLContext* pContext ) = 0;
+
public:
OpenGLSalGraphicsImpl();
virtual ~OpenGLSalGraphicsImpl ();
- OpenGLContext& GetOpenGLContext() { return *mpContext; }
+ OpenGLContext* GetOpenGLContext();
virtual void Init() SAL_OVERRIDE;
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index 2d8698890513..5fb496be3d6a 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -342,7 +342,7 @@ struct ImplSVData
void ImplInitSVData();
void ImplDeInitSVData();
void ImplDestroySVData();
-vcl::Window* ImplGetDefaultWindow();
+VCL_PLUGIN_PUBLIC vcl::Window* ImplGetDefaultWindow();
VCL_PLUGIN_PUBLIC ResMgr* ImplGetResMgr();
VCL_PLUGIN_PUBLIC ResId VclResId( sal_Int32 nId ); // throws std::bad_alloc if no res mgr
DockingManager* ImplGetDockingManager();
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 8ef42ba5cd12..edf47b12eeef 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -46,6 +46,7 @@ class X11Pixmap;
class X11SalVirtualDevice;
class X11SalGraphicsImpl;
class X11OpenGLSalGraphicsImpl;
+class X11OpenGLSalVirtualDevice;
class PspSalPrinter;
class PspSalInfoPrinter;
class ServerFont;
@@ -73,7 +74,7 @@ private:
protected:
SalFrame* m_pFrame; // the SalFrame which created this Graphics or NULL
- X11SalVirtualDevice* m_pVDev; // the SalVirtualDevice which created this Graphics or NULL
+ SalVirtualDevice* m_pVDev; // the SalVirtualDevice which created this Graphics or NULL
const SalColormap* m_pColormap;
SalColormap *m_pDeleteColormap;
@@ -123,6 +124,7 @@ public:
void Init( SalFrame *pFrame, Drawable aDrawable, SalX11Screen nXScreen );
void Init( X11SalVirtualDevice *pVirtualDevice, SalColormap* pColormap = NULL, bool bDeleteColormap = false );
+ void Init( X11OpenGLSalVirtualDevice *pVirtualDevice );
void Init( class ImplSalPrinterData *pPrinter );
void DeInit();
diff --git a/vcl/inc/unx/salvd.h b/vcl/inc/unx/salvd.h
index dd84c3542fa3..b1caa68f0a39 100644
--- a/vcl/inc/unx/salvd.h
+++ b/vcl/inc/unx/salvd.h
@@ -44,19 +44,12 @@ class X11SalVirtualDevice : public SalVirtualDevice
bool bExternPixmap_;
public:
- X11SalVirtualDevice();
+ X11SalVirtualDevice( SalGraphics *pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData );
virtual ~X11SalVirtualDevice();
- bool Init( SalDisplay *pDisplay,
- long nDX, long nDY,
- sal_uInt16 nBitCount,
- SalX11Screen nXScreen,
- Pixmap hDrawable = None,
- XRenderPictFormat* pXRenderFormat = NULL );
- void InitGraphics( X11SalVirtualDevice *pVD )
- {
- pGraphics_->Init( pVD );
- }
Display *GetXDisplay() const
{
return pDisplay_->GetDisplay();
diff --git a/vcl/opengl/framebuffer.cxx b/vcl/opengl/framebuffer.cxx
new file mode 100644
index 000000000000..29f9a781130a
--- /dev/null
+++ b/vcl/opengl/framebuffer.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/log.hxx>
+
+#include <opengl/framebuffer.hxx>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+OpenGLFramebuffer::OpenGLFramebuffer() :
+ mnId( 0 ),
+ mpPrevFramebuffer( NULL ),
+ mpNextFramebuffer( NULL )
+{
+ glGenFramebuffers( 1, &mnId );
+ SAL_INFO( "vcl.opengl", "Created framebuffer " << (int)mnId );
+}
+
+OpenGLFramebuffer::~OpenGLFramebuffer()
+{
+ glDeleteFramebuffers( 1, &mnId );
+}
+
+void OpenGLFramebuffer::Bind()
+{
+ glBindFramebuffer( GL_FRAMEBUFFER, mnId );
+ SAL_INFO( "vcl.opengl", "Binding framebuffer " << (int)mnId );
+ CHECK_GL_ERROR();
+}
+
+void OpenGLFramebuffer::Unbind()
+{
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ SAL_INFO( "vcl.opengl", "Binding default framebuffer" );
+ CHECK_GL_ERROR();
+}
+
+bool OpenGLFramebuffer::IsFree() const
+{
+ return (!maAttachedTexture);
+}
+
+bool OpenGLFramebuffer::IsAttached( const OpenGLTexture& rTexture ) const
+{
+ return ( maAttachedTexture == rTexture );
+}
+
+void OpenGLFramebuffer::AttachTexture( const OpenGLTexture& rTexture )
+{
+ SAL_INFO( "vcl.opengl", "Attaching texture " << rTexture.Id() << " to framebuffer " << (int)mnId );
+ maAttachedTexture = rTexture;
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ maAttachedTexture.Id(), 0 );
+ CHECK_GL_ERROR();
+}
+
+void OpenGLFramebuffer::DetachTexture()
+{
+ maAttachedTexture = OpenGLTexture();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 );
+ CHECK_GL_ERROR();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index cff4a0bee77f..beae9dd9b887 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -65,10 +65,10 @@
OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
: mpContext(0)
+ , mpFramebuffer(NULL)
, mbUseScissor(false)
, mbUseStencil(false)
, mbOffscreen(false)
- , mnFramebufferId(0)
, mnLineColor(SALCOLOR_NONE)
, mnFillColor(SALCOLOR_NONE)
, mnSolidProgram(0)
@@ -111,27 +111,30 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
{
}
-bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
+OpenGLContext* OpenGLSalGraphicsImpl::GetOpenGLContext()
+{
+ if( !mpContext )
+ AcquireContext();
+ return mpContext.get();
+}
+
+bool OpenGLSalGraphicsImpl::AcquireContext( )
{
ImplSVData* pSVData = ImplGetSVData();
- if( bOffscreen )
- {
- mpContext.reset(CreatePixmapContext());
- return (mpContext.get() != NULL);
- }
+ mpContext.reset();
OpenGLContext* pContext = pSVData->maGDIData.mpLastContext;
while( pContext )
{
// check if this context can be used by this SalGraphicsImpl instance
- if( CompareWinContext( pContext ) )
+ if( UseContext( pContext ) )
break;
pContext = pContext->mpPrevContext;
}
if (!pContext)
- pContext =CreateWinContext();
+ pContext = mbOffscreen ? CreatePixmapContext() : CreateWinContext();
mpContext.reset(pContext);
return (mpContext != nullptr);
@@ -145,68 +148,41 @@ bool OpenGLSalGraphicsImpl::ReleaseContext()
void OpenGLSalGraphicsImpl::Init()
{
- const bool bOffscreen = IsOffscreen();
+ mbOffscreen = IsOffscreen();
// check if we can simply re-use the same context
if( mpContext )
{
- if( bOffscreen != mbOffscreen || ( !mbOffscreen && CompareWinContext( mpContext.get() ) ) )
+ if( !UseContext( mpContext.get() ) )
ReleaseContext();
}
- if( !mpContext && !AcquireContext( bOffscreen ) )
+ // reset the offscreen texture
+ if( !mbOffscreen ||
+ maOffscreenTex.GetWidth() != GetWidth() ||
+ maOffscreenTex.GetHeight() != GetHeight() )
{
- 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();
+ maOffscreenTex = OpenGLTexture();
}
}
void OpenGLSalGraphicsImpl::PreDraw()
{
- assert( mpContext && mpContext->isInitialized() );
+ if( !mpContext && !AcquireContext() )
+ {
+ SAL_WARN( "vcl.opengl", "Couldn't acquire context" );
+ return;
+ }
mpContext->makeCurrent();
- // TODO: lfrb: make sure the render target has the right size
- if( mbOffscreen )
- CheckOffscreenTexture();
+ CHECK_GL_ERROR();
+
+ if( !mbOffscreen )
+ mpContext->AcquireDefaultFramebuffer();
else
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ CheckOffscreenTexture();
CHECK_GL_ERROR();
+
glViewport( 0, 0, GetWidth(), GetHeight() );
ImplInitClipRegion();
@@ -215,15 +191,16 @@ void OpenGLSalGraphicsImpl::PreDraw()
void OpenGLSalGraphicsImpl::PostDraw()
{
- if( mbOffscreen )
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- else if( mpContext->mnPainting == 0 )
+ if( !mbOffscreen && mpContext->mnPainting == 0 )
glFlush();
if( mbUseScissor )
glDisable( GL_SCISSOR_TEST );
if( mbUseStencil )
glDisable( GL_STENCIL_TEST );
+ mpContext->ReleaseFramebuffer( mpFramebuffer );
+ mpFramebuffer = NULL;
+
CHECK_GL_ERROR();
}
@@ -279,6 +256,8 @@ void OpenGLSalGraphicsImpl::ImplInitClipRegion()
glStencilFunc( GL_EQUAL, 1, 0x1 );
glEnable( GL_STENCIL_TEST );
}
+
+ CHECK_GL_ERROR();
}
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
@@ -371,26 +350,25 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
{
- glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
+ if( !maOffscreenTex )
+ maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
- if( maOffscreenTex.IsUnique() )
+ if( !maOffscreenTex.IsUnique() )
{
- GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
- if( nStatus != GL_FRAMEBUFFER_COMPLETE )
- SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
- return true;
- }
-
- GLfloat fWidth = GetWidth();
- GLfloat fHeight = GetHeight();
- SalTwoRect aPosAry(0, 0, fWidth, fHeight, 0,0, fWidth, fHeight);
+ GLfloat fWidth = GetWidth();
+ GLfloat fHeight = GetHeight();
+ SalTwoRect aPosAry(0, 0, fWidth, fHeight, 0,0, fWidth, fHeight);
- // TODO: improve performance: lfrb: User GL_ARB_copy_image?
- OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 );
- glViewport( 0, 0, GetWidth(), GetHeight() );
- DrawTexture( maOffscreenTex, aPosAry );
- maOffscreenTex = aNewTex;
+ // TODO: lfrb: User GL_ARB_copy_image?
+ OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
+ mpFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
+ DrawTexture( maOffscreenTex, aPosAry );
+ maOffscreenTex = aNewTex;
+ }
+ else
+ {
+ mpFramebuffer = mpContext->AcquireFramebuffer( maOffscreenTex );
+ }
CHECK_GL_ERROR();
return true;
@@ -1895,13 +1873,17 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
void OpenGLSalGraphicsImpl::beginPaint()
{
- SAL_INFO( "vcl.opengl", "BEGIN PAINT " << this );
+ if( !mpContext && !AcquireContext() )
+ return;
+
mpContext->mnPainting++;
}
void OpenGLSalGraphicsImpl::endPaint()
{
- SAL_INFO( "vcl.opengl", "END PAINT " << this );
+ if( !mpContext && !AcquireContext() )
+ return;
+
mpContext->mnPainting--;
assert( mpContext->mnPainting >= 0 );
if( mpContext->mnPainting == 0 && !mbOffscreen )
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 7a1af0d0f9af..6fdb2af578c8 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -35,7 +35,8 @@ static bool isValidBitCount( sal_uInt16 nBitCount )
}
OpenGLSalBitmap::OpenGLSalBitmap()
-: mbDirtyTexture(true)
+: mpContext(NULL)
+, mbDirtyTexture(true)
, mnBits(0)
, mnBytesPerRow(0)
, mnWidth(0)
@@ -472,10 +473,14 @@ OpenGLContext* OpenGLSalBitmap::GetBitmapContext() const
void OpenGLSalBitmap::makeCurrent()
{
- // Always use the default window's context for bitmap
- OpenGLContext* pContext = GetBitmapContext();
- assert(pContext && "Couldn't get default OpenGL context provider");
- pContext->makeCurrent();
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // TODO: make sure we can really use the last used context
+ mpContext = pSVData->maGDIData.mpLastContext;
+ if( !mpContext )
+ mpContext = GetBitmapContext();
+ assert(mpContext && "Couldn't get an OpenGL context");
+ mpContext->makeCurrent();
}
BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
@@ -490,8 +495,6 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
if( !maPendingOps.empty() )
{
- makeCurrent();
-
SAL_INFO( "vcl.opengl", "** Creating texture and reading it back immediatly" );
if( !CreateTexture() || !AllocateUserData() || !ReadTexture() )
return NULL;
diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
index 9c52cc271f48..d3966521136f 100644
--- a/vcl/opengl/scale.cxx
+++ b/vcl/opengl/scale.cxx
@@ -86,8 +86,8 @@ bool OpenGLSalBitmap::ImplScaleFilter(
const double& rScaleY,
GLenum nFilter )
{
+ OpenGLFramebuffer* pFramebuffer;
GLuint nProgram;
- GLuint nFramebufferId;
GLenum nOldFilter;
int nNewWidth( mnWidth * rScaleX );
int nNewHeight( mnHeight * rScaleY );
@@ -96,15 +96,13 @@ bool OpenGLSalBitmap::ImplScaleFilter(
if( nProgram == 0 )
return false;
- glGenFramebuffers( 1, &nFramebufferId );
- glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
- glUseProgram( nProgram );
- glUniform1i( mnTexSamplerUniform, 0 );
-
OpenGLTexture aNewTex = OpenGLTexture( nNewWidth, nNewHeight );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 );
+ pFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
- glViewport( 0, 0, nNewWidth, nNewHeight );
+ glUseProgram( nProgram );
+ glUniform1i( mnTexSamplerUniform, 0 );
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT );
maTexture.Bind();
nOldFilter = maTexture.GetFilter();
maTexture.SetFilter( nFilter );
@@ -113,8 +111,7 @@ bool OpenGLSalBitmap::ImplScaleFilter(
maTexture.Unbind();
glUseProgram( 0 );
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- glDeleteFramebuffers( 1, &nFramebufferId );
+ mpContext->ReleaseFramebuffer( pFramebuffer );
mnWidth = nNewWidth;
mnHeight = nNewHeight;
@@ -167,8 +164,8 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
const double& rScaleY,
const Kernel& aKernel )
{
+ OpenGLFramebuffer* pFramebuffer;
GLfloat* pWeights( 0 );
- GLuint nFramebufferId;
GLuint nProgram;
sal_uInt32 nKernelSize;
GLfloat aOffsets[32];
@@ -181,8 +178,6 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
if( nProgram == 0 )
return false;
- glGenFramebuffers( 1, &nFramebufferId );
- glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
glUseProgram( nProgram );
glUniform1i( mnConvSamplerUniform, 0 );
CHECK_GL_ERROR();
@@ -191,8 +186,7 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
if( mnWidth != nNewWidth )
{
OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, mnHeight );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aScratchTex.Id(), 0 );
- CHECK_GL_ERROR();
+ pFramebuffer = mpContext->AcquireFramebuffer( aScratchTex );
for( sal_uInt32 i = 0; i < 16; i++ )
{
@@ -205,19 +199,19 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
CHECK_GL_ERROR();
- glViewport( 0, 0, nNewWidth, mnHeight );
maTexture.Bind();
maTexture.Draw();
maTexture.Unbind();
maTexture = aScratchTex;
+ mpContext->ReleaseFramebuffer( pFramebuffer );
}
// vertical scaling in final texture
if( mnHeight != nNewHeight )
{
OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, nNewHeight );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aScratchTex.Id(), 0 );
+ pFramebuffer = mpContext->AcquireFramebuffer( aScratchTex );
for( sal_uInt32 i = 0; i < 16; i++ )
{
@@ -229,17 +223,15 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
CHECK_GL_ERROR();
- glViewport( 0, 0, nNewWidth, nNewHeight );
maTexture.Bind();
maTexture.Draw();
maTexture.Unbind();
maTexture = aScratchTex;
+ mpContext->ReleaseFramebuffer( pFramebuffer );
}
glUseProgram( 0 );
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- glDeleteFramebuffers( 1, &nFramebufferId );
mnWidth = nNewWidth;
mnHeight = nNewHeight;
@@ -314,7 +306,8 @@ bool OpenGLSalBitmap::Scale( const double& rScaleX, const double& rScaleY, sal_u
nScaleFlag == BMP_SCALE_LANCZOS )
{
//TODO maUserBuffer.reset();
- if( GetBitmapContext() == NULL )
+ makeCurrent();
+ if( mpContext == NULL )
{
SAL_INFO( "vcl.opengl", "Add ScaleOp to pending operations" );
maPendingOps.push_back( new ScaleOp( this, rScaleX, rScaleY, nScaleFlag ) );
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index 08159278f576..2bd31bf99dd8 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -82,7 +82,7 @@ OpenGLContext* WinOpenGLSalGraphicsImpl::CreateWinContext()
return pContext;
}
-bool WinOpenGLSalGraphicsImpl::CompareWinContext( OpenGLContext* pContext )
+bool WinOpenGLSalGraphicsImpl::UseContext( OpenGLContext* pContext )
{
if( !pContext || !pContext->isInitialized() )
return false;
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 80db3a9a66ef..07b8abff7235 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -7,16 +7,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include "vcl/salbtype.hxx"
+#include <vcl/salbtype.hxx>
-#include "unx/pixmap.hxx"
-#include "unx/saldisp.hxx"
-#include "unx/salframe.h"
-#include "unx/salgdi.h"
-#include "unx/salvd.h"
+#include <svdata.hxx>
-#include "opengl/texture.hxx"
-#include "opengl/x11/gdiimpl.hxx"
+#include <unx/pixmap.hxx>
+#include <unx/saldisp.hxx>
+#include <unx/salframe.h>
+#include <unx/salgdi.h>
+#include <unx/salvd.h>
+#include <unx/x11/xlimits.hxx>
+
+#include <opengl/texture.hxx>
+#include <opengl/x11/gdiimpl.hxx>
+#include <opengl/x11/salvd.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
@@ -36,12 +40,7 @@ GLfloat X11OpenGLSalGraphicsImpl::GetWidth() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nWidth;
else if( mrParent.m_pVDev )
- {
- long nWidth = 0;
- long nHeight = 0;
- mrParent.m_pVDev->GetSize( nWidth, nHeight );
- return nWidth;
- }
+ return static_cast< X11OpenGLSalVirtualDevice* >(mrParent.m_pVDev)->GetWidth();
return 1;
}
@@ -50,12 +49,7 @@ GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nHeight;
else if( mrParent.m_pVDev )
- {
- long nWidth = 0;
- long nHeight = 0;
- mrParent.m_pVDev->GetSize( nWidth, nHeight );
- return nHeight;
- }
+ return static_cast< X11OpenGLSalVirtualDevice* >(mrParent.m_pVDev)->GetHeight();
return 1;
}
@@ -79,6 +73,7 @@ OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext()
if( !pProvider )
return NULL;
+
Window aWin = pProvider->GetX11Window();
OpenGLContext* pContext = new OpenGLContext();
pContext->init( mrParent.GetXDisplay(), aWin,
@@ -86,24 +81,27 @@ OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext()
return pContext;
}
-bool X11OpenGLSalGraphicsImpl::CompareWinContext( OpenGLContext* pContext )
+OpenGLContext* X11OpenGLSalGraphicsImpl::CreatePixmapContext()
{
- X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+ X11OpenGLSalVirtualDevice* pVDev = dynamic_cast<X11OpenGLSalVirtualDevice*>(mrParent.m_pVDev);
- if( !pProvider || !pContext->isInitialized() )
- return false;
- return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
+ if( pVDev == NULL )
+ return NULL;
+
+ return ImplGetDefaultWindow()->GetGraphics()->GetOpenGLContext();
}
-OpenGLContext* X11OpenGLSalGraphicsImpl::CreatePixmapContext()
+bool X11OpenGLSalGraphicsImpl::UseContext( OpenGLContext* pContext )
{
- 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;
+ X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+
+ if( !pContext->isInitialized() )
+ return false;
+
+ if( !pProvider )
+ return ( pContext->getOpenGLWindow().win != None );
+ else
+ return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
}
void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
diff --git a/vcl/opengl/x11/salvd.cxx b/vcl/opengl/x11/salvd.cxx
new file mode 100644
index 000000000000..b7c4eea60bf0
--- /dev/null
+++ b/vcl/opengl/x11/salvd.cxx
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/sysdata.hxx>
+
+#include <unx/salunx.h>
+#include <unx/saldata.hxx>
+#include <unx/saldisp.hxx>
+#include <unx/salgdi.h>
+#include <unx/salvd.h>
+
+#include <opengl/x11/salvd.hxx>
+
+void X11SalGraphics::Init( X11OpenGLSalVirtualDevice *pDevice )
+{
+ SalDisplay *pDisplay = pDevice->GetDisplay();
+
+ m_nXScreen = pDevice->GetXScreenNumber();
+ m_pColormap = &pDisplay->GetColormap( m_nXScreen );
+
+ m_pVDev = pDevice;
+ m_pFrame = NULL;
+
+ bWindow_ = pDisplay->IsDisplay();
+ bVirDev_ = true;
+
+ mpImpl->Init();
+}
+
+X11OpenGLSalVirtualDevice::X11OpenGLSalVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData ) :
+ mbGraphics( false ),
+ mnXScreen( 0 )
+{
+ // TODO Do we really need the requested bit count?
+ if( !nBitCount && pGraphics )
+ nBitCount = pGraphics->GetBitCount();
+
+ // TODO Check where a VirtualDevice is created from SystemGraphicsData
+ assert( pData == NULL ); (void)pData;
+
+ mpDisplay = GetGenericData()->GetSalDisplay();
+ mnDepth = nBitCount;
+ mnXScreen = pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() :
+ GetGenericData()->GetSalDisplay()->GetDefaultXScreen();
+ mnWidth = nDX;
+ mnHeight = nDY;
+ mpGraphics = new X11SalGraphics();
+ mpGraphics->SetLayout( 0 );
+ mpGraphics->Init( this );
+}
+
+X11OpenGLSalVirtualDevice::~X11OpenGLSalVirtualDevice()
+{
+ if( mpGraphics )
+ delete mpGraphics;
+}
+
+SalGraphics* X11OpenGLSalVirtualDevice::AcquireGraphics()
+{
+ if( mbGraphics )
+ return NULL;
+
+ if( mpGraphics )
+ mbGraphics = true;
+
+ return mpGraphics;
+}
+
+void X11OpenGLSalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ mbGraphics = false;
+}
+
+bool X11OpenGLSalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ if( !nDX ) nDX = 1;
+ if( !nDY ) nDY = 1;
+
+ mnWidth = nDX;
+ mnHeight = nDY;
+ if( mpGraphics )
+ mpGraphics->Init( this );
+
+ return true;
+}
+
+void X11OpenGLSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
+{
+ rWidth = mnWidth;
+ rHeight = mnHeight;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index dc419a0b7ef4..88a0abc1d352 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -81,7 +81,7 @@ OpenGLContext* SalGraphics::GetOpenGLContext() const
{
OpenGLSalGraphicsImpl *pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(GetImpl());
if (pImpl)
- return &pImpl->GetOpenGLContext();
+ return pImpl->GetOpenGLContext();
return NULL;
}
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 4c64f6344257..84d6bbebccae 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -29,6 +29,9 @@
#include "svdata.hxx"
+#include <opengl/framebuffer.hxx>
+#include <opengl/texture.hxx>
+
using namespace com::sun::star;
// TODO use rtl::Static instead of 'static'
@@ -52,6 +55,9 @@ OpenGLContext::OpenGLContext():
mbRequestLegacyContext(false),
mbUseDoubleBufferedRendering(true),
mbRequestVirtualDevice(false),
+ mpCurrentFramebuffer(NULL),
+ mpFirstFramebuffer(NULL),
+ mpLastFramebuffer(NULL),
mnPainting(0),
mpPrevContext(NULL),
mpNextContext(NULL)
@@ -73,6 +79,15 @@ OpenGLContext::OpenGLContext():
OpenGLContext::~OpenGLContext()
{
+ ImplSVData* pSVData = ImplGetSVData();
+ if( mpPrevContext )
+ mpPrevContext->mpNextContext = mpNextContext;
+ else
+ pSVData->maGDIData.mpFirstContext = mpNextContext;
+ if( mpNextContext )
+ mpNextContext->mpPrevContext = mpPrevContext;
+ else
+ pSVData->maGDIData.mpLastContext = mpPrevContext;
#if defined( WNT )
if (m_aGLWin.hRC)
{
@@ -102,16 +117,6 @@ OpenGLContext::~OpenGLContext()
glXDestroyPixmap(m_aGLWin.dpy, m_aGLWin.glPix);
}
#endif
-
- ImplSVData* pSVData = ImplGetSVData();
- if( mpPrevContext )
- mpPrevContext->mpNextContext = mpNextContext;
- else
- pSVData->maGDIData.mpFirstContext = mpNextContext;
- if( mpNextContext )
- mpNextContext->mpPrevContext = mpPrevContext;
- else
- pSVData->maGDIData.mpLastContext = mpPrevContext;
}
void OpenGLContext::requestLegacyContext()
@@ -565,6 +570,7 @@ void initOpenGLFunctionPointers()
glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig"); // try to find a visual for the current set of attributes
glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int* value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
glXCreateContextAttribsARB = (GLXContext(*) (Display*, GLXFBConfig, GLXContext, Bool, const int*)) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");;
+ glXCreatePixmap = (GLXPixmap(*) (Display*, GLXFBConfig, Pixmap, const int*)) glXGetProcAddressARB((const GLubyte *) "glXCreatePixmap");;
}
Visual* getVisual(Display* dpy, Window win)
@@ -655,6 +661,8 @@ bool OpenGLContext::init(Display* dpy, Pixmap pix, unsigned int width, unsigned
if (!dpy)
return false;
+ initOpenGLFunctionPointers();
+
SAL_INFO("vcl.opengl", "init with pixmap");
m_aGLWin.dpy = dpy;
m_aGLWin.Width = width;
@@ -673,8 +681,6 @@ bool OpenGLContext::init(Display* dpy, Pixmap pix, unsigned int width, unsigned
mbPixmap = true;
- initOpenGLFunctionPointers();
-
return ImplInit();
}
@@ -873,7 +879,7 @@ bool OpenGLContext::ImplInit()
}
HGLRC hTempRC = wglCreateContext(m_aGLWin.hDC);
- if (m_aGLWin.hRC == NULL)
+ if (hTempRC == NULL)
{
ImplWriteLastError(GetLastError(), "wglCreateContext in OpenGLContext::ImplInit");
SAL_WARN("vcl.opengl", "wglCreateContext failed");
@@ -1213,13 +1219,32 @@ void OpenGLContext::makeCurrent()
// nothing
#elif defined( UNX )
GLXDrawable nDrawable = mbPixmap ? m_aGLWin.glPix : m_aGLWin.win;
+ static int nSwitch = 0;
if (glXGetCurrentContext() == m_aGLWin.ctx &&
glXGetCurrentDrawable() == nDrawable)
{
- SAL_INFO("vcl.opengl", "OpenGLContext::makeCurrent(): Avoid setting the same context");
+ ; // no-op
}
else if (!glXMakeCurrent( m_aGLWin.dpy, nDrawable, m_aGLWin.ctx ))
SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed on drawable " << nDrawable << " pixmap? " << mbPixmap);
+ else
+ {
+ SAL_INFO("vcl.opengl", "******* CONTEXT SWITCH " << ++nSwitch << " *********");
+ ImplSVData* pSVData = ImplGetSVData();
+ if( mpNextContext )
+ {
+ if( mpPrevContext )
+ mpPrevContext->mpNextContext = mpNextContext;
+ else
+ pSVData->maGDIData.mpFirstContext = mpNextContext;
+ mpNextContext->mpPrevContext = mpPrevContext;
+
+ mpPrevContext = pSVData->maGDIData.mpLastContext;
+ mpNextContext = NULL;
+ pSVData->maGDIData.mpLastContext->mpNextContext = this;
+ pSVData->maGDIData.mpLastContext = this;
+ }
+ }
#endif
}
@@ -1292,4 +1317,78 @@ NSOpenGLView* OpenGLContext::getOpenGLView()
}
#endif
+bool OpenGLContext::AcquireFramebuffer( OpenGLFramebuffer* pFramebuffer )
+{
+ if( pFramebuffer != mpCurrentFramebuffer )
+ {
+ // release the attached texture so it's available from the other contexts
+ //if( mpCurrentFramebuffer )
+ // mpCurrentFramebuffer->DetachTexture();
+
+ if( pFramebuffer )
+ pFramebuffer->Bind();
+ else
+ mpCurrentFramebuffer->Unbind();
+ mpCurrentFramebuffer = pFramebuffer;
+ }
+
+ return true;
+}
+
+bool OpenGLContext::AcquireDefaultFramebuffer()
+{
+ return AcquireFramebuffer( NULL );
+}
+
+OpenGLFramebuffer* OpenGLContext::AcquireFramebuffer( const OpenGLTexture& rTexture )
+{
+ OpenGLFramebuffer* pFramebuffer = NULL;
+ OpenGLFramebuffer* pFreeFramebuffer = NULL;
+
+ // check if there is already a framebuffer attached to that texture
+ pFramebuffer = mpLastFramebuffer;
+ while( pFramebuffer )
+ {
+ if( pFramebuffer->IsAttached( rTexture ) )
+ break;
+ if( !pFreeFramebuffer && pFramebuffer->IsFree() )
+ pFreeFramebuffer = pFramebuffer;
+ pFramebuffer = pFramebuffer->mpPrevFramebuffer;
+ }
+
+ // else use the first free framebuffer
+ if( !pFramebuffer && pFreeFramebuffer )
+ pFramebuffer = pFreeFramebuffer;
+
+ // if there isn't any free one, create a new one
+ if( !pFramebuffer )
+ {
+ pFramebuffer = new OpenGLFramebuffer();
+ if( mpLastFramebuffer )
+ {
+ pFramebuffer->mpPrevFramebuffer = mpLastFramebuffer;
+ mpLastFramebuffer->mpNextFramebuffer = pFramebuffer;
+ mpLastFramebuffer = pFramebuffer;
+ }
+ else
+ {
+ mpFirstFramebuffer = pFramebuffer;
+ mpLastFramebuffer = pFramebuffer;
+ }
+ }
+
+ AcquireFramebuffer( pFramebuffer );
+ if( pFramebuffer->IsFree() )
+ pFramebuffer->AttachTexture( rTexture );
+ glViewport( 0, 0, rTexture.GetWidth(), rTexture.GetHeight() );
+
+ return pFramebuffer;
+}
+
+void OpenGLContext::ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer )
+{
+ if( pFramebuffer )
+ pFramebuffer->DetachTexture();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index 46865d0481a7..f2f909c96142 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -728,7 +728,7 @@ void X11SalGraphicsImpl::drawMaskedBitmap( const SalTwoRect& rPosAry,
// bitdepth to create pixmaps for, otherwise, XCopyArea will
// refuse to work.
const sal_uInt16 nDepth( mrParent.m_pVDev ?
- mrParent.m_pVDev->GetDepth() :
+ static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() :
pSalDisp->GetVisual( mrParent.m_nXScreen ).GetDepth() );
Pixmap aFG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
rPosAry.mnDestHeight, nDepth ) );
@@ -850,7 +850,7 @@ bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR,
Display* pXDisplay = pSalDisp->GetDisplay();
// create source Picture
- int nDepth = mrParent.m_pVDev ? mrParent.m_pVDev->GetDepth() : rSalVis.GetDepth();
+ int nDepth = mrParent.m_pVDev ? static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() : rSalVis.GetDepth();
const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( mrParent.hDrawable_, mrParent.m_nXScreen, nDepth, rTR );
if( !pSrcDDB )
@@ -977,7 +977,7 @@ bool X11SalGraphicsImpl::drawAlphaRect( long nX, long nY, long nWidth,
if( mbPenGC || !mbBrushGC || mbXORMode )
return false; // can only perform solid fills without XOR.
- if( mrParent.m_pVDev && mrParent.m_pVDev->GetDepth() < 8 )
+ if( mrParent.m_pVDev && static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() < 8 )
return false;
Picture aDstPic = GetXRenderPicture();
@@ -1564,7 +1564,7 @@ long X11SalGraphicsImpl::GetGraphicsHeight() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nHeight;
else if( mrParent.m_pVDev )
- return mrParent.m_pVDev->GetHeight();
+ return static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetHeight();
else
return 0;
}
@@ -1838,7 +1838,7 @@ long X11SalGraphicsImpl::GetGraphicsWidth() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nWidth;
else if( mrParent.m_pVDev )
- return mrParent.m_pVDev->GetWidth();
+ return static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetWidth();
else
return 0;
}
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 80f24f0628fb..38aa7a33c914 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -149,11 +149,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
m_aXRenderPicture = 0;
}
- if( hDrawable_ )
- {
- mpImpl->Init();
- // TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ );
- }
+ // TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ );
}
void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
@@ -161,11 +157,15 @@ void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
{
m_pColormap = &GetGenericData()->GetSalDisplay()->GetColormap(nXScreen);
m_nXScreen = nXScreen;
+
m_pFrame = pFrame;
- SetDrawable( aTarget, nXScreen );
+ m_pVDev = NULL;
bWindow_ = true;
- m_pVDev = NULL;
+ bVirDev_ = false;
+
+ SetDrawable( aTarget, nXScreen );
+ mpImpl->Init();
}
void X11SalGraphics::DeInit()
diff --git a/vcl/unx/generic/gdi/salvd.cxx b/vcl/unx/generic/gdi/salvd.cxx
index 71ec509d1a2b..7967a4d84acf 100644
--- a/vcl/unx/generic/gdi/salvd.cxx
+++ b/vcl/unx/generic/gdi/salvd.cxx
@@ -32,49 +32,17 @@
#include <salinst.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
+#include <opengl/x11/salvd.hxx>
+
SalVirtualDevice* X11SalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
long nDX, long nDY,
sal_uInt16 nBitCount, const SystemGraphicsData *pData )
{
- X11SalVirtualDevice *pVDev = new X11SalVirtualDevice();
- if( !nBitCount && pGraphics )
- nBitCount = pGraphics->GetBitCount();
-
- if( pData && pData->hDrawable != None )
- {
- ::Window aRoot;
- int x, y;
- unsigned int w = 0, h = 0, bw, d;
- Display* pDisp = GetGenericData()->GetSalDisplay()->GetDisplay();
- XGetGeometry( pDisp, pData->hDrawable,
- &aRoot, &x, &y, &w, &h, &bw, &d );
- int nScreen = 0;
- while( nScreen < ScreenCount( pDisp ) )
- {
- if( RootWindow( pDisp, nScreen ) == aRoot )
- break;
- nScreen++;
- }
- nDX = (long)w;
- nDY = (long)h;
- if( !pVDev->Init( GetGenericData()->GetSalDisplay(), nDX, nDY, nBitCount,
- SalX11Screen( nScreen ), pData->hDrawable,
- static_cast< XRenderPictFormat* >( pData->pXRenderFormat )) )
- {
- delete pVDev;
- return NULL;
- }
- }
- else if( !pVDev->Init( GetGenericData()->GetSalDisplay(), nDX, nDY, nBitCount,
- pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() :
- GetGenericData()->GetSalDisplay()->GetDefaultXScreen() ) )
- {
- delete pVDev;
- return NULL;
- }
-
- pVDev->InitGraphics( pVDev );
- return pVDev;
+ if (OpenGLHelper::isVCLOpenGLEnabled())
+ return new X11OpenGLSalVirtualDevice( pGraphics, nDX, nDY, nBitCount, pData );
+ else
+ return new X11SalVirtualDevice( pGraphics, nDX, nDY, nBitCount, pData );
}
void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap,
@@ -110,66 +78,78 @@ void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap,
const Drawable aVdevDrawable = pDevice->GetDrawable();
SetDrawable( aVdevDrawable, m_nXScreen );
+ mpImpl->Init();
}
-bool X11SalVirtualDevice::Init( SalDisplay *pDisplay,
- long nDX, long nDY,
- sal_uInt16 nBitCount,
- SalX11Screen nXScreen,
- Pixmap hDrawable,
- XRenderPictFormat* pXRenderFormat )
+X11SalVirtualDevice::X11SalVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData ) :
+ m_nXScreen( 0 ),
+ bGraphics_( false )
{
SalColormap* pColormap = NULL;
bool bDeleteColormap = false;
- pDisplay_ = pDisplay;
+ if( !nBitCount && pGraphics )
+ nBitCount = pGraphics->GetBitCount();
+
+ pDisplay_ = GetGenericData()->GetSalDisplay();
pGraphics_ = new X11SalGraphics();
- m_nXScreen = nXScreen;
- if( pXRenderFormat ) {
+ nDepth_ = nBitCount;
+
+ if( pData && pData->hDrawable != None )
+ {
+ ::Window aRoot;
+ int x, y;
+ unsigned int w = 0, h = 0, bw, d;
+ Display* pDisp = pDisplay_->GetDisplay();
+ XGetGeometry( pDisp, pData->hDrawable,
+ &aRoot, &x, &y, &w, &h, &bw, &d );
+ int nScreen = 0;
+ while( nScreen < ScreenCount( pDisp ) )
+ {
+ if( RootWindow( pDisp, nScreen ) == aRoot )
+ break;
+ nScreen++;
+ }
+ nDX_ = (long)w;
+ nDY_ = (long)h;
+ m_nXScreen = SalX11Screen( nScreen );
+ hDrawable_ = pData->hDrawable;
+ bExternPixmap_ = true;
+ }
+ else
+ {
+ nDX_ = nDX;
+ nDY_ = nDY;
+ m_nXScreen = pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() :
+ GetGenericData()->GetSalDisplay()->GetDefaultXScreen();
+ hDrawable_ = limitXCreatePixmap( GetXDisplay(),
+ pDisplay_->GetDrawable( m_nXScreen ),
+ nDX_, nDY_,
+ GetDepth() );
+ bExternPixmap_ = false;
+ }
+
+ XRenderPictFormat* pXRenderFormat = pData ? static_cast<XRenderPictFormat*>(pData->pXRenderFormat) : NULL;
+ if( pXRenderFormat )
+ {
pGraphics_->SetXRenderFormat( pXRenderFormat );
if( pXRenderFormat->colormap )
- pColormap = new SalColormap( pDisplay, pXRenderFormat->colormap, m_nXScreen );
+ pColormap = new SalColormap( pDisplay_, pXRenderFormat->colormap, m_nXScreen );
else
pColormap = new SalColormap( nBitCount );
bDeleteColormap = true;
}
- else if( nBitCount != pDisplay->GetVisual( m_nXScreen ).GetDepth() )
+ else if( nBitCount != pDisplay_->GetVisual( m_nXScreen ).GetDepth() )
{
pColormap = new SalColormap( nBitCount );
bDeleteColormap = true;
}
- pGraphics_->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
- nDX_ = nDX;
- nDY_ = nDY;
- nDepth_ = nBitCount;
-
- if( hDrawable == None )
- hDrawable_ = limitXCreatePixmap( GetXDisplay(),
- pDisplay_->GetDrawable( m_nXScreen ),
- nDX_, nDY_,
- GetDepth() );
- else
- {
- hDrawable_ = hDrawable;
- bExternPixmap_ = true;
- }
+ pGraphics_->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
pGraphics_->Init( this, pColormap, bDeleteColormap );
-
- return hDrawable_ != None;
-}
-
-X11SalVirtualDevice::X11SalVirtualDevice() :
- m_nXScreen( 0 )
-{
- pDisplay_ = NULL;
- pGraphics_ = NULL;
- hDrawable_ = None;
- nDX_ = 0;
- nDY_ = 0;
- nDepth_ = 0;
- bGraphics_ = false;
- bExternPixmap_ = false;
}
X11SalVirtualDevice::~X11SalVirtualDevice()
@@ -196,8 +176,6 @@ SalGraphics* X11SalVirtualDevice::AcquireGraphics()
void X11SalVirtualDevice::ReleaseGraphics( SalGraphics* )
{ bGraphics_ = false; }
-#include "opengl/x11/gdiimpl.hxx"
-
bool X11SalVirtualDevice::SetSize( long nDX, long nDY )
{
if( bExternPixmap_ )
@@ -231,14 +209,7 @@ bool X11SalVirtualDevice::SetSize( long nDX, long nDY )
nDY_ = nDY;
if( pGraphics_ )
- {
- InitGraphics( this );
-
- // re-initialize OpenGLContext [!] having freed it's underlying pixmap above
- X11OpenGLSalGraphicsImpl *pImpl = dynamic_cast< X11OpenGLSalGraphicsImpl* >(pGraphics_->GetImpl());
- if( pImpl )
- pImpl->Init();
- }
+ pGraphics_->Init( this );
return true;
}