summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-10 13:46:12 -0500
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-11-11 11:08:23 +0100
commit243047fd68820e15e13dd9afd33122aef20ca377 (patch)
tree78a436f00c586da307c6a9a4960e3d8977fccb71
parent7baadae3e8f4b0338234bd90135e90a355dc1dba (diff)
vcl: Use a different FBO when rendering using a VirtualDevice
Change-Id: I8cb97a4057c06ca09adfcac8dcd3f61ac9508430
-rw-r--r--vcl/inc/opengl/salbmp.hxx2
-rw-r--r--vcl/inc/opengl/texture.hxx3
-rw-r--r--vcl/inc/openglgdiimpl.hxx9
-rw-r--r--vcl/opengl/gdiimpl.cxx41
-rw-r--r--vcl/opengl/salbmp.cxx15
-rw-r--r--vcl/opengl/texture.cxx10
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx2
7 files changed, 75 insertions, 7 deletions
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index 6f7a03af09d4..77ac90bbbc55 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -81,7 +81,7 @@ public:
public:
- bool Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight );
+ bool Create( OpenGLContext& rContext, OpenGLTextureSharedPtr pTex, long nX, long nY, long nWidth, long nHeight );
bool Draw( OpenGLContext& rContext, const SalTwoRect& rPosAry );
GLuint GetTexture( OpenGLContext& rContext ) const;
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index f9d3ad864291..c0b6541d7700 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -39,6 +39,9 @@ public:
virtual ~OpenGLTexture();
GLuint Id() const;
+ int GetWidth() const;
+ int GetHeight() const;
+
void Bind();
void Unbind();
bool Draw();
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 9dfa231a7e1b..e9be6653dca0 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -23,6 +23,8 @@
#include "salgdiimpl.hxx"
#include <vcl/dllapi.h>
+#include "opengl/texture.hxx"
+
#include <vcl/opengl/OpenGLContext.hxx>
class SalFrame;
@@ -36,6 +38,10 @@ protected:
SalFrame* mpFrame;
SalVirtualDevice* mpVDev;
+ bool mbOffscreen;
+ GLuint mnFramebufferId;
+ OpenGLTextureSharedPtr mpOffscreenTex;
+
SalColor mnLineColor;
SalColor mnFillColor;
@@ -90,6 +96,9 @@ protected:
// operations to do after painting
virtual void PostDraw();
+ // enable/disable offscreen rendering
+ virtual void SetOffscreen( bool bOffscreen );
+
public:
OpenGLSalGraphicsImpl();
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6af704eb3c2a..94cba660e413 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -75,16 +75,21 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
void OpenGLSalGraphicsImpl::PreDraw()
{
maContext.makeCurrent();
+ // TODO: lfrb: make sure the render target has the right size
+ if( mbOffscreen )
+ glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
glViewport( 0, 0, GetWidth(), GetHeight() );
}
void OpenGLSalGraphicsImpl::PostDraw()
{
+ if( mbOffscreen )
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
}
void OpenGLSalGraphicsImpl::freeResources()
{
- // Delete shaders, programs and textures if not shared
+ // TODO Delete shaders, programs and textures if not shared
}
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
@@ -187,6 +192,38 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
{
}
+// enable/disbale offscreen rendering
+void OpenGLSalGraphicsImpl::SetOffscreen( bool bOffscreen )
+{
+ if( bOffscreen == mbOffscreen )
+ {
+ // Already disabled
+ if( !mbOffscreen )
+ return;
+
+ // Already enabled and same size
+ if( mpOffscreenTex->GetWidth() == GetWidth() &&
+ mpOffscreenTex->GetHeight() == GetHeight() )
+ return;
+ }
+ else
+ {
+ mbOffscreen = bOffscreen;
+ if( bOffscreen )
+ glGenFramebuffers( 1, &mnFramebufferId );
+ else
+ glDeleteFramebuffers( 1, &mnFramebufferId );
+ }
+
+ if( mbOffscreen )
+ {
+ glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
+ mpOffscreenTex.reset( new OpenGLTexture( GetWidth(), GetHeight() ) );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mpOffscreenTex->Id(), 0 );
+ CHECK_GL_ERROR();
+ }
+}
+
bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
{
SAL_INFO( "vcl.opengl", "::CreateSolidProgram" );
@@ -879,7 +916,7 @@ SalBitmap* OpenGLSalGraphicsImpl::getBitmap( long nX, long nY, long nWidth, long
SAL_INFO( "vcl.opengl", "::getBitmap " << nX << "," << nY <<
" " << nWidth << "x" << nHeight );
PreDraw();
- if( !pBitmap->Create( maContext, nX, nY, nWidth, nHeight ) )
+ if( !pBitmap->Create( maContext, mpOffscreenTex, nX, nY, nWidth, nHeight ) )
{
delete pBitmap;
pBitmap = NULL;
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index d54ace76021f..5a93aaa8b094 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -52,7 +52,7 @@ OpenGLSalBitmap::~OpenGLSalBitmap()
SAL_INFO( "vcl.opengl", "~OpenGLSalBitmap" );
}
-bool OpenGLSalBitmap::Create( OpenGLContext& rContext, long nX, long nY, long nWidth, long nHeight )
+bool OpenGLSalBitmap::Create( OpenGLContext& rContext, OpenGLTextureSharedPtr pTex, long nX, long nY, long nWidth, long nHeight )
{
static const BitmapPalette aEmptyPalette;
@@ -60,7 +60,6 @@ bool OpenGLSalBitmap::Create( OpenGLContext& rContext, long nX, long nY, long nW
SAL_INFO( "vcl.opengl", "OpenGLSalBitmap::Create from FBO" );
mpContext = &rContext;
- mpContext->makeCurrent();
mnWidth = nWidth;
mnHeight = nHeight;
mnBufWidth = 0;
@@ -70,8 +69,13 @@ bool OpenGLSalBitmap::Create( OpenGLContext& rContext, long nX, long nY, long nW
mnBits = 32;
maPalette = aEmptyPalette;
- mpTexture.reset( new OpenGLTexture( nX, nY, nWidth, nHeight ) );
+ // TODO: lfrb: Crop texture if size doesn't match the texture one
+ if( pTex )
+ mpTexture = pTex;
+ else
+ mpTexture.reset( new OpenGLTexture( nX, nY, nWidth, nHeight ) );
mbDirtyTexture = false;
+ SAL_INFO( "vcl.opengl", "Created texture " << mpTexture->Id() );
return true;
}
@@ -154,6 +158,7 @@ GLuint OpenGLSalBitmap::GetTexture( OpenGLContext& rContext ) const
const_cast<OpenGLSalBitmap*>(this)->mpContext = &rContext;
if( !mpTexture || mbDirtyTexture )
const_cast<OpenGLSalBitmap*>(this)->CreateTexture();
+ SAL_INFO( "vcl.opengl", "Got texture " << mpTexture->Id() );
return mpTexture->Id();
}
@@ -388,9 +393,9 @@ GLuint OpenGLSalBitmap::CreateTexture()
}
}
- SAL_INFO( "vcl.opengl", "::CreateTexture" );
mpContext->makeCurrent();
mpTexture.reset( new OpenGLTexture (mnBufWidth, mnBufHeight, nFormat, nType, pData ) );
+ SAL_INFO( "vcl.opengl", "Created texture " << mpTexture->Id() );
if( bAllocated )
delete pData;
@@ -412,6 +417,8 @@ bool OpenGLSalBitmap::ReadTexture()
GLuint nFramebufferId, nRenderbufferDepthId, nRenderbufferColorId;
sal_uInt8* pData = maUserBuffer.get();
+ SAL_INFO( "vcl.opengl", "::ReadTexture" );
+
// TODO Check mnTexWidth and mnTexHeight
mpContext->makeCurrent();
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 2770c20a5519..0c8dc1d69b8e 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -95,6 +95,16 @@ GLuint OpenGLTexture::Id() const
return mnTexture;
}
+int OpenGLTexture::GetWidth() const
+{
+ return mnWidth;
+}
+
+int OpenGLTexture::GetHeight() const
+{
+ return mnHeight;
+}
+
GLenum OpenGLTexture::GetFilter() const
{
return mnFilter;
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 353ec7649f39..6e803bd21acd 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -64,12 +64,14 @@ void X11OpenGLSalGraphicsImpl::Init()
{
Window aWin = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame)->GetX11Window();
maContext.init( mrParent.GetXDisplay(), aWin, mrParent.m_nXScreen.getXScreen());
+ SetOffscreen( false );
}
else if( mrParent.m_pVDev )
{
maContext.init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
mrParent.m_nXScreen.getXScreen() );
+ SetOffscreen( true );
}
else
{