[Libreoffice-commits] core.git: vcl/inc vcl/opengl vcl/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Sat Apr 30 03:08:33 UTC 2016


 vcl/inc/opengl/RenderState.hxx      |  122 +++++++++++++++++++++---------------
 vcl/opengl/gdiimpl.cxx              |   12 ++-
 vcl/source/opengl/OpenGLContext.cxx |    1 
 3 files changed, 80 insertions(+), 55 deletions(-)

New commits:
commit a57d048f88ba6cac3ce1550e2a8a143a8887eb05
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Apr 29 17:07:11 2016 +0900

    opengl: sync scissor and stencil state, generic capability state
    
    Scissor and stencil test needed to be disabled in flush() (which
    means every postDraw call) because sometimes the state became out
    of sync with the current state. This commit adds sync() function
    which synchronises the actual OpenGL state and adds debugging
    mechanisms to warn when the state becomes out of sync (so we can
    inspect the exact moment in apitrace).
    
    Added a GenericCapabilityState for GL capabilities like
    GL_SCISSORS_TEST, GL_STENCIL_TEST, GL_BLEND,... and refactored
    existing ScissorState and StencilState to inherit from it.
    
    Change-Id: Ifc159108a5ce850c78a89b1f5b8d12ecdd84f459
    Reviewed-on: https://gerrit.libreoffice.org/24506
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/vcl/inc/opengl/RenderState.hxx b/vcl/inc/opengl/RenderState.hxx
index b1b0b18..eeac1a50 100644
--- a/vcl/inc/opengl/RenderState.hxx
+++ b/vcl/inc/opengl/RenderState.hxx
@@ -13,95 +13,110 @@
 
 #include "opengl/TextureState.hxx"
 
-class ScissorState
+template<GLenum ENUM_TYPE, typename TYPE>
+class GenericCapabilityState
 {
+protected:
     bool mbTest;
-    int mX;
-    int mY;
-    int mWidth;
-    int mHeight;
 
-public:
-
-    ScissorState()
-        : mbTest(false)
-        , mX(0)
-        , mY(0)
-        , mWidth(0)
-        , mHeight(0)
+    bool readState()
     {
-        glDisable(GL_SCISSOR_TEST);
-        CHECK_GL_ERROR();
-    }
+        return (glIsEnabled(ENUM_TYPE) == GL_TRUE);
+    };
 
-    void set(int x, int y, int width, int height)
+public:
+    void sync()
     {
-        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;
-        }
+        mbTest = readState();
     }
 
     void enable()
     {
         if (!mbTest)
         {
-            glEnable(GL_SCISSOR_TEST);
+            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(GL_SCISSOR_TEST);
+            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 StencilState
+class ScissorState : public GenericCapabilityState<GL_SCISSOR_TEST, ScissorState>
 {
-    bool mbTest;
+private:
+    int mX;
+    int mY;
+    int mWidth;
+    int mHeight;
+
 public:
+    static std::string className() { return std::string("ScissorState"); }
 
-    StencilState()
-        : mbTest(false)
-    {
-        glDisable(GL_STENCIL_TEST);
-        CHECK_GL_ERROR();
-    }
+    ScissorState()
+        : mX(0)
+        , mY(0)
+        , mWidth(0)
+        , mHeight(0)
+    {}
 
-    void enable()
+    void set(int x, int y, int width, int height)
     {
-        if (!mbTest)
+        if (x != mX || y != mY || width != mWidth || height != mHeight)
         {
-            glEnable(GL_STENCIL_TEST);
+            glScissor(x, y, width, height);
             CHECK_GL_ERROR();
-            mbTest = true;
-        }
-    }
 
-    void disable()
-    {
-        if (mbTest)
-        {
-            glDisable(GL_STENCIL_TEST);
-            CHECK_GL_ERROR();
-            mbTest = false;
+            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;
@@ -115,6 +130,13 @@ public:
     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
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 70b2d65..f98f5d2 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -265,8 +265,6 @@ void OpenGLSalGraphicsImpl::freeResources()
         VCL_GL_INFO( "freeResources" );
         mpContext->makeCurrent();
         FlushDeferredDrawing();
-        mpContext->state()->scissor().disable();
-        mpContext->state()->stencil().disable();
         mpContext->ReleaseFramebuffer( maOffscreenTex );
     }
     ReleaseContext();
@@ -274,6 +272,7 @@ void OpenGLSalGraphicsImpl::freeResources()
 
 void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMask )
 {
+    mpContext->state()->scissor().disable();
     mpContext->state()->stencil().enable();
 
     VCL_GL_INFO( "Adding complex clip / stencil" );
@@ -499,6 +498,10 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
 
         // TODO: lfrb: User GL_ARB_copy_image?
         OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
+
+        mpContext->state()->scissor().disable();
+        mpContext->state()->stencil().disable();
+
         mpContext->AcquireFramebuffer( aNewTex );
         DrawTexture( maOffscreenTex, aPosAry );
         maOffscreenTex = aNewTex;
@@ -2498,9 +2501,6 @@ void OpenGLSalGraphicsImpl::flush()
 {
     FlushDeferredDrawing();
 
-    mpContext->state()->scissor().disable();
-    mpContext->state()->stencil().disable();
-
     if( IsOffscreen() )
         return;
 
@@ -2557,6 +2557,8 @@ void OpenGLSalGraphicsImpl::doFlush()
 
     VCL_GL_INFO( "flushAndSwap - acquire default framebuffer" );
 
+    mpWindowContext->state()->sync();
+
     mpWindowContext->AcquireDefaultFramebuffer();
     CHECK_GL_ERROR();
 
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index b5881fe..5b441db 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -1226,6 +1226,7 @@ void OpenGLContext::reset()
 
     // reset the clip region
     maClipRegion.SetEmpty();
+    mpRenderState.reset(new RenderState);
 
     // destroy all framebuffers
     if( mpLastFramebuffer )


More information about the Libreoffice-commits mailing list