[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - include/vcl vcl/inc vcl/opengl vcl/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Fri May 6 07:07:38 UTC 2016


 include/vcl/opengl/OpenGLContext.hxx |    8 +
 vcl/inc/opengl/RenderState.hxx       |  156 +++++++++++++++++++++++++++++++++++
 vcl/inc/opengl/TextureState.hxx      |   76 +++++++++++++++++
 vcl/opengl/gdiimpl.cxx               |   91 +++++++++-----------
 vcl/opengl/program.cxx               |   26 ++---
 vcl/opengl/salbmp.cxx                |   14 ++-
 vcl/opengl/scale.cxx                 |    3 
 vcl/opengl/texture.cxx               |   60 ++++++-------
 vcl/opengl/x11/gdiimpl.cxx           |    5 -
 vcl/source/opengl/OpenGLContext.cxx  |    8 +
 10 files changed, 348 insertions(+), 99 deletions(-)

New commits:
commit 75667b6c68e7c9c288c74623e4925a2de42f2d6f
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Apr 28 14:55:45 2016 +0900

    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 at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Reviewed-by: David Tardon <dtardon at redhat.com>

diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index a565f5b..c632ab5 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -62,6 +62,7 @@ class OpenGLProgram;
 class OpenGLTexture;
 class SalGraphicsImpl;
 class OpenGLTests;
+class RenderState;
 
 /// Holds the information of our new child window
 struct GLWindow
@@ -169,6 +170,11 @@ public:
     OpenGLProgram*      UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader, const OString& preamble = "" );
     void                UseNoProgram();
 
+    std::unique_ptr<RenderState>& state()
+    {
+        return mpRenderState;
+    }
+
     /// Is this GL context the current context ?
     bool isCurrent();
     /// release bound resources from the current context
@@ -260,6 +266,8 @@ private:
     std::set<SalGraphicsImpl*> maParents;
 #endif
 
+    std::unique_ptr<RenderState> mpRenderState;
+
 public:
     vcl::Region maClipRegion;
     int mnPainting;
diff --git a/vcl/inc/opengl/RenderState.hxx b/vcl/inc/opengl/RenderState.hxx
new file mode 100644
index 0000000..ac215a8
--- /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 0000000..945b3b4
--- /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 0c107da..d9640b9 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 340b10f..eafd0c6 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 18c2ce3..87fc542 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 d279229..3a42bdd 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 61b6514..9f5f9a2 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 fc49e25..61dba9b 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 a009476..1ac5f4d 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;
 }


More information about the Libreoffice-commits mailing list