summaryrefslogtreecommitdiff
path: root/vcl/opengl
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-04-28 14:55:45 +0900
committerTomaž Vajngerl <quikee@gmail.com>2016-04-30 03:06:49 +0000
commitba0a5708803d899de4c40cfe2c1697ae83b4827a (patch)
tree2001952d455e7a0258a49a858f4a1f5339053f1a /vcl/opengl
parent02a8589553b5ce0e57a7ee9e66327376125b4378 (diff)
opengl: track state of active and bound textures in context
Add TextureState which is responsible to track the state of texture binding (and unbinding) and changing the current active texture unit. This is necessary because all GL calls reset the internal state without checking what the current state actually is and this can accumulate to a large amount of overhead. We also unbound the textures (glBindTexture with 0 as ID) after every operation which is also a major unneeded overhead which is fixed by this commit. Change-Id: I770a6a744c0c41850c576b928f027375962088aa Reviewed-on: https://gerrit.libreoffice.org/24503 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl/opengl')
-rw-r--r--vcl/opengl/program.cxx26
-rw-r--r--vcl/opengl/texture.cxx60
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx5
3 files changed, 44 insertions, 47 deletions
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index c8b0583f56a2..c4f5c0e5ec02 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -7,9 +7,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#include <opengl/program.hxx>
+#include "opengl/program.hxx"
+#include "opengl/RenderState.hxx"
#include <vcl/opengl/OpenGLHelper.hxx>
+#include <vcl/opengl/OpenGLContext.hxx>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
@@ -62,19 +64,11 @@ bool OpenGLProgram::Use()
bool OpenGLProgram::Clean()
{
// unbind all textures
- if( !maTextures.empty() )
+ for (OpenGLTexture& rTexture : maTextures)
{
- int nIndex( maTextures.size() - 1 );
- TextureList::reverse_iterator it( maTextures.rbegin() );
- while( it != maTextures.rend() )
- {
- glActiveTexture( GL_TEXTURE0 + nIndex-- );
- CHECK_GL_ERROR();
- it->Unbind();
- ++it;
- }
- maTextures.clear();
+ rTexture.Unbind();
}
+ maTextures.clear();
// disable any enabled vertex attrib array
if( mnEnabledAttribs )
@@ -252,10 +246,12 @@ void OpenGLProgram::SetTexture( const OString& rName, OpenGLTexture& rTexture )
glUniform1i( nUniform, nIndex );
CHECK_GL_ERROR();
- glActiveTexture( GL_TEXTURE0 + nIndex );
- CHECK_GL_ERROR();
+
+ std::unique_ptr<RenderState>& rState = OpenGLContext::getVCLContext()->state();
+ rState->texture().active(nIndex);
+
rTexture.Bind();
- maTextures.push_back( rTexture );
+ maTextures.push_back(rTexture);
}
void OpenGLProgram::SetTransform(
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 232b2cd002f0..e9fca75befa1 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -29,6 +29,8 @@
#include "opengl/framebuffer.hxx"
#include "opengl/texture.hxx"
#include "opengl/zone.hxx"
+#include "opengl/RenderState.hxx"
+
namespace
{
@@ -47,10 +49,11 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate )
{
OpenGLVCLContextZone aContextZone;
- glGenTextures( 1, &mnTexture );
- CHECK_GL_ERROR();
- glBindTexture( GL_TEXTURE_2D, mnTexture );
- CHECK_GL_ERROR();
+ auto& rState = OpenGLContext::getVCLContext()->state();
+ rState->texture().generate(mnTexture);
+ rState->texture().active(0);
+ rState->texture().bind(mnTexture);
+
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
@@ -64,8 +67,6 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, bool bAllocate )
glTexImage2D( GL_TEXTURE_2D, 0, constInternalFormat, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
CHECK_GL_ERROR();
}
- glBindTexture( GL_TEXTURE_2D, 0 );
- CHECK_GL_ERROR();
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " allocate" );
}
@@ -84,10 +85,11 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight )
// FIXME We need the window height here
// nY = GetHeight() - nHeight - nY;
- glGenTextures( 1, &mnTexture );
- CHECK_GL_ERROR();
- glBindTexture( GL_TEXTURE_2D, mnTexture );
- CHECK_GL_ERROR();
+ auto& rState = OpenGLContext::getVCLContext()->state();
+ rState->texture().generate(mnTexture);
+ rState->texture().active(0);
+ rState->texture().bind(mnTexture);
+
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
@@ -98,8 +100,6 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nX, int nY, int nWidth, int nHeight )
CHECK_GL_ERROR();
glCopyTexImage2D( GL_TEXTURE_2D, 0, constInternalFormat, nX, nY, nWidth, nHeight, 0 );
CHECK_GL_ERROR();
- glBindTexture( GL_TEXTURE_2D, 0 );
- CHECK_GL_ERROR();
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " from x" << nX << ", y" << nY );
}
@@ -115,10 +115,11 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int
{
OpenGLVCLContextZone aContextZone;
- glGenTextures( 1, &mnTexture );
- CHECK_GL_ERROR();
- glBindTexture( GL_TEXTURE_2D, mnTexture );
- CHECK_GL_ERROR();
+ auto& rState = OpenGLContext::getVCLContext()->state();
+ rState->texture().generate(mnTexture);
+ rState->texture().active(0);
+ rState->texture().bind(mnTexture);
+
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
CHECK_GL_ERROR();
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
@@ -131,8 +132,6 @@ ImplOpenGLTexture::ImplOpenGLTexture( int nWidth, int nHeight, int nFormat, int
CHECK_GL_ERROR();
glTexImage2D( GL_TEXTURE_2D, 0, constInternalFormat, mnWidth, mnHeight, 0, nFormat, nType, pData );
CHECK_GL_ERROR();
- glBindTexture( GL_TEXTURE_2D, 0 );
- CHECK_GL_ERROR();
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " " << nWidth << "x" << nHeight << " from data" );
}
@@ -187,8 +186,8 @@ void ImplOpenGLTexture::Dispose()
glDeleteRenderbuffers( 1, &mnOptStencil );
mnOptStencil = 0;
}
- glDeleteTextures( 1, &mnTexture );
-
+ auto& rState = pContext->state();
+ rState->texture().unbindAndDelete(mnTexture);
mnTexture = 0;
}
else
@@ -203,14 +202,15 @@ bool ImplOpenGLTexture::InsertBuffer(int nX, int nY, int nWidth, int nHeight, in
{
if (!pData || mnTexture == 0)
return false;
- glBindTexture(GL_TEXTURE_2D, mnTexture);
- CHECK_GL_ERROR();
+
+ rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
+ xContext->state()->texture().active(0);
+ xContext->state()->texture().bind(mnTexture);
+
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
CHECK_GL_ERROR();
glTexSubImage2D(GL_TEXTURE_2D, 0, nX, mnHeight - nY - nHeight, nWidth, nHeight, nFormat, nType, pData);
CHECK_GL_ERROR();
- glBindTexture(GL_TEXTURE_2D, 0);
- CHECK_GL_ERROR();
VCL_GL_INFO( "OpenGLTexture " << mnTexture << " Insert buff. to " << nX << " " << nY
<< " size " << nWidth << "x" << nHeight << " from data" );
@@ -492,10 +492,10 @@ void OpenGLTexture::SetFilter( GLenum nFilter )
void OpenGLTexture::Bind()
{
- if( mpImpl )
+ if (mpImpl)
{
- glBindTexture( GL_TEXTURE_2D, mpImpl->mnTexture );
- CHECK_GL_ERROR();
+ std::unique_ptr<RenderState>& rState = OpenGLContext::getVCLContext()->state();
+ rState->texture().bind(mpImpl->mnTexture);
}
else
VCL_GL_INFO( "OpenGLTexture::Binding invalid texture" );
@@ -505,10 +505,10 @@ void OpenGLTexture::Bind()
void OpenGLTexture::Unbind()
{
- if( mpImpl )
+ if (mpImpl)
{
- glBindTexture( GL_TEXTURE_2D, 0 );
- CHECK_GL_ERROR();
+ std::unique_ptr<RenderState>& rState = OpenGLContext::getVCLContext()->state();
+ rState->texture().unbind(mpImpl->mnTexture);
}
}
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index fc49e2520e58..61dba9b78db3 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -22,6 +22,7 @@
#include <opengl/texture.hxx>
#include <opengl/x11/gdiimpl.hxx>
#include <opengl/x11/salvd.hxx>
+#include "opengl/RenderState.hxx"
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
@@ -144,8 +145,8 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask
rCombo.mpTexture.reset(new OpenGLTexture(pPixmap->GetWidth(), pPixmap->GetHeight(), false));
- glActiveTexture( GL_TEXTURE0 );
- CHECK_GL_ERROR();
+ mpContext->state()->texture().active(0);
+
rCombo.mpTexture->Bind();
glXBindTexImageEXT( pDisplay, pGlxPixmap, GLX_FRONT_LEFT_EXT, nullptr );
rCombo.mpTexture->Unbind();