include/vcl/opengl/OpenGLContext.hxx | 15 ++ vcl/CppunitTest_vcl_outdev.mk | 52 +++++++++ vcl/Library_vcl.mk | 1 vcl/Library_vclplug_gen.mk | 1 vcl/Module_vcl.mk | 1 vcl/headless/svpvd.cxx | 12 -- vcl/inc/headless/svpvd.hxx | 5 vcl/inc/opengl/framebuffer.hxx | 45 ++++++++ vcl/inc/opengl/salbmp.hxx | 1 vcl/inc/opengl/texture.hxx | 3 vcl/inc/opengl/win/gdiimpl.hxx | 9 - vcl/inc/opengl/x11/gdiimpl.hxx | 9 - vcl/inc/opengl/x11/salvd.hxx | 56 ++++++++++ vcl/inc/openglgdiimpl.hxx | 26 ++-- vcl/inc/quartz/salvd.h | 1 vcl/inc/salframe.hxx | 9 + vcl/inc/salgeom.hxx | 12 ++ vcl/inc/salvd.hxx | 8 - vcl/inc/svdata.hxx | 2 vcl/inc/unx/salgdi.h | 6 - vcl/inc/unx/salvd.h | 24 +--- vcl/inc/win/salgdi.h | 4 vcl/inc/win/salvd.h | 7 + vcl/opengl/framebuffer.cxx | 70 ++++++++++++ vcl/opengl/gdiimpl.cxx | 137 +++++++++++-------------- vcl/opengl/salbmp.cxx | 17 +-- vcl/opengl/scale.cxx | 35 ++---- vcl/opengl/win/gdiimpl.cxx | 56 ---------- vcl/opengl/x11/gdiimpl.cxx | 95 ++++++----------- vcl/opengl/x11/salvd.cxx | 97 +++++++++++++++++ vcl/qa/cppunit/outdev.cxx | 67 ++++++++++++ vcl/quartz/salvd.cxx | 16 -- vcl/source/gdi/salgdilayout.cxx | 2 vcl/source/gdi/virdev.cxx | 6 - vcl/source/opengl/OpenGLContext.cxx | 127 ++++++++++++++++++++--- vcl/unx/generic/gdi/gdiimpl.cxx | 10 - vcl/unx/generic/gdi/salgdi.cxx | 22 ++-- vcl/unx/generic/gdi/salvd.cxx | 157 +++++++++++------------------ vcl/unx/generic/gdi/x11cairotextrender.cxx | 36 ++---- vcl/win/source/gdi/salgdi.cxx | 4 vcl/win/source/gdi/salprn.cxx | 2 vcl/win/source/gdi/salvd.cxx | 17 +-- vcl/win/source/window/salframe.cxx | 4 43 files changed, 832 insertions(+), 454 deletions(-)
New commits: commit 5dcaefdae5ddf5ee70b4dd453afee69cdf8fc9d7 Author: Michael Meeks <[email protected]> Date: Sat Nov 29 22:55:31 2014 +0000 vcl: Consolidate size information around the GeometryProvider. Conflicts: vcl/inc/openglgdiimpl.hxx Change-Id: I1d764a8dba1850d2475f08e1014a085846f336c3 diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx index da1a278..30ade23 100644 --- a/vcl/inc/opengl/win/gdiimpl.hxx +++ b/vcl/inc/opengl/win/gdiimpl.hxx @@ -24,13 +24,10 @@ private: WinSalGraphics& mrParent; public: - WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics); + WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics, + SalGeometryProvider *mpProvider); protected: - virtual GLfloat GetWidth() const SAL_OVERRIDE; - virtual GLfloat GetHeight() const SAL_OVERRIDE; - virtual bool IsOffscreen() const SAL_OVERRIDE; - virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE; virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE; virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE; diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx index 53ebe5b..d6ef010 100644 --- a/vcl/inc/opengl/x11/gdiimpl.hxx +++ b/vcl/inc/opengl/x11/gdiimpl.hxx @@ -26,10 +26,6 @@ public: virtual ~X11OpenGLSalGraphicsImpl(); protected: - GLfloat GetWidth() const SAL_OVERRIDE; - GLfloat GetHeight() const SAL_OVERRIDE; - bool IsOffscreen() const SAL_OVERRIDE; - virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE; virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE; virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE; @@ -38,6 +34,9 @@ public: // implementation of X11GraphicsImpl virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE; + + virtual void Init() SAL_OVERRIDE; + bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE; bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY ) SAL_OVERRIDE; }; diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index ac42527..39e39fc 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -20,6 +20,7 @@ #ifndef INCLUDED_VCL_OPENGLGDIIMPL_HXX #define INCLUDED_VCL_OPENGLGDIIMPL_HXX +#include "salgeom.hxx" #include "salgdiimpl.hxx" #include <vcl/dllapi.h> @@ -40,6 +41,8 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl protected: boost::shared_ptr<OpenGLContext> mpContext; + /// Pointer to the SalFrame or SalVirtualDevice + SalGeometryProvider* mpParent; OpenGLFramebuffer* mpFramebuffer; // clipping @@ -144,13 +147,13 @@ public: public: // get the width of the device - virtual GLfloat GetWidth() const = 0; + GLfloat GetWidth() const { return mpParent ? mpParent->GetWidth() : 1; } // get the height of the device - virtual GLfloat GetHeight() const = 0; + GLfloat GetHeight() const { return mpParent ? mpParent->GetHeight() : 1; } // check whether this instance is used for offscreen rendering - virtual bool IsOffscreen() const = 0; + bool IsOffscreen() const { return mpParent ? mpParent->IsOffScreen() : true; } // operations to do before painting virtual void PreDraw(); @@ -172,7 +175,7 @@ protected: virtual bool UseContext( OpenGLContext* pContext ) = 0; public: - OpenGLSalGraphicsImpl(); + OpenGLSalGraphicsImpl(SalGeometryProvider* pParent); virtual ~OpenGLSalGraphicsImpl (); OpenGLContext* GetOpenGLContext(); diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index edf47b1..29697a9 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -29,6 +29,7 @@ #include <vcl/metric.hxx> #include "salgdi.hxx" +#include "salgeom.hxx" #include "sallayout.hxx" #include "vclpluginapi.h" @@ -132,6 +133,7 @@ public: inline const SalDisplay* GetDisplay() const; inline Display* GetXDisplay() const; inline const SalVisual& GetVisual() const; + SalGeometryProvider *GetGeometryProvider() const; inline Drawable GetDrawable() const { return hDrawable_; } void SetDrawable( Drawable d, SalX11Screen nXScreen ); XRenderPictFormat* GetXRenderFormat() const; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 443c1c2..5a46cb1f 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -21,6 +21,7 @@ #define INCLUDED_VCL_INC_WIN_SALGDI_H #include "sallayout.hxx" +#include "salgeom.hxx" #include "salgdi.hxx" #include "outfont.hxx" #include "PhysicalFontFace.hxx" @@ -243,7 +244,8 @@ public: HFONT ImplDoSetFont( FontSelectPattern* i_pFont, float& o_rFontScale, HFONT& o_rOldFont ); public: - explicit WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd); + explicit WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd, + SalGeometryProvider *pProvider); virtual ~WinSalGraphics(); SalGraphicsImpl* GetImpl() const SAL_OVERRIDE; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index beae9dd..2f0dd29 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -63,8 +63,9 @@ ((float) aColor.GetBlue()) * nFactor / 25500.0, \ 1.0f ) -OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl() +OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGeometryProvider* pParent) : mpContext(0) + , mpParent(pParent) , mpFramebuffer(NULL) , mbUseScissor(false) , mbUseStencil(false) diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx index 2bd31bf..939d4e0 100644 --- a/vcl/opengl/win/gdiimpl.cxx +++ b/vcl/opengl/win/gdiimpl.cxx @@ -13,7 +13,9 @@ #include <win/saldata.hxx> #include <win/salframe.h> -WinOpenGLSalGraphicsImpl::WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics): +WinOpenGLSalGraphicsImpl::WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics, + SalGeometryProvider *mpProvider): + OpenGLSalGraphicsImpl(mpProvider), mrParent(rGraphics) { } @@ -24,56 +26,6 @@ void WinOpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* OpenGLSalGraphicsImpl::DoCopyBits( rPosAry, *pImpl ); } -GLfloat WinOpenGLSalGraphicsImpl::GetWidth() const -{ - if( mrParent.gethWnd() && IsWindow( mrParent.gethWnd() ) ) - { - WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() ); - if( pFrame ) - { - if( pFrame->maGeometry.nWidth ) - return pFrame->maGeometry.nWidth; - else - { - // TODO: perhaps not needed, maGeometry should always be up-to-date - RECT aRect; - GetClientRect( mrParent.gethWnd(), &aRect ); - return aRect.right; - } - } - } - - return 1; -} - -GLfloat WinOpenGLSalGraphicsImpl::GetHeight() const -{ - if( mrParent.gethWnd() && IsWindow( mrParent.gethWnd() ) ) - { - WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() ); - if( pFrame ) - { - if( pFrame->maGeometry.nHeight ) - return pFrame->maGeometry.nHeight; - else - { - // TODO: perhaps not needed, maGeometry should always be up-to-date - RECT aRect; - GetClientRect( mrParent.gethWnd(), &aRect ); - return aRect.bottom; - } - } - } - - return 1; -} - -bool WinOpenGLSalGraphicsImpl::IsOffscreen() const -{ - WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() ); - return ( pFrame == NULL ); -} - OpenGLContext* WinOpenGLSalGraphicsImpl::CreateWinContext() { OpenGLContext* pContext = new OpenGLContext(); diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx index 07b8abf..e5070d7 100644 --- a/vcl/opengl/x11/gdiimpl.cxx +++ b/vcl/opengl/x11/gdiimpl.cxx @@ -26,7 +26,7 @@ #include <vcl/opengl/OpenGLHelper.hxx> X11OpenGLSalGraphicsImpl::X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ): - OpenGLSalGraphicsImpl(), + OpenGLSalGraphicsImpl(rParent.GetGeometryProvider()), mrParent(rParent) { } @@ -35,36 +35,11 @@ X11OpenGLSalGraphicsImpl::~X11OpenGLSalGraphicsImpl() { } -GLfloat X11OpenGLSalGraphicsImpl::GetWidth() const +void X11OpenGLSalGraphicsImpl::Init() { - if( mrParent.m_pFrame ) - return mrParent.m_pFrame->maGeometry.nWidth; - else if( mrParent.m_pVDev ) - return static_cast< X11OpenGLSalVirtualDevice* >(mrParent.m_pVDev)->GetWidth(); - return 1; -} - -GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const -{ - if( mrParent.m_pFrame ) - return mrParent.m_pFrame->maGeometry.nHeight; - else if( mrParent.m_pVDev ) - return static_cast< X11OpenGLSalVirtualDevice* >(mrParent.m_pVDev)->GetHeight(); - return 1; -} - -bool X11OpenGLSalGraphicsImpl::IsOffscreen() const -{ - X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame); - if( pProvider ) - return false; - else if( mrParent.m_pVDev ) - return true; - else - { - SAL_WARN( "vcl.opengl", "what happened here?" ); - return true; - } + // The m_pFrame and m_pVDev pointers are updated late in X11 + mpParent = mrParent.GetGeometryProvider(); + OpenGLSalGraphicsImpl::Init(); } OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext() diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 38aa7a3..7772972 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -487,4 +487,12 @@ void X11SalGraphics::EndPaint() return mpImpl->endPaint(); } +SalGeometryProvider *X11SalGraphics::GetGeometryProvider() const +{ + if (m_pFrame) + return static_cast< SalGeometryProvider * >(m_pFrame); + else + return static_cast< SalGeometryProvider * >(m_pVDev); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index 4c36bb3..c2d644d 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -613,7 +613,7 @@ OpenGLTexture* OpenGLCompatibleDC::getTexture() return new OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, reinterpret_cast<sal_uInt8*>(mpData)); } -WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd): +WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd, SalGeometryProvider *pProvider): mhLocalDC(0), mbPrinter(eType == WinSalGraphics::PRINTER), mbVirDev(eType == WinSalGraphics::VIRTUAL_DEVICE), @@ -634,7 +634,7 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW mnPenWidth(GSL_PEN_WIDTH) { if (OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter) - mpImpl.reset(new WinOpenGLSalGraphicsImpl(*this)); + mpImpl.reset(new WinOpenGLSalGraphicsImpl(*this, pProvider)); else mpImpl.reset(new WinSalGraphicsImpl(*this)); diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx index ad22b4e..7822662 100644 --- a/vcl/win/source/gdi/salprn.cxx +++ b/vcl/win/source/gdi/salprn.cxx @@ -1045,7 +1045,7 @@ static HDC ImplCreateSalPrnIC( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetup static WinSalGraphics* ImplCreateSalPrnGraphics( HDC hDC ) { - WinSalGraphics* pGraphics = new WinSalGraphics(WinSalGraphics::PRINTER, false, 0); + WinSalGraphics* pGraphics = new WinSalGraphics(WinSalGraphics::PRINTER, false, 0, /* CHECKME */ NULL); pGraphics->SetLayout( 0 ); pGraphics->setHDC(hDC); pGraphics->InitGraphics(); diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx index cea8a76..6758b09 100644 --- a/vcl/win/source/gdi/salvd.cxx +++ b/vcl/win/source/gdi/salvd.cxx @@ -105,7 +105,7 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, { WinSalVirtualDevice* pVDev = new WinSalVirtualDevice; SalData* pSalData = GetSalData(); - WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE, pGraphics->isScreen(), 0); + WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE, pGraphics->isScreen(), 0, pVDev); pVirGraphics->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL() pVirGraphics->setHDC(hDC); if ( pSalData->mhDitherPal && pVirGraphics->isScreen() ) @@ -115,8 +115,8 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, } pVirGraphics->InitGraphics(); - mnWidth = nDX; - mnHeight = nDY; + pVDev->mnWidth = nDX; + pVDev->mnHeight = nDY; pVDev->setHDC(hDC); pVDev->mhBmp = hBmp; if( hBmp ) @@ -207,6 +207,9 @@ bool WinSalVirtualDevice::SetSize( long nDX, long nDY ) HBITMAP hNewBmp = ImplCreateVirDevBitmap(getHDC(), nDX, nDY, mnBitCount, &pDummy); if ( hNewBmp ) { + mnWidth = nDX; + mnHeight = nDY; + SelectBitmap( getHDC(), hNewBmp ); DeleteBitmap( mhBmp ); mhBmp = hNewBmp; @@ -215,6 +218,8 @@ bool WinSalVirtualDevice::SetSize( long nDX, long nDY ) else { ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in SetSize" ); + mnWidth = 0; + mnHeight = 0; return FALSE; } } diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx index c8f5f3f..a048e2e 100644 --- a/vcl/win/source/window/salframe.cxx +++ b/vcl/win/source/window/salframe.cxx @@ -983,7 +983,7 @@ SalGraphics* WinSalFrame::AcquireGraphics() if ( !mpGraphics2 ) { - mpGraphics2 = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd); + mpGraphics2 = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd, this); mpGraphics2->setHDC(0); } @@ -1014,7 +1014,7 @@ SalGraphics* WinSalFrame::AcquireGraphics() HDC hDC = GetDC( mhWnd ); if ( hDC ) { - mpGraphics = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd); + mpGraphics = new WinSalGraphics(WinSalGraphics::WINDOW, true, mhWnd, this); mpGraphics->setHDC(hDC); if ( pSalData->mhDitherPal ) { commit c31ed7004dfb3e8e37ddeb9fddf0f015b661dd12 Author: Michael Meeks <[email protected]> Date: Sat Nov 29 22:14:36 2014 +0000 vcl: create a GeometryProvider interface. Implemented by both SalFrame and SalVirtualDevice, to help us to un-tangle code that needs to operate on resources associated with both of these without special cases. Change-Id: If681a002647e20c57186577fe039d4ac85bba872 diff --git a/vcl/inc/headless/svpvd.hxx b/vcl/inc/headless/svpvd.hxx index eb6b8d1..fa9d042 100644 --- a/vcl/inc/headless/svpvd.hxx +++ b/vcl/inc/headless/svpvd.hxx @@ -47,6 +47,10 @@ public: ) SAL_OVERRIDE; basebmp::BitmapDeviceSharedPtr getBitmapDevice() { return m_aDevice; } + + // SalGeometryProvider + virtual long GetWidth() const SAL_OVERRIDE { return m_aDevice.get() ? m_aDevice->getSize().getX() : 0; } + virtual long GetHeight() const SAL_OVERRIDE { return m_aDevice.get() ? m_aDevice->getSize().getY() : 0; } }; #endif // INCLUDED_VCL_INC_HEADLESS_SVPVD_HXX diff --git a/vcl/inc/opengl/x11/salvd.hxx b/vcl/inc/opengl/x11/salvd.hxx index 7696e04..7f5f1f5 100644 --- a/vcl/inc/opengl/x11/salvd.hxx +++ b/vcl/inc/opengl/x11/salvd.hxx @@ -36,10 +36,12 @@ public: const SystemGraphicsData *pData ); virtual ~X11OpenGLSalVirtualDevice(); + // SalGeometryProvider + virtual long GetWidth() const SAL_OVERRIDE { return mnWidth; } + virtual long GetHeight() const SAL_OVERRIDE { return mnHeight; } + 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; diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx index f427c24..cfc41b7 100644 --- a/vcl/inc/salframe.hxx +++ b/vcl/inc/salframe.hxx @@ -96,7 +96,9 @@ typedef sal_uInt64 SalExtStyle; struct SystemParentData; -class VCL_PLUGIN_PUBLIC SalFrame : public vcl::DeletionNotifier +class VCL_PLUGIN_PUBLIC SalFrame + : public vcl::DeletionNotifier + , public SalGeometryProvider { // the VCL window corresponding to this frame vcl::Window* m_pWindow; @@ -108,6 +110,11 @@ public: SalFrameGeometry maGeometry; + // SalGeometryProvider + virtual long GetWidth() const SAL_OVERRIDE { return maGeometry.nWidth; } + virtual long GetHeight() const SAL_OVERRIDE { return maGeometry.nHeight; } + virtual bool IsOffScreen() const SAL_OVERRIDE { return false; } + // SalGraphics or NULL, but two Graphics for all SalFrames // must be returned virtual SalGraphics* AcquireGraphics() = 0; diff --git a/vcl/inc/salgeom.hxx b/vcl/inc/salgeom.hxx index 138a6d9..d54c58a 100644 --- a/vcl/inc/salgeom.hxx +++ b/vcl/inc/salgeom.hxx @@ -20,6 +20,8 @@ #ifndef INCLUDED_VCL_INC_SALGEOM_HXX #define INCLUDED_VCL_INC_SALGEOM_HXX +#include <vcl/dllapi.h> + typedef struct _SalFrameGeometry { // screen position of upper left corner of drawable area in pixel long nX, nY; @@ -40,6 +42,16 @@ typedef struct _SalFrameGeometry { {} } SalFrameGeometry; +/// Interface used to share logic on sizing between +/// SalVirtualDevices and SalFrames +class VCL_PLUGIN_PUBLIC SalGeometryProvider { +public: + virtual ~SalGeometryProvider() {} + virtual long GetWidth() const = 0; + virtual long GetHeight() const = 0; + virtual bool IsOffScreen() const = 0; +}; + #endif // INCLUDED_VCL_INC_SALGEOM_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/salvd.hxx b/vcl/inc/salvd.hxx index 1397935..c07722f 100644 --- a/vcl/inc/salvd.hxx +++ b/vcl/inc/salvd.hxx @@ -22,15 +22,20 @@ #include <basebmp/bitmapdevice.hxx> #include <vcl/dllapi.h> +#include <salgeom.hxx> class SalGraphics; class VCL_PLUGIN_PUBLIC SalVirtualDevice + : public SalGeometryProvider { public: SalVirtualDevice() {} virtual ~SalVirtualDevice(); + // SalGeometryProvider + virtual bool IsOffScreen() const SAL_OVERRIDE { return true; } + // SalGraphics or NULL, but two Graphics for all SalVirtualDevices // must be returned virtual SalGraphics* AcquireGraphics() = 0; diff --git a/vcl/inc/unx/salvd.h b/vcl/inc/unx/salvd.h index 9b520a7..0b08521 100644 --- a/vcl/inc/unx/salvd.h +++ b/vcl/inc/unx/salvd.h @@ -64,8 +64,6 @@ public: } Pixmap GetDrawable() const { return hDrawable_; } sal_uInt16 GetDepth() const { return nDepth_; } - int GetWidth() const { return nDX_; } - int GetHeight() const { return nDY_; } SalX11Screen GetXScreenNumber() const { return m_nXScreen; } virtual SalGraphics* AcquireGraphics() SAL_OVERRIDE; @@ -73,6 +71,10 @@ public: /// Set new size, without saving the old contents virtual bool SetSize( long nNewDX, long nNewDY ) SAL_OVERRIDE; + + // SalGeometryProvider + virtual long GetWidth() const SAL_OVERRIDE { return nDX_; } + virtual long GetHeight() const SAL_OVERRIDE { return nDY_; } }; #endif // INCLUDED_VCL_INC_UNX_SALVD_H diff --git a/vcl/inc/win/salvd.h b/vcl/inc/win/salvd.h index 9abb46b..6ecba54 100644 --- a/vcl/inc/win/salvd.h +++ b/vcl/inc/win/salvd.h @@ -43,6 +43,8 @@ public: sal_uInt16 mnBitCount; // BitCount (0 or 1) bool mbGraphics; // is Graphics used bool mbForeignDC; // uses a foreign DC instead of a bitmap + long mnWidth; + long mnHeight; WinSalVirtualDevice(); virtual ~WinSalVirtualDevice(); @@ -52,6 +54,10 @@ public: virtual bool SetSize( long nNewDX, long nNewDY ); static HBITMAP ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, sal_uInt16 nBitCount, void **ppDummy); + + // SalGeometryProvider + virtual long GetWidth() const SAL_OVERRIDE { return mnWidth; } + virtual long GetHeight() const SAL_OVERRIDE { return mnHeight; } }; diff --git a/vcl/opengl/x11/salvd.cxx b/vcl/opengl/x11/salvd.cxx index 4fde8f8..7996cff 100644 --- a/vcl/opengl/x11/salvd.cxx +++ b/vcl/opengl/x11/salvd.cxx @@ -80,6 +80,7 @@ void X11OpenGLSalVirtualDevice::ReleaseGraphics( SalGraphics* ) mbGraphics = false; } + bool X11OpenGLSalVirtualDevice::SetSize( long nDX, long nDY ) { if( !nDX ) nDX = 1; diff --git a/vcl/unx/generic/gdi/x11cairotextrender.cxx b/vcl/unx/generic/gdi/x11cairotextrender.cxx index 2533107..0449b98 100644 --- a/vcl/unx/generic/gdi/x11cairotextrender.cxx +++ b/vcl/unx/generic/gdi/x11cairotextrender.cxx @@ -96,30 +96,26 @@ void X11CairoTextRender::clipRegion(cairo_t* cr) size_t X11CairoTextRender::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 1; + SalGeometryProvider *pProvider = mrParent.m_pFrame; + if( !pProvider ) + pProvider = mrParent.m_pVDev; + + if( pProvider ) + return pProvider->GetWidth(); + else + return 1; } size_t X11CairoTextRender::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 1; + SalGeometryProvider *pProvider = mrParent.m_pFrame; + if( !pProvider ) + pProvider = mrParent.m_pVDev; + + if( pProvider ) + return pProvider->GetHeight(); + else + return 1; } void X11CairoTextRender::drawSurface(cairo_t* /*cr*/) diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx index b5986b1..cea8a76 100644 --- a/vcl/win/source/gdi/salvd.cxx +++ b/vcl/win/source/gdi/salvd.cxx @@ -115,6 +115,8 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, } pVirGraphics->InitGraphics(); + mnWidth = nDX; + mnHeight = nDY; pVDev->setHDC(hDC); pVDev->mhBmp = hBmp; if( hBmp ) @@ -152,6 +154,8 @@ WinSalVirtualDevice::WinSalVirtualDevice() mnBitCount = 0; // BitCount (0 or 1) mbGraphics = FALSE; // is Graphics used mbForeignDC = FALSE; // uses a foreign DC instead of a bitmap + mnWidth = 0; + mnHeight = 0; } WinSalVirtualDevice::~WinSalVirtualDevice() commit c22d5338fad383800b35efa458561bb89b604922 Author: Michael Meeks <[email protected]> Date: Sat Nov 29 21:42:47 2014 +0000 vcl: remove SalVirtualDevice::GetWidth It is presumed that #i59315# is fixed already, and that this is no longer necessary. Change-Id: Ifb2f6550fac2481c4fec269b38d6e806753cb53e diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx index dc280db..e2f9042 100644 --- a/vcl/headless/svpvd.cxx +++ b/vcl/headless/svpvd.cxx @@ -93,18 +93,6 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY, return true; } -void SvpSalVirtualDevice::GetSize( long& rWidth, long& rHeight ) -{ - if( m_aDevice.get() ) - { - B2IVector aDevSize( m_aDevice->getSize() ); - rWidth = aDevSize.getX(); - rHeight = aDevSize.getY(); - } - else - rWidth = rHeight = 0; -} - #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/headless/svpvd.hxx b/vcl/inc/headless/svpvd.hxx index e69bf8f..eb6b8d1 100644 --- a/vcl/inc/headless/svpvd.hxx +++ b/vcl/inc/headless/svpvd.hxx @@ -45,7 +45,6 @@ public: const basebmp::RawMemorySharedArray &pBuffer, const bool bTopDown ) SAL_OVERRIDE; - virtual void GetSize( long& rWidth, long& rHeight ) SAL_OVERRIDE; basebmp::BitmapDeviceSharedPtr getBitmapDevice() { return m_aDevice; } }; diff --git a/vcl/inc/opengl/x11/salvd.hxx b/vcl/inc/opengl/x11/salvd.hxx index 0d7143b..7696e04 100644 --- a/vcl/inc/opengl/x11/salvd.hxx +++ b/vcl/inc/opengl/x11/salvd.hxx @@ -47,7 +47,6 @@ public: // 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 diff --git a/vcl/inc/quartz/salvd.h b/vcl/inc/quartz/salvd.h index f48a19a..e1d1d51 100644 --- a/vcl/inc/quartz/salvd.h +++ b/vcl/inc/quartz/salvd.h @@ -61,7 +61,6 @@ public: virtual SalGraphics* AcquireGraphics() SAL_OVERRIDE; virtual void ReleaseGraphics( SalGraphics* pGraphics ) SAL_OVERRIDE; virtual bool SetSize( long nNewDX, long nNewDY ) SAL_OVERRIDE; - virtual void GetSize( long& rWidth, long& rHeight ) SAL_OVERRIDE; }; #endif // INCLUDED_VCL_INC_QUARTZ_SALVD_H diff --git a/vcl/inc/salvd.hxx b/vcl/inc/salvd.hxx index f5a63ee..1397935 100644 --- a/vcl/inc/salvd.hxx +++ b/vcl/inc/salvd.hxx @@ -49,9 +49,6 @@ public: // pBuffer (and bTopDown). return SetSize( nNewDX, nNewDY ); } - - /// Get actual VDev size in pixel - virtual void GetSize( long& rWidth, long& rHeight ) = 0; }; #endif // INCLUDED_VCL_INC_SALVD_HXX diff --git a/vcl/inc/unx/salvd.h b/vcl/inc/unx/salvd.h index b1caa68..9b520a7 100644 --- a/vcl/inc/unx/salvd.h +++ b/vcl/inc/unx/salvd.h @@ -71,9 +71,8 @@ public: virtual SalGraphics* AcquireGraphics() SAL_OVERRIDE; virtual void ReleaseGraphics( SalGraphics* pGraphics ) SAL_OVERRIDE; - // Set new size, without saving the old contents + /// 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_UNX_SALVD_H diff --git a/vcl/inc/win/salvd.h b/vcl/inc/win/salvd.h index 2c59f47..9abb46b 100644 --- a/vcl/inc/win/salvd.h +++ b/vcl/inc/win/salvd.h @@ -50,7 +50,6 @@ public: virtual SalGraphics* AcquireGraphics(); virtual void ReleaseGraphics( SalGraphics* pGraphics ); virtual bool SetSize( long nNewDX, long nNewDY ); - virtual void GetSize( long& rWidth, long& rHeight ); static HBITMAP ImplCreateVirDevBitmap(HDC hDC, long nDX, long nDY, sal_uInt16 nBitCount, void **ppDummy); }; diff --git a/vcl/opengl/x11/salvd.cxx b/vcl/opengl/x11/salvd.cxx index b7c4eea..4fde8f8 100644 --- a/vcl/opengl/x11/salvd.cxx +++ b/vcl/opengl/x11/salvd.cxx @@ -93,10 +93,4 @@ bool X11OpenGLSalVirtualDevice::SetSize( long nDX, long nDY ) return true; } -void X11OpenGLSalVirtualDevice::GetSize( long& rWidth, long& rHeight ) -{ - rWidth = mnWidth; - rHeight = mnHeight; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/quartz/salvd.cxx b/vcl/quartz/salvd.cxx index f430908..a524c1e 100644 --- a/vcl/quartz/salvd.cxx +++ b/vcl/quartz/salvd.cxx @@ -277,20 +277,4 @@ bool AquaSalVirtualDevice::SetSize( long nDX, long nDY ) return (mxLayer != NULL); } -void AquaSalVirtualDevice::GetSize( long& rWidth, long& rHeight ) -{ - if( mxLayer ) - { - const CGSize aSize = CGLayerGetSize( mxLayer ); - rWidth = static_cast<long>(aSize.width); - rHeight = static_cast<long>(aSize.height); - CG_TRACE( "CGLayerGetSize(" << mxLayer << ") = " << aSize << "(" << rWidth << "x" << rHeight << ")" ); - } - else - { - rWidth = 0; - rHeight = 0; - } -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx index d783cd9..063bef1 100644 --- a/vcl/source/gdi/virdev.cxx +++ b/vcl/source/gdi/virdev.cxx @@ -164,12 +164,6 @@ void VirtualDevice::ImplInitVirDev( const OutputDevice* pOutDev, mbScreenComp = true; mnAlphaDepth = -1; - // #i59315# init vdev size from system object, when passed a - // SystemGraphicsData. Otherwise, output size will always - // incorrectly stay at (1,1) - if( pData && mpVirDev ) - mpVirDev->GetSize(mnOutWidth,mnOutHeight); - if( mnBitCount < 8 ) SetAntialiasing( ANTIALIASING_DISABLE_TEXT ); diff --git a/vcl/unx/generic/gdi/salvd.cxx b/vcl/unx/generic/gdi/salvd.cxx index 7967a4d..b4bcfa1 100644 --- a/vcl/unx/generic/gdi/salvd.cxx +++ b/vcl/unx/generic/gdi/salvd.cxx @@ -214,10 +214,4 @@ bool X11SalVirtualDevice::SetSize( long nDX, long nDY ) return true; } -void X11SalVirtualDevice::GetSize( long& rWidth, long& rHeight ) -{ - rWidth = GetWidth(); - rHeight = GetHeight(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx index c85133d..b5986b1 100644 --- a/vcl/win/source/gdi/salvd.cxx +++ b/vcl/win/source/gdi/salvd.cxx @@ -216,10 +216,4 @@ bool WinSalVirtualDevice::SetSize( long nDX, long nDY ) } } -void WinSalVirtualDevice::GetSize( long& rWidth, long& rHeight ) -{ - rWidth = GetDeviceCaps( getHDC(), HORZRES ); - rHeight= GetDeviceCaps( getHDC(), VERTRES ); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 1c6843f426314637e542949e8c71542a1c33d3c9 Author: Michael Meeks <[email protected]> Date: Fri Nov 28 16:11:25 2014 +0000 vcl: initial outdev unit test - for VirtualDevices. Change-Id: Ia2bb1f8110c738cfbf6ff84293af115b32abeb93 diff --git a/vcl/CppunitTest_vcl_outdev.mk b/vcl/CppunitTest_vcl_outdev.mk new file mode 100644 index 0000000..a5adcee --- /dev/null +++ b/vcl/CppunitTest_vcl_outdev.mk @@ -0,0 +1,52 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_CppunitTest_CppunitTest,vcl_outdev)) + +$(eval $(call gb_CppunitTest_set_include,vcl_outdev,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,vcl_outdev, \ + vcl/qa/cppunit/outdev \ +)) + +$(eval $(call gb_CppunitTest_use_externals,vcl_outdev,boost_headers)) + +$(eval $(call gb_CppunitTest_use_libraries,vcl_outdev, \ + comphelper \ + cppu \ + cppuhelper \ + sal \ + svt \ + test \ + tl \ + unotest \ + vcl \ + $(gb_UWINAPI) \ +)) + +$(eval $(call gb_CppunitTest_use_api,vcl_outdev,\ + udkapi \ + offapi \ +)) + +$(eval $(call gb_CppunitTest_use_ure,vcl_outdev)) +$(eval $(call gb_CppunitTest_use_vcl,vcl_outdev)) + +$(eval $(call gb_CppunitTest_use_components,vcl_outdev,\ + configmgr/source/configmgr \ + i18npool/util/i18npool \ + ucb/source/core/ucb1 \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,vcl_outdev)) + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index 01db2e7..329740a 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -101,6 +101,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\ CppunitTest_vcl_fontcharmap \ CppunitTest_vcl_complextext \ CppunitTest_vcl_filters_test \ + CppunitTest_vcl_outdev \ CppunitTest_vcl_app_test \ CppunitTest_vcl_wmf_test \ )) diff --git a/vcl/qa/cppunit/outdev.cxx b/vcl/qa/cppunit/outdev.cxx new file mode 100644 index 0000000..47e8dcf --- /dev/null +++ b/vcl/qa/cppunit/outdev.cxx @@ -0,0 +1,67 @@ +/* -*- 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 <unotest/filters-test.hxx> +#include <test/bootstrapfixture.hxx> + +#include <vcl/virdev.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/bmpacc.hxx> +#include <vcl/wrkwin.hxx> + +class VclOutdevTest : public test::BootstrapFixture +{ +public: + VclOutdevTest() : BootstrapFixture(true, false) {} + + void testVirtualDevice(); + + CPPUNIT_TEST_SUITE(VclOutdevTest); + CPPUNIT_TEST(testVirtualDevice); + CPPUNIT_TEST_SUITE_END(); +}; + +void VclOutdevTest::testVirtualDevice() +{ + VirtualDevice aVDev; + aVDev.SetOutputSizePixel(Size(32,32)); + aVDev.SetBackground(Wallpaper(COL_WHITE)); + aVDev.Erase(); + aVDev.DrawPixel(Point(1,2),COL_GREEN); + aVDev.DrawPixel(Point(31,30),COL_RED); + + CPPUNIT_ASSERT(aVDev.GetPixel(Point(0,0)) == COL_WHITE); + CPPUNIT_ASSERT(aVDev.GetPixel(Point(1,2)) == COL_GREEN); + CPPUNIT_ASSERT(aVDev.GetPixel(Point(31,30)) == COL_RED); + CPPUNIT_ASSERT(aVDev.GetPixel(Point(30,31)) == COL_WHITE); + + Size aSize = aVDev.GetOutputSizePixel(); + CPPUNIT_ASSERT(aSize == Size(32,32)); + + Bitmap aBmp = aVDev.GetBitmap(Point(),aSize); + Bitmap::ScopedReadAccess pAcc(aBmp); + + // Gotcha: y and x swap for BitmapReadAccess: deep joy. + CPPUNIT_ASSERT(pAcc->GetPixel(0,0) == Color(COL_WHITE)); + CPPUNIT_ASSERT(pAcc->GetPixel(2,1) == Color(COL_GREEN)); + CPPUNIT_ASSERT(pAcc->GetPixel(30,31) == Color(COL_RED)); + CPPUNIT_ASSERT(pAcc->GetPixel(31,30) == Color(COL_WHITE)); + +#if 0 + vcl::Window* pWin = new WorkWindow( (vcl::Window *)NULL ); + CPPUNIT_ASSERT( pWin != NULL ); + OutputDevice *pOutDev = static_cast< OutputDevice * >( pWin ); +#endif +} + +CPPUNIT_TEST_SUITE_REGISTRATION(VclOutdevTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit d6b51a87b482b69097100b9a2ce7ba85005e20ac Author: Louis-Francis Ratté-Boulianne <[email protected]> Date: Wed Nov 26 09:22:25 2014 -0500 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 diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 7931f4b..6d99488 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 { @@ -175,6 +178,13 @@ public: bool init( HDC hDC, HWND hWnd ); #endif + // 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(); @@ -226,6 +236,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 3113497..737a031 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 76be2c1..29695e9 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 0000000..4ccc1c5 --- /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 20b0e61..bc232b1 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 eb003cf..ad4738a 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 de25d23..da1a278 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 f5e5bfb..53ebe5b 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 0000000..0d7143b --- /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 bc813f1..ac42527 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 2d86988..5fb496b 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 8ef42ba..edf47b1 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 dd84c35..b1caa68 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 0000000..29f9a78 --- /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 cff4a0b..beae9dd 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 7a1af0d..6fdb2af 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 9c52cc2..d396652 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 0815927..2bd31bf 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 80db3a9..07b8abf 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 0000000..b7c4eea --- /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 dc419a0..88a0abc 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 4c64f63..84d6bbe 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 46865d0..f2f909c 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 80f24f0..38aa7a3 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 71ec509..7967a4d 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; }
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
