summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-26 09:22:25 -0500
committerLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-26 17:53:03 -0500
commit7ac688fa6d7756ce25a3cfe8b4e3d06379a8dd08 (patch)
treea5e5d9c8d773d0c3ea200f76a24bd38f26e148e0
parentd45409468b98ada43c0536fc1b0ba5e221d5b9bf (diff)
vcl: Use the current OpenGL context for VirtualDevice and Bitmap if possiblefeature/lfrb-vcl-opengl
Change-Id: I17f6ce66fb8b5bc027d35b4016ae56c24ee0a738
-rw-r--r--include/vcl/opengl/OpenGLContext.hxx15
-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/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.cxx138
-rw-r--r--vcl/opengl/salbmp.cxx17
-rw-r--r--vcl/opengl/scale.cxx35
-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.cxx124
-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
23 files changed, 610 insertions, 276 deletions
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 9be9c593b362..1b2185175fe7 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -55,6 +55,9 @@ class NSOpenGLView;
#include <tools/gen.hxx>
#include <vcl/syschild.hxx>
+class OpenGLFramebuffer;
+class OpenGLTexture;
+
/// Holds the information of our new child window
struct GLWindow
{
@@ -177,6 +180,13 @@ public:
void AddRef();
void DeRef();
+ // use these methods right after setting a context to make sure drawing happens
+ // in the right FBO (default one is for onscreen painting)
+ bool AcquireDefaultFramebuffer();
+ bool AcquireFramebuffer( OpenGLFramebuffer* pFramebuffer );
+ OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture );
+ void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer );
+
void makeCurrent();
void resetCurrent();
void swapBuffers();
@@ -229,6 +239,11 @@ private:
bool mbPixmap; // is a pixmap instead of a window
#endif
+ int mnFramebufferCount;
+ OpenGLFramebuffer* mpCurrentFramebuffer;
+ OpenGLFramebuffer* mpFirstFramebuffer;
+ OpenGLFramebuffer* mpLastFramebuffer;
+
public:
vcl::Region maClipRegion;
int mnPainting;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 81f774a98644..a231daea37d1 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -125,6 +125,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 449c1b68adf3..6a812d007af0 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/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 ee7889ea69a4..043bd9528fa4 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"
@@ -37,6 +38,7 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
protected:
OpenGLContext* mpContext;
+ OpenGLFramebuffer* mpFramebuffer;
// clipping
vcl::Region maClipRegion;
@@ -44,7 +46,6 @@ protected:
bool mbUseStencil;
bool mbOffscreen;
- GLuint mnFramebufferId;
OpenGLTexture maOffscreenTex;
SalColor mnLineColor;
@@ -156,23 +157,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 212e036ea13f..be40afc1f703 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -345,7 +345,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 8f4c6c445f8e..28f7959567b1 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)
@@ -112,24 +112,25 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
ReleaseContext();
}
-bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
+OpenGLContext* OpenGLSalGraphicsImpl::GetOpenGLContext()
+{
+ if( !mpContext )
+ AcquireContext();
+ return mpContext;
+}
+
+bool OpenGLSalGraphicsImpl::AcquireContext( )
{
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 ) )
+ if( UseContext( pContext ) )
break;
pContext = pContext->mpPrevContext;
}
@@ -137,7 +138,7 @@ bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
if( pContext )
pContext->AddRef();
else
- pContext = CreateWinContext();
+ pContext = mbOffscreen ? CreatePixmapContext() : CreateWinContext();
mpContext = pContext;
return (mpContext != NULL);
@@ -153,68 +154,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 ) ) )
+ if( !UseContext( mpContext ) )
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();
@@ -223,15 +197,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();
}
@@ -287,6 +262,8 @@ void OpenGLSalGraphicsImpl::ImplInitClipRegion()
glStencilFunc( GL_EQUAL, 1, 0x1 );
glEnable( GL_STENCIL_TEST );
}
+
+ CHECK_GL_ERROR();
}
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
@@ -379,28 +356,27 @@ 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;
- }
+ SalTwoRect aPosAry;
+ aPosAry.mnSrcX = aPosAry.mnDestX = 0;
+ aPosAry.mnSrcY = aPosAry.mnDestY = 0;
+ aPosAry.mnSrcWidth = aPosAry.mnDestWidth = GetWidth();
+ aPosAry.mnSrcHeight = aPosAry.mnDestHeight = GetHeight();
- SalTwoRect aPosAry;
- aPosAry.mnSrcX = aPosAry.mnDestX = 0;
- aPosAry.mnSrcY = aPosAry.mnDestY = 0;
- aPosAry.mnSrcWidth = aPosAry.mnDestWidth = GetWidth();
- aPosAry.mnSrcHeight = aPosAry.mnDestHeight = GetHeight();
-
- // TODO: 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;
@@ -1916,13 +1892,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 8cd756176e74..ce566b061e70 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/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 605cbd55d760..b01e476ba8a1 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..b0dbc0094dd6
--- /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 );
+
+ 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 a075b4de0070..6a85e59affd8 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 caf3d3022293..3eb7d25462dd 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'
@@ -53,6 +56,9 @@ OpenGLContext::OpenGLContext():
mbRequestLegacyContext(false),
mbUseDoubleBufferedRendering(true),
mbRequestVirtualDevice(false),
+ mpCurrentFramebuffer(NULL),
+ mpFirstFramebuffer(NULL),
+ mpLastFramebuffer(NULL),
mnPainting(0),
mpPrevContext(NULL),
mpNextContext(NULL)
@@ -74,15 +80,6 @@ OpenGLContext::OpenGLContext():
OpenGLContext::~OpenGLContext()
{
-#if defined( WNT )
- if (m_aGLWin.hRC)
- {
- vShareList.erase(std::remove(vShareList.begin(), vShareList.end(), m_aGLWin.hRC));
-
- wglMakeCurrent( m_aGLWin.hDC, 0 );
- wglDeleteContext( m_aGLWin.hRC );
- ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC );
- }
ImplSVData* pSVData = ImplGetSVData();
if( mpPrevContext )
mpPrevContext->mpNextContext = mpNextContext;
@@ -93,6 +90,15 @@ OpenGLContext::~OpenGLContext()
else
pSVData->maGDIData.mpLastContext = mpPrevContext;
+#if defined( WNT )
+ if (m_aGLWin.hRC)
+ {
+ vShareList.erase(std::remove(vShareList.begin(), vShareList.end(), m_aGLWin.hRC));
+
+ wglMakeCurrent( m_aGLWin.hDC, 0 );
+ wglDeleteContext( m_aGLWin.hRC );
+ ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC );
+ }
#elif defined( MACOSX )
OpenGLWrapper::resetCurrent();
#elif defined( IOS ) || defined( ANDROID )
@@ -579,6 +585,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)
@@ -663,6 +670,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;
@@ -681,8 +690,6 @@ bool OpenGLContext::init(Display* dpy, Pixmap pix, unsigned int width, unsigned
mbPixmap = true;
- initOpenGLFunctionPointers();
-
return ImplInit();
}
@@ -1203,13 +1210,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
}
@@ -1282,4 +1308,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 91c4db7b4221..28beaf4e23b1 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -739,7 +739,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 ) );
@@ -861,7 +861,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 )
@@ -988,7 +988,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();
@@ -1575,7 +1575,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;
}
@@ -1849,7 +1849,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 3c1a7279c421..d9eb7df2cf74 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -148,11 +148,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,
@@ -160,11 +156,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;
}