summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/opengl/RenderState.hxx29
-rw-r--r--vcl/inc/opengl/TextureState.hxx76
-rw-r--r--vcl/opengl/program.cxx26
-rw-r--r--vcl/opengl/texture.cxx60
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx5
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx3
6 files changed, 152 insertions, 47 deletions
diff --git a/vcl/inc/opengl/RenderState.hxx b/vcl/inc/opengl/RenderState.hxx
new file mode 100644
index 000000000000..a184f2ebe41b
--- /dev/null
+++ b/vcl/inc/opengl/RenderState.hxx
@@ -0,0 +1,29 @@
+/* -*- 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_RENDER_STATE_H
+#define INCLUDED_VCL_INC_OPENGL_RENDER_STATE_H
+
+#include "opengl/TextureState.hxx"
+
+class RenderState
+{
+ TextureState maTexture;
+
+public:
+ RenderState()
+ {}
+
+ TextureState& texture() { return maTexture; }
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_RENDER_STATE_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/TextureState.hxx b/vcl/inc/opengl/TextureState.hxx
new file mode 100644
index 000000000000..945b3b4a95d3
--- /dev/null
+++ b/vcl/inc/opengl/TextureState.hxx
@@ -0,0 +1,76 @@
+/* -*- 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_TEXTURE_STATE_H
+#define INCLUDED_VCL_INC_OPENGL_TEXTURE_STATE_H
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+class TextureState
+{
+private:
+ GLuint mnCurrentTextureUnit;
+ std::vector<GLuint> maBoundTextures;
+
+public:
+ TextureState()
+ : mnCurrentTextureUnit(0)
+ , maBoundTextures(4, 0)
+ {}
+
+ void generate(GLuint& nTexture)
+ {
+ glGenTextures(1, &nTexture);
+ CHECK_GL_ERROR();
+ }
+
+ void active(GLuint nTextureUnit)
+ {
+ if (mnCurrentTextureUnit != nTextureUnit)
+ {
+ glActiveTexture(GL_TEXTURE0 + nTextureUnit);
+ CHECK_GL_ERROR();
+ mnCurrentTextureUnit = nTextureUnit;
+ }
+
+ }
+
+ void bind(GLuint nTexture)
+ {
+ if (maBoundTextures[mnCurrentTextureUnit] != nTexture)
+ {
+ glBindTexture(GL_TEXTURE_2D, nTexture);
+ CHECK_GL_ERROR();
+ maBoundTextures[mnCurrentTextureUnit] = nTexture;
+ }
+ }
+
+ void unbindAndDelete(GLuint nTexture)
+ {
+ unbind(nTexture);
+ glDeleteTextures(1, &nTexture);
+ }
+
+ void unbind(GLuint nTexture)
+ {
+ for (size_t i = 0; i < maBoundTextures.size(); i++)
+ {
+ if (nTexture == maBoundTextures[i])
+ maBoundTextures[i] = 0;
+ }
+ }
+
+};
+
+
+
+#endif // INCLUDED_VCL_INC_OPENGL_TEXTURE_STATE_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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();
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 2b1e6bead8cd..b5881fe18c90 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -41,6 +41,8 @@
#include <opengl/texture.hxx>
#include <opengl/zone.hxx>
+#include "opengl/RenderState.hxx"
+
using namespace com::sun::star;
#define MAX_FRAMEBUFFER_COUNT 30
@@ -74,6 +76,7 @@ OpenGLContext::OpenGLContext():
mpFirstFramebuffer(nullptr),
mpLastFramebuffer(nullptr),
mpCurrentProgram(nullptr),
+ mpRenderState(new RenderState),
mnPainting(0),
mpPrevContext(nullptr),
mpNextContext(nullptr)