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
This commit is contained in:
committed by
Markus Mohrhard
parent
83c97b2a1c
commit
d6b51a87b4
@@ -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;
|
||||
|
@@ -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 \
|
||||
|
@@ -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
|
||||
|
45
vcl/inc/opengl/framebuffer.hxx
Normal file
45
vcl/inc/opengl/framebuffer.hxx
Normal file
@@ -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: */
|
@@ -39,6 +39,7 @@ class BitmapPalette;
|
||||
class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap
|
||||
{
|
||||
private:
|
||||
OpenGLContext* mpContext;
|
||||
OpenGLTexture maTexture;
|
||||
bool mbDirtyTexture;
|
||||
BitmapPalette maPalette;
|
||||
|
@@ -22,6 +22,9 @@
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <vcl/dllapi.h>
|
||||
#include <vcl/salgtype.hxx>
|
||||
|
||||
#include <tools/gen.hxx>
|
||||
|
||||
class ImplOpenGLTexture
|
||||
{
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
55
vcl/inc/opengl/x11/salvd.hxx
Normal file
55
vcl/inc/opengl/x11/salvd.hxx
Normal file
@@ -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: */
|
@@ -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;
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -44,19 +44,12 @@ class X11SalVirtualDevice : public SalVirtualDevice
|
||||
bool bExternPixmap_;
|
||||
|
||||
public:
|
||||
X11SalVirtualDevice();
|
||||
virtual ~X11SalVirtualDevice();
|
||||
|
||||
bool Init( SalDisplay *pDisplay,
|
||||
X11SalVirtualDevice( SalGraphics *pGraphics,
|
||||
long nDX, long nDY,
|
||||
sal_uInt16 nBitCount,
|
||||
SalX11Screen nXScreen,
|
||||
Pixmap hDrawable = None,
|
||||
XRenderPictFormat* pXRenderFormat = NULL );
|
||||
void InitGraphics( X11SalVirtualDevice *pVD )
|
||||
{
|
||||
pGraphics_->Init( pVD );
|
||||
}
|
||||
const SystemGraphicsData *pData );
|
||||
virtual ~X11SalVirtualDevice();
|
||||
|
||||
Display *GetXDisplay() const
|
||||
{
|
||||
return pDisplay_->GetDisplay();
|
||||
|
70
vcl/opengl/framebuffer.cxx
Normal file
70
vcl/opengl/framebuffer.cxx
Normal file
@@ -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: */
|
@@ -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();
|
||||
else
|
||||
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
if( !mbOffscreen )
|
||||
mpContext->AcquireDefaultFramebuffer();
|
||||
else
|
||||
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);
|
||||
|
||||
// TODO: improve performance: lfrb: User GL_ARB_copy_image?
|
||||
// TODO: lfrb: User GL_ARB_copy_image?
|
||||
OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 );
|
||||
glViewport( 0, 0, GetWidth(), GetHeight() );
|
||||
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 )
|
||||
|
@@ -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;
|
||||
|
@@ -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 );
|
||||
OpenGLTexture aNewTex = OpenGLTexture( nNewWidth, nNewHeight );
|
||||
pFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
|
||||
|
||||
glUseProgram( nProgram );
|
||||
glUniform1i( mnTexSamplerUniform, 0 );
|
||||
|
||||
OpenGLTexture aNewTex = OpenGLTexture( nNewWidth, nNewHeight );
|
||||
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 );
|
||||
|
||||
glViewport( 0, 0, nNewWidth, nNewHeight );
|
||||
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 ) );
|
||||
|
@@ -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;
|
||||
|
@@ -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()
|
||||
{
|
||||
X11OpenGLSalVirtualDevice* pVDev = dynamic_cast<X11OpenGLSalVirtualDevice*>(mrParent.m_pVDev);
|
||||
|
||||
if( pVDev == NULL )
|
||||
return NULL;
|
||||
|
||||
return ImplGetDefaultWindow()->GetGraphics()->GetOpenGLContext();
|
||||
}
|
||||
|
||||
bool X11OpenGLSalGraphicsImpl::UseContext( OpenGLContext* pContext )
|
||||
{
|
||||
X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
|
||||
|
||||
if( !pProvider || !pContext->isInitialized() )
|
||||
if( !pContext->isInitialized() )
|
||||
return false;
|
||||
return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
|
||||
}
|
||||
|
||||
OpenGLContext* X11OpenGLSalGraphicsImpl::CreatePixmapContext()
|
||||
{
|
||||
if( mrParent.m_pVDev == NULL )
|
||||
return NULL;
|
||||
OpenGLContext* pContext = new OpenGLContext();
|
||||
pContext->init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
|
||||
mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
|
||||
mrParent.m_nXScreen.getXScreen() );
|
||||
return pContext;
|
||||
if( !pProvider )
|
||||
return ( pContext->getOpenGLWindow().win != None );
|
||||
else
|
||||
return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
|
||||
}
|
||||
|
||||
void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
|
||||
|
102
vcl/opengl/x11/salvd.cxx
Normal file
102
vcl/opengl/x11/salvd.cxx
Normal file
@@ -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: */
|
@@ -81,7 +81,7 @@ OpenGLContext* SalGraphics::GetOpenGLContext() const
|
||||
{
|
||||
OpenGLSalGraphicsImpl *pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(GetImpl());
|
||||
if (pImpl)
|
||||
return &pImpl->GetOpenGLContext();
|
||||
return pImpl->GetOpenGLContext();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -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: */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -149,11 +149,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
|
||||
m_aXRenderPicture = 0;
|
||||
}
|
||||
|
||||
if( hDrawable_ )
|
||||
{
|
||||
mpImpl->Init();
|
||||
// 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()
|
||||
|
@@ -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,
|
||||
X11SalVirtualDevice::X11SalVirtualDevice( SalGraphics* pGraphics,
|
||||
long nDX, long nDY,
|
||||
sal_uInt16 nBitCount,
|
||||
SalX11Screen nXScreen,
|
||||
Pixmap hDrawable,
|
||||
XRenderPictFormat* pXRenderFormat )
|
||||
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 ) {
|
||||
pGraphics_->SetXRenderFormat( pXRenderFormat );
|
||||
if( pXRenderFormat->colormap )
|
||||
pColormap = new SalColormap( pDisplay, pXRenderFormat->colormap, m_nXScreen );
|
||||
else
|
||||
pColormap = new SalColormap( nBitCount );
|
||||
bDeleteColormap = true;
|
||||
}
|
||||
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 )
|
||||
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() );
|
||||
else
|
||||
{
|
||||
hDrawable_ = hDrawable;
|
||||
bExternPixmap_ = true;
|
||||
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 );
|
||||
else
|
||||
pColormap = new SalColormap( nBitCount );
|
||||
bDeleteColormap = true;
|
||||
}
|
||||
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()
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user