summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-04-28 14:55:45 +0900
committerDavid Tardon <dtardon@redhat.com>2016-05-06 07:07:14 +0000
commit75667b6c68e7c9c288c74623e4925a2de42f2d6f (patch)
treeb4e03320982f51547f0ffad15133ce86badb4479 /vcl
parentd80e87a91f25f78239d36ab4a4550173e8d6184b (diff)
opengl: combined commits for state tracking
Includes commits: opengl: track state of active and bound textures in context ba0a5708803d899de4c40cfe2c1697ae83b4827a opengl: track the state of scissor test and the dimensions 51e953a3579fb91f30f7f0d6159b737684976959 opengl: track the state of stencil test b8f0e6452cc019744c44997c92831d94086b35b7 opengl: sync scissor and stencil state, generic capability state a57d048f88ba6cac3ce1550e2a8a143a8887eb05 opengl: track the state of glViewport 540fee2dc7553152914f7f1d8a41921e765087ef Change-Id: I770a6a744c0c41850c576b928f027375962088aa Reviewed-on: https://gerrit.libreoffice.org/24508 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Reviewed-by: David Tardon <dtardon@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/opengl/RenderState.hxx156
-rw-r--r--vcl/inc/opengl/TextureState.hxx76
-rw-r--r--vcl/opengl/gdiimpl.cxx91
-rw-r--r--vcl/opengl/program.cxx26
-rw-r--r--vcl/opengl/salbmp.cxx14
-rw-r--r--vcl/opengl/scale.cxx3
-rw-r--r--vcl/opengl/texture.cxx60
-rw-r--r--vcl/opengl/x11/gdiimpl.cxx5
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx8
9 files changed, 340 insertions, 99 deletions
diff --git a/vcl/inc/opengl/RenderState.hxx b/vcl/inc/opengl/RenderState.hxx
new file mode 100644
index 000000000000..ac215a8d97c1
--- /dev/null
+++ b/vcl/inc/opengl/RenderState.hxx
@@ -0,0 +1,156 @@
+/* -*- 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"
+
+template<GLenum ENUM_TYPE, typename TYPE>
+class GenericCapabilityState
+{
+protected:
+ bool mbTest;
+
+ bool readState()
+ {
+ return (glIsEnabled(ENUM_TYPE) == GL_TRUE);
+ };
+
+public:
+ void sync()
+ {
+ mbTest = readState();
+ }
+
+ void enable()
+ {
+ if (!mbTest)
+ {
+ glEnable(ENUM_TYPE);
+ CHECK_GL_ERROR();
+ mbTest = true;
+ }
+ else
+ {
+ VCL_GL_INFO(TYPE::className() << ": enable called but already set");
+ }
+#ifdef DBG_UTIL
+ checkState();
+#endif
+ }
+
+ void disable()
+ {
+ if (mbTest)
+ {
+ glDisable(ENUM_TYPE);
+ CHECK_GL_ERROR();
+ mbTest = false;
+ }
+ else
+ {
+ VCL_GL_INFO(TYPE::className() << ": disable called but already set");
+ }
+#ifdef DBG_UTIL
+ checkState();
+#endif
+ }
+
+#ifdef DBG_UTIL
+ void checkState()
+ {
+ bool bRealState = readState();
+ if (mbTest != bRealState)
+ {
+ VCL_GL_INFO(TYPE::className() << " mismatch! "
+ << "Expected: " << (mbTest ? "enabled" : "disabled")
+ << " but is: " << (bRealState ? "enabled" : "disabled"));
+ }
+ }
+#endif
+};
+
+class ScissorState : public GenericCapabilityState<GL_SCISSOR_TEST, ScissorState>
+{
+private:
+ int mX;
+ int mY;
+ int mWidth;
+ int mHeight;
+
+public:
+ static std::string className() { return std::string("ScissorState"); }
+
+ ScissorState()
+ : mX(0)
+ , mY(0)
+ , mWidth(0)
+ , mHeight(0)
+ {}
+
+ void set(int x, int y, int width, int height)
+ {
+ if (x != mX || y != mY || width != mWidth || height != mHeight)
+ {
+ glScissor(x, y, width, height);
+ CHECK_GL_ERROR();
+
+ mX = x;
+ mY = y;
+ mWidth = width;
+ mHeight = height;
+ }
+ }
+};
+
+class StencilState : public GenericCapabilityState<GL_STENCIL_TEST, StencilState>
+{
+public:
+ static std::string className() { return std::string("StencilState"); }
+};
+
+class RenderState
+{
+ TextureState maTexture;
+ ScissorState maScissor;
+ StencilState maStencil;
+
+ Rectangle maCurrentViewport;
+
+public:
+ RenderState()
+ {}
+
+ void viewport(Rectangle aViewPort)
+ {
+ if (aViewPort != maCurrentViewport)
+ {
+ glViewport(aViewPort.Left(), aViewPort.Top(), aViewPort.GetWidth(), aViewPort.GetHeight());
+ CHECK_GL_ERROR();
+ maCurrentViewport = aViewPort;
+ }
+ }
+
+ TextureState& texture() { return maTexture; }
+ ScissorState& scissor() { return maScissor; }
+ StencilState& stencil() { return maStencil; }
+
+ void sync()
+ {
+ VCL_GL_INFO("RenderState::sync");
+ maScissor.sync();
+ maStencil.sync();
+ }
+};
+
+#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/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 0c107da49abc..d9640b96381b 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -34,6 +34,7 @@
#include "svdata.hxx"
#include "opengl/zone.hxx"
#include "opengl/salbmp.hxx"
+#include "opengl/RenderState.hxx"
#include <vector>
@@ -208,8 +209,7 @@ void OpenGLSalGraphicsImpl::InitializePreDrawState(XOROption eOpt)
CheckOffscreenTexture();
CHECK_GL_ERROR();
- glViewport( 0, 0, GetWidth(), GetHeight() );
- CHECK_GL_ERROR();
+ mpContext->state()->viewport(Rectangle(Point(0, 0), Size(GetWidth(), GetHeight())));
ImplInitClipRegion();
CHECK_GL_ERROR();
@@ -231,16 +231,6 @@ void OpenGLSalGraphicsImpl::PostDraw()
CHECK_GL_ERROR();
}
- if( mbUseScissor )
- {
- glDisable( GL_SCISSOR_TEST );
- CHECK_GL_ERROR();
- }
- if( mbUseStencil )
- {
- glDisable( GL_STENCIL_TEST );
- CHECK_GL_ERROR();
- }
if( mpProgram )
{
mpProgram->Clean();
@@ -279,7 +269,8 @@ void OpenGLSalGraphicsImpl::freeResources()
void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMask )
{
- glEnable( GL_STENCIL_TEST );
+ mpContext->state()->scissor().disable();
+ mpContext->state()->stencil().enable();
VCL_GL_INFO( "Adding complex clip / stencil" );
GLuint nStencil = maOffscreenTex.StencilId();
@@ -318,39 +309,42 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMa
CHECK_GL_ERROR();
glStencilMask( 0x00 );
CHECK_GL_ERROR();
- glDisable( GL_STENCIL_TEST );
- CHECK_GL_ERROR();
+
+ mpContext->state()->stencil().disable();
}
void OpenGLSalGraphicsImpl::ImplInitClipRegion()
{
// make sure the context has the right clipping set
- if( maClipRegion != mpContext->maClipRegion )
+ if (maClipRegion != mpContext->maClipRegion)
{
mpContext->maClipRegion = maClipRegion;
- if( mbUseScissor )
+ if (mbUseStencil)
{
- Rectangle aRect( maClipRegion.GetBoundRect() );
- glScissor( aRect.Left(), GetHeight() - aRect.Bottom() - 1, aRect.GetWidth(), aRect.GetHeight() );
- CHECK_GL_ERROR();
- }
- else if( !maClipRegion.IsEmpty() )
- {
- ImplSetClipBit( maClipRegion, 0x01 );
+ ImplSetClipBit(maClipRegion, 0x01);
}
}
- if( mbUseScissor )
+ if (mbUseScissor)
{
- glEnable( GL_SCISSOR_TEST );
- CHECK_GL_ERROR();
+ Rectangle aRect(maClipRegion.GetBoundRect());
+ mpContext->state()->scissor().set(aRect.Left(), GetHeight() - aRect.Bottom() - 1, aRect.GetWidth(), aRect.GetHeight());
+ mpContext->state()->scissor().enable();
}
- if( mbUseStencil )
+ else
+ {
+ mpContext->state()->scissor().disable();
+ }
+
+ if (mbUseStencil)
{
glStencilFunc( GL_EQUAL, 1, 0x1 );
CHECK_GL_ERROR();
- glEnable( GL_STENCIL_TEST );
- CHECK_GL_ERROR();
+ mpContext->state()->stencil().enable();
+ }
+ else
+ {
+ mpContext->state()->stencil().disable();
}
}
@@ -375,9 +369,9 @@ bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
mbUseStencil = false;
mbUseScissor = false;
- if( maClipRegion.IsRectangle() )
+ if (maClipRegion.IsRectangle())
mbUseScissor = true;
- else if ( !maClipRegion.IsEmpty() )
+ else if (!maClipRegion.IsEmpty())
mbUseStencil = true;
return true;
@@ -501,6 +495,10 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
// TODO: lfrb: User GL_ARB_copy_image?
OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
+
+ mpContext->state()->scissor().disable();
+ mpContext->state()->stencil().disable();
+
mpFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
DrawTexture( maOffscreenTex, aPosAry );
maOffscreenTex = aNewTex;
@@ -1503,12 +1501,8 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
// The scissor area is set to the current window size in PreDraw,
// so if we do not disable the scissor test, the texture produced
// by the first downscaling is clipped to the current window size.
- glDisable(GL_SCISSOR_TEST);
- CHECK_GL_ERROR();
-
- // Maybe it can give problems too.
- glDisable(GL_STENCIL_TEST);
- CHECK_GL_ERROR();
+ mpContext->state()->scissor().disable();
+ mpContext->state()->stencil().disable();
// the square root of the whole inverted scale ratio
double ixscalesqrt = std::floor(std::sqrt(ixscale));
@@ -1529,15 +1523,10 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
// Re-enable scissor and stencil tests if needed.
if (mbUseScissor)
- {
- glEnable(GL_SCISSOR_TEST);
- CHECK_GL_ERROR();
- }
+ mpContext->state()->scissor().enable();
+
if (mbUseStencil)
- {
- glEnable(GL_STENCIL_TEST);
- CHECK_GL_ERROR();
- }
+ mpContext->state()->stencil().enable();
}
}
@@ -2508,6 +2497,9 @@ void OpenGLSalGraphicsImpl::doFlush()
{
FlushDeferredDrawing();
+ mpContext->state()->scissor().disable();
+ mpContext->state()->stencil().disable();
+
if( IsOffscreen() )
return;
@@ -2545,11 +2537,14 @@ void OpenGLSalGraphicsImpl::doFlush()
VCL_GL_INFO( "flushAndSwap - acquire default framebuffer" );
+ mpWindowContext->state()->sync();
+
mpWindowContext->AcquireDefaultFramebuffer();
CHECK_GL_ERROR();
- glViewport( 0, 0, GetWidth(), GetHeight() );
- CHECK_GL_ERROR();
+ mpWindowContext->state()->viewport(Rectangle(Point(0, 0), Size(GetWidth(), GetHeight())));
+ mpWindowContext->state()->scissor().disable();
+ mpWindowContext->state()->stencil().disable();
#if OSL_DEBUG_LEVEL > 0 // random background glClear
glClearColor((float)rand()/RAND_MAX, (float)rand()/RAND_MAX,
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index 340b10f6bb8f..eafd0c6ff70b 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/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 18c2ce3e2f6a..87fc54225020 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -33,7 +33,7 @@
#include "opengl/zone.hxx"
#include "opengl/program.hxx"
#include "opengl/salbmp.hxx"
-
+#include "opengl/RenderState.hxx"
#include "opengl/FixedTextureAtlas.hxx"
#if OSL_DEBUG_LEVEL > 0
@@ -537,6 +537,10 @@ bool OpenGLSalBitmap::ReadTexture()
OpenGLVCLContextZone aContextZone;
+ rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
+ xContext->state()->scissor().disable();
+ xContext->state()->stencil().disable();
+
if (mnBits == 8 || mnBits == 16 || mnBits == 24 || mnBits == 32)
{
determineTextureFormat(mnBits, nFormat, nType);
@@ -613,6 +617,8 @@ bool OpenGLSalBitmap::calcChecksumGL(OpenGLTexture& rInputTexture, ChecksumType&
OUString FragShader("areaHashCRC64TFragmentShader");
rtl::Reference< OpenGLContext > xContext = OpenGLContext::getVCLContext();
+ xContext->state()->scissor().disable();
+ xContext->state()->stencil().disable();
static vcl::DeleteOnDeinit<OpenGLTexture> gCRCTableTexture(
new OpenGLTexture(512, 1, GL_RGBA, GL_UNSIGNED_BYTE,
@@ -880,7 +886,9 @@ bool OpenGLSalBitmap::Replace( const Color& rSearchColor, const Color& rReplaceC
VCL_GL_INFO("::Replace");
OpenGLZone aZone;
- rtl::Reference< OpenGLContext > xContext = OpenGLContext::getVCLContext();
+ rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
+ xContext->state()->scissor().disable();
+ xContext->state()->stencil().disable();
OpenGLFramebuffer* pFramebuffer;
OpenGLProgram* pProgram;
@@ -919,6 +927,8 @@ bool OpenGLSalBitmap::ConvertToGreyscale()
OpenGLZone aZone;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
+ xContext->state()->scissor().disable();
+ xContext->state()->stencil().disable();
OpenGLFramebuffer* pFramebuffer;
OpenGLProgram* pProgram;
diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
index d2792295b0b8..3a42bdddb684 100644
--- a/vcl/opengl/scale.cxx
+++ b/vcl/opengl/scale.cxx
@@ -27,6 +27,7 @@
#include "opengl/salbmp.hxx"
#include "opengl/program.hxx"
#include "opengl/texture.hxx"
+#include "opengl/RenderState.hxx"
#include <ResampleKernel.hxx>
@@ -330,6 +331,8 @@ bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, B
maUserBuffer.reset();
OpenGLVCLContextZone aContextZone;
rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
+ xContext->state()->scissor().disable();
+ xContext->state()->stencil().disable();
if (rScaleX <= 1 && rScaleY <= 1)
{
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index 61b65140b8e7..9f5f9a2965a3 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
{
@@ -48,10 +50,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 );
@@ -65,8 +68,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" );
}
@@ -86,10 +87,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 );
@@ -100,8 +102,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 );
}
@@ -118,10 +118,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 );
@@ -134,8 +135,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" );
@@ -507,10 +507,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" );
@@ -520,10 +520,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 a00947649aaf..1ac5f4d55918 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -40,6 +40,8 @@
#include <opengl/texture.hxx>
#include <opengl/zone.hxx>
+#include "opengl/RenderState.hxx"
+
using namespace com::sun::star;
#define MAX_FRAMEBUFFER_COUNT 30
@@ -73,6 +75,7 @@ OpenGLContext::OpenGLContext():
mpFirstFramebuffer(nullptr),
mpLastFramebuffer(nullptr),
mpCurrentProgram(nullptr),
+ mpRenderState(new RenderState),
mnPainting(0),
mpPrevContext(nullptr),
mpNextContext(nullptr)
@@ -1225,6 +1228,7 @@ void OpenGLContext::reset()
// reset the clip region
maClipRegion.SetEmpty();
+ mpRenderState.reset(new RenderState);
// destroy all framebuffers
if( mpLastFramebuffer )
@@ -1679,8 +1683,8 @@ OpenGLFramebuffer* OpenGLContext::AcquireFramebuffer( const OpenGLTexture& rText
assert( pFramebuffer );
BindFramebuffer( pFramebuffer );
pFramebuffer->AttachTexture( rTexture );
- glViewport( 0, 0, rTexture.GetWidth(), rTexture.GetHeight() );
- CHECK_GL_ERROR();
+
+ state()->viewport(Rectangle(Point(), Size(rTexture.GetWidth(), rTexture.GetHeight())));
return pFramebuffer;
}