diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-26 09:22:25 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@collabora.co.uk> | 2014-12-02 08:34:51 +0100 |
commit | d6b51a87b482b69097100b9a2ce7ba85005e20ac (patch) | |
tree | c29780d4f11e703e0f2b571cd2094ae998d7b7bf /vcl | |
parent | 83c97b2a1c1a8d0531b6048fb27cf117b0da24e0 (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.mk | 1 | ||||
-rw-r--r-- | vcl/Library_vclplug_gen.mk | 1 | ||||
-rw-r--r-- | vcl/inc/opengl/framebuffer.hxx | 45 | ||||
-rw-r--r-- | vcl/inc/opengl/salbmp.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/opengl/texture.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/opengl/win/gdiimpl.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/opengl/x11/gdiimpl.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/opengl/x11/salvd.hxx | 55 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 15 | ||||
-rw-r--r-- | vcl/inc/svdata.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/unx/salgdi.h | 4 | ||||
-rw-r--r-- | vcl/inc/unx/salvd.h | 15 | ||||
-rw-r--r-- | vcl/opengl/framebuffer.cxx | 70 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 134 | ||||
-rw-r--r-- | vcl/opengl/salbmp.cxx | 17 | ||||
-rw-r--r-- | vcl/opengl/scale.cxx | 35 | ||||
-rw-r--r-- | vcl/opengl/win/gdiimpl.cxx | 2 | ||||
-rw-r--r-- | vcl/opengl/x11/gdiimpl.cxx | 64 | ||||
-rw-r--r-- | vcl/opengl/x11/salvd.cxx | 102 | ||||
-rw-r--r-- | vcl/source/gdi/salgdilayout.cxx | 2 | ||||
-rw-r--r-- | vcl/source/opengl/OpenGLContext.cxx | 127 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.cxx | 10 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi.cxx | 14 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salvd.cxx | 151 |
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; } |