summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-12 15:37:11 -0500
committerMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-11-13 07:54:19 +0100
commita6fee2ca4c3bd502df755be64d2b62c1a4d2c1bb (patch)
treec5d51ca450836de201ac472a89a7705480f67248 /vcl
parentc4e494bc62faa810c1b373f2e6ba7142c2b1c88d (diff)
vcl: Use scissor or stencil for clipping in OpenGL backend
Change-Id: Ib6620572391999d5f8124a1a8695909d6c48643d
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/openglgdiimpl.hxx4
-rw-r--r--vcl/opengl/gdiimpl.cxx68
-rw-r--r--vcl/source/gdi/region.cxx17
3 files changed, 68 insertions, 21 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 3d1c585cb6ab..82bb919a5c3c 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -40,6 +40,10 @@ protected:
SalVirtualDevice* mpVDev;
int mnPainting;
+ // clipping
+ bool mbUseScissor;
+ bool mbUseStencil;
+
bool mbOffscreen;
GLuint mnFramebufferId;
OpenGLTextureSharedPtr mpOffscreenTex;
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 669b1905dafb..252d30309f10 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -61,6 +61,8 @@
OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
: mpFrame(NULL)
, mnPainting(0)
+ , mbUseScissor(false)
+ , mbUseStencil(false)
, mbOffscreen(false)
, mnFramebufferId(0)
, mpOffscreenTex(nullptr)
@@ -97,6 +99,10 @@ void OpenGLSalGraphicsImpl::PreDraw()
if( mbOffscreen )
glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
glViewport( 0, 0, GetWidth(), GetHeight() );
+ if( mbUseScissor )
+ glEnable( GL_SCISSOR_TEST );
+ if( mbUseStencil )
+ glEnable( GL_STENCIL_TEST );
CHECK_GL_ERROR();
}
@@ -105,8 +111,12 @@ void OpenGLSalGraphicsImpl::PostDraw()
{
if( mbOffscreen )
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- if( mnPainting == 0 )
+ else if( mnPainting == 0 )
glFlush();
+ if( mbUseScissor )
+ glDisable( GL_SCISSOR_TEST );
+ if( mbUseStencil )
+ glDisable( GL_STENCIL_TEST );
CHECK_GL_ERROR();
}
@@ -117,28 +127,46 @@ void OpenGLSalGraphicsImpl::freeResources()
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
{
- const basegfx::B2DPolyPolygon aClip( rClip.GetAsB2DPolyPolygon() );
+ SAL_INFO( "vcl.opengl", "::setClipRegion " << rClip );
- SAL_INFO( "vcl.opengl", "::setClipRegion" );
+ if( rClip.IsEmpty() )
+ {
+ ResetClipRegion();
+ return true;
+ }
- /*maContext.makeCurrent();
- glViewport( 0, 0, GetWidth(), GetHeight() );
+ if( false ) //rClip.IsRectangle() )
+ {
+ Rectangle aRect( rClip.GetBoundRect() );
- glEnable( GL_STENCIL_TEST );
+ mbUseStencil = false;
+ mbUseScissor = true;
+ maContext.makeCurrent();
+ glScissor( aRect.Left(), GetHeight() - aRect.Top(), aRect.GetWidth(), aRect.GetHeight() );
+ }
+ else
+ {
+ mbUseStencil = true;
+ mbUseScissor = false;
+ maContext.makeCurrent();
+ glViewport( 0, 0, GetWidth(), GetHeight() );
- glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
- glStencilMask( 0xFF );
- glStencilFunc( GL_NEVER, 1, 0xFF );
- glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP );
+ glEnable( GL_STENCIL_TEST );
+ glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
+ glStencilMask( 0xFF );
+ glStencilFunc( GL_NEVER, 1, 0xFF );
+ glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP );
- glClear( GL_STENCIL_BUFFER_BIT );
- BeginSolid( SALCOLOR_NONE );
- DrawPolyPolygon( aClip );
- EndSolid();
+ glClear( GL_STENCIL_BUFFER_BIT );
+ BeginSolid( SALCOLOR_NONE );
+ DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
+ EndSolid();
- glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
- glStencilMask( 0x00 );
- glStencilFunc( GL_EQUAL, 1, 0xFF );*/
+ glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
+ glStencilMask( 0x00 );
+ glStencilFunc( GL_EQUAL, 1, 0xFF );
+ glDisable( GL_STENCIL_TEST );
+ }
return true;
}
@@ -147,10 +175,8 @@ bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
void OpenGLSalGraphicsImpl::ResetClipRegion()
{
SAL_INFO( "vcl.opengl", "::ResetClipRegion" );
- maContext.makeCurrent();
- glDisable(GL_STENCIL_TEST);
-
- CHECK_GL_ERROR();
+ mbUseScissor = false;
+ mbUseStencil = false;
}
// get the depth of the device
diff --git a/vcl/source/gdi/region.cxx b/vcl/source/gdi/region.cxx
index 3f56d0ef6891..6fb78b08b145 100644
--- a/vcl/source/gdi/region.cxx
+++ b/vcl/source/gdi/region.cxx
@@ -1434,6 +1434,23 @@ bool vcl::Region::IsOver( const Rectangle& rRect ) const
return !aRegion.IsEmpty();
}
+bool vcl::Region::IsRectangle() const
+{
+ if( IsEmpty() || IsNull() )
+ return false;
+
+ if( getB2DPolyPolygon() )
+ return basegfx::tools::isRectangle( *getB2DPolyPolygon() );
+
+ if( getPolyPolygon() )
+ return getPolyPolygon()->IsRect();
+
+ if( getRegionBand() )
+ return (getRegionBand()->getRectangleCount() == 1);
+
+ return false;
+}
+
void vcl::Region::SetNull()
{
// reset all content