[Libreoffice-commits] core.git: Branch 'private/mmeeks/opengl-backbuffer2' - vcl/inc vcl/opengl vcl/README.vars vcl/source
Michael Meeks
michael.meeks at collabora.com
Wed Dec 9 06:09:43 PST 2015
Rebased ref, commits from common ancestor:
commit f2a3a957110f19f3ddfea943d6afd167f8708292
Author: Michael Meeks <michael.meeks at collabora.com>
Date: Sat Dec 5 22:11:24 2015 +0000
vcl: bind stencil buffer for clipping vs. textures.
Fixes complex (ie. non glScissor) clipping when rendering to textures:
virtual-devices and/or (now) off-screen rendering.
Also cleanup and document debug variables.
Change-Id: Ia8289d02d4cb51161cdde8927ecc7b24c767db13
diff --git a/vcl/README.vars b/vcl/README.vars
index 4f62333..bf85485 100644
--- a/vcl/README.vars
+++ b/vcl/README.vars
@@ -21,6 +21,8 @@ EMF_PLUS_DISABLE - use EMF rendering and ignore EMF+ specifics
OpenGL
------
SAL_FORCEGL - force enable OpenGL
+SAL_GL_NO_SWAP - disable buffer swapping if set (should show nothing)
+SAL_GL_SLEEP_ON_SWAP - sleep for half a second on each swap-buffers.
SAL_WITHOUT_WIDGET_CACHE - disable LRU caching of native widget texutres
SAL_DISABLE_GLYPH_CACHING - don't render glyphs through OpenGL textures
SAL_DISABLE_GL_WATCHDOG - don't start the thread that watches for broken GL drivers
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index f67b334..e57aa9e 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -37,6 +37,8 @@ public:
int mnWidth;
int mnHeight;
GLenum mnFilter;
+ GLuint mnOptStencil;
+ bool mbHasOptStencil;
std::unique_ptr<std::vector<int>> mpSlotReferences;
int mnFreeSlots;
@@ -76,7 +78,8 @@ public:
}
bool InitializeSlots(int nSlotSize);
- int FindFreeSlot();
+ int FindFreeSlot();
+ GLuint AddStencil();
};
class VCL_DLLPUBLIC OpenGLTexture
@@ -110,6 +113,9 @@ public:
void Bind();
void Unbind();
void Read( GLenum nFormat, GLenum nType, sal_uInt8* pData );
+ GLuint AddStencil();
+ bool HasStencil() const;
+ GLuint StencilId() const;
void SaveToFile(const OUString& rFileName);
diff --git a/vcl/opengl/framebuffer.cxx b/vcl/opengl/framebuffer.cxx
index c009ccb..464662d 100644
--- a/vcl/opengl/framebuffer.cxx
+++ b/vcl/opengl/framebuffer.cxx
@@ -72,6 +72,16 @@ void OpenGLFramebuffer::AttachTexture( const OpenGLTexture& rTexture )
mnHeight = rTexture.GetHeight();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mnAttachedTexture, 0);
CHECK_GL_ERROR();
+
+ GLuint nStencil = rTexture.StencilId();
+ if( nStencil )
+ {
+ VCL_GL_INFO( "Attaching stencil " << nStencil << " to framebuffer " << (int)mnId );
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, nStencil );
+ CHECK_GL_ERROR();
+ }
+
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
CHECK_GL_ERROR();
if (status != GL_FRAMEBUFFER_COMPLETE)
@@ -87,6 +97,11 @@ void OpenGLFramebuffer::DetachTexture()
mnAttachedTexture = 0;
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 );
CHECK_GL_ERROR();
+
+ // FIXME: we could make this conditional on having a stencil ?
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, 0 );
+ CHECK_GL_ERROR();
}
}
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 3266dea..05994dd 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -277,6 +277,20 @@ void OpenGLSalGraphicsImpl::freeResources()
void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMask )
{
glEnable( GL_STENCIL_TEST );
+
+ VCL_GL_INFO( "Adding complex clip / stencil" );
+ GLuint nStencil = maOffscreenTex.StencilId();
+ if( nStencil == 0 )
+ {
+ nStencil = maOffscreenTex.AddStencil();
+ glFramebufferRenderbuffer(
+ GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, nStencil );
+ CHECK_GL_ERROR();
+ }
+ // else - we associated the stencil in
+ // AcquireFrameBuffer / AttachTexture
+
CHECK_GL_ERROR();
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
CHECK_GL_ERROR();
@@ -311,7 +325,7 @@ void OpenGLSalGraphicsImpl::ImplInitClipRegion()
if( maClipRegion != mpContext->maClipRegion )
{
mpContext->maClipRegion = maClipRegion;
- if( maClipRegion.IsRectangle() )
+ if( mbUseScissor )
{
Rectangle aRect( maClipRegion.GetBoundRect() );
glScissor( aRect.Left(), GetHeight() - aRect.Bottom() - 1, aRect.GetWidth() + 1, aRect.GetHeight() + 1 );
@@ -476,7 +490,11 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
if( bClearTexture )
{
glDrawBuffer( GL_COLOR_ATTACHMENT0 );
+#if OSL_DEBUG_LEVEL > 0 // lets have some red debugging background.
GLfloat clearColor[4] = { 1.0, 0, 0, 0 };
+#else
+ GLfloat clearColor[4] = { 1.0, 1.0, 1.0, 0 };
+#endif
glClearBufferfv( GL_COLOR, 0, clearColor );
// FIXME: use glClearTexImage if we have it ?
}
@@ -2056,19 +2074,15 @@ void OpenGLSalGraphicsImpl::doFlush()
pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0);
pProgram->SetVertices( &aVertices[0] );
- if (!getenv("NO_COPY"))
- glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+ glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
pProgram->Clean();
glBindTexture( GL_TEXTURE_2D, 0 );
- if (!getenv("NO_SWAP"))
- {
+ static bool bNoSwap = getenv("SAL_GL_NO_SWAP");
+ if (!bNoSwap)
mpWindowContext->swapBuffers();
- if (!getenv("NO_SLEEP"))
- usleep(500 * 1000);
- }
}
VCL_GL_INFO( "flushAndSwap - end." );
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index b540e96..bf4aa1d 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -35,6 +35,7 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate )
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
+ mnOptStencil( 0 ),
mnFreeSlots(-1)
{
glGenTextures( 1, &mnTexture );
@@ -67,6 +68,7 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight )
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
+ mnOptStencil( 0 ),
mnFreeSlots(-1)
{
// FIXME We need the window height here
@@ -99,6 +101,7 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int
mnWidth( nWidth ),
mnHeight( nHeight ),
mnFilter( GL_NEAREST ),
+ mnOptStencil( 0 ),
mnFreeSlots(-1)
{
if( !mnTexture )
@@ -126,6 +129,21 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " from data" );
}
+GLuint ImplOpenGLTexture::AddStencil()
+{
+ assert( mnOptStencil == 0 );
+
+ glGenRenderbuffers( 1, &mnOptStencil );
+ glBindRenderbuffer( GL_RENDERBUFFER, mnOptStencil );
+ CHECK_GL_ERROR();
+ VCL_GL_INFO( "Allocate stencil " << mnWidth << " x " << mnHeight );
+ glRenderbufferStorage( GL_RENDERBUFFER, GL_STENCIL_INDEX,
+ mnWidth, mnHeight );
+ CHECK_GL_ERROR();
+
+ return mnOptStencil;
+}
+
ImplOpenGLTexture::~ImplOpenGLTexture()
{
VCL_GL_INFO( "~OpenGLTexture " << mnTexture );
@@ -136,9 +154,11 @@ ImplOpenGLTexture::~ImplOpenGLTexture()
// Check we have been correctly un-bound from all framebuffers.
ImplSVData* pSVData = ImplGetSVData();
rtl::Reference<OpenGLContext> pContext = pSVData->maGDIData.mpLastContext;
- if (pContext.is())
+ if( pContext.is() )
pContext->UnbindTextureFromFramebuffers( mnTexture );
+ if( mnOptStencil != 0 )
+ glDeleteRenderbuffers( 1, &mnOptStencil );
glDeleteTextures( 1, &mnTexture );
}
}
@@ -279,6 +299,24 @@ int OpenGLTexture::GetHeight() const
return maRect.GetHeight();
}
+bool OpenGLTexture::HasStencil() const
+{
+ return mpImpl && mpImpl->mnOptStencil != 0;
+}
+
+GLuint OpenGLTexture::StencilId() const
+{
+ return mpImpl ? mpImpl->mnOptStencil : 0;
+}
+
+GLuint OpenGLTexture::AddStencil()
+{
+ if (mpImpl)
+ return mpImpl->AddStencil();
+ else
+ return 0;
+}
+
void OpenGLTexture::GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted ) const
{
VCL_GL_INFO( "Getting coord " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() );
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index fb50f90..ed1347d 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -18,6 +18,8 @@
#include <vcl/bmpacc.hxx>
#include <vcl/graph.hxx>
+#include <osl/thread.hxx>
+
#if defined(MACOSX)
#include <premac.h>
#include "OpenGLWrapper.hxx"
@@ -1486,6 +1488,14 @@ void OpenGLContext::swapBuffers()
#elif defined( UNX )
glXSwapBuffers(m_aGLWin.dpy, m_aGLWin.win);
#endif
+
+ static bool bSleep = getenv("SAL_GL_SLEEP_ON_SWAP");
+ if (bSleep)
+ {
+ // half a second.
+ TimeValue aSleep( 0, 500*1000*1000 );
+ osl::Thread::wait( aSleep );
+ }
}
void OpenGLContext::sync()
More information about the Libreoffice-commits
mailing list