[Libreoffice-commits] core.git: Branch 'feature/fixes21' - vcl/inc vcl/opengl vcl/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Mon May 16 03:29:20 UTC 2016


 vcl/inc/opengl/RenderState.hxx      |   27 ++++++++
 vcl/inc/opengl/program.hxx          |    5 +
 vcl/opengl/gdiimpl.cxx              |  116 +++++++++++++++---------------------
 vcl/opengl/program.cxx              |   45 ++++++++-----
 vcl/source/opengl/OpenGLContext.cxx |    6 +
 5 files changed, 115 insertions(+), 84 deletions(-)

New commits:
commit b629300695bcb148d2ff293875cb71089d19532a
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu May 12 13:37:11 2016 +0900

    opengl: track the state of blend, DrawArrays on OpenGLProgram
    
    This adds tracking of GL_BLEND and glBlendFunc which are usually
    set when setting up the current draw call on OpenGLProgram with
    SetBlendFunc method.
    
    Until now the final draw call (glDrawArrays) was called outside
    of OpenGLProgram. This is a problem because we need to know if
    we did call SetBlendFunc or not between when we used or reused
    the current program. So we added DrawArrays to OpenGLProgram and
    refactored all draw calls in OpenGLSalGraphicsImpl to use this.
    
    From now on glDrawArrays should not be called directly but always
    through OpenGLProgram.
    
    Change-Id: I530b4b948af8a962669a3751e1a95ff3986ffec9

diff --git a/vcl/inc/opengl/RenderState.hxx b/vcl/inc/opengl/RenderState.hxx
index ac215a8..2930ff1 100644
--- a/vcl/inc/opengl/RenderState.hxx
+++ b/vcl/inc/opengl/RenderState.hxx
@@ -117,11 +117,36 @@ public:
     static std::string className() { return std::string("StencilState"); }
 };
 
+class BlendState : public GenericCapabilityState<GL_BLEND, BlendState>
+{
+    GLenum mnSourceMode;
+    GLenum mnDestinationMode;
+public:
+    BlendState()
+        : mnSourceMode(GL_ZERO)
+        , mnDestinationMode(GL_ZERO)
+    {}
+
+    static std::string className() { return std::string("BlendState"); }
+
+    void func(GLenum nSource, GLenum nDestination)
+    {
+        if (mnSourceMode != nSource || mnDestinationMode != nDestination)
+        {
+            glBlendFunc(nSource, nDestination);
+            CHECK_GL_ERROR();
+            mnSourceMode = nSource;
+            mnDestinationMode = nDestination;
+        }
+    }
+};
+
 class RenderState
 {
     TextureState maTexture;
     ScissorState maScissor;
     StencilState maStencil;
+    BlendState   maBlend;
 
     Rectangle maCurrentViewport;
 
@@ -142,12 +167,14 @@ public:
     TextureState& texture() { return maTexture; }
     ScissorState& scissor() { return maScissor; }
     StencilState& stencil() { return maStencil; }
+    BlendState&   blend()   { return maBlend; }
 
     void sync()
     {
         VCL_GL_INFO("RenderState::sync");
         maScissor.sync();
         maStencil.sync();
+        maBlend.sync();
     }
 };
 
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
index 780cba7..5944c72 100644
--- a/vcl/inc/opengl/program.hxx
+++ b/vcl/inc/opengl/program.hxx
@@ -51,9 +51,12 @@ public:
     OpenGLProgram();
     ~OpenGLProgram();
 
+    GLuint Id() { return mnId; }
+
     bool Load( const OUString& rVertexShader, const OUString& rFragmentShader,
                const rtl::OString& preamble = "", const rtl::OString& rDigest = "" );
     bool Use();
+    void Reuse();
     bool Clean();
 
     void SetVertices( const GLvoid* pData );
@@ -81,6 +84,8 @@ public:
 
     bool DrawTexture( const OpenGLTexture& rTexture );
 
+    void DrawArrays(GLenum GLenum, std::vector<GLfloat>& aVertices);
+
 protected:
     void SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData, GLint nSize = 2 );
     GLuint GetUniformLocation( const OString& rName );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index c6139e8..424f4be 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -626,14 +626,12 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
 {
     OpenGLZone aZone;
 
-    GLfloat pPoint[2];
-
-    pPoint[0] = GLfloat(nX);
-    pPoint[1] = GLfloat(nY);
+    std::vector<GLfloat> pPoint {
+        GLfloat(nX), GLfloat(nY)
+    };
 
     ApplyProgramMatrices(0.5f);
-    mpProgram->SetVertices( pPoint );
-    glDrawArrays( GL_POINTS, 0, 1 );
+    mpProgram->DrawArrays(GL_POINTS, pPoint);
     CHECK_GL_ERROR();
 }
 
@@ -641,16 +639,13 @@ void OpenGLSalGraphicsImpl::DrawLine( double nX1, double nY1, double nX2, double
 {
     OpenGLZone aZone;
 
-    GLfloat pPoints[4];
-
-    pPoints[0] = GLfloat(nX1);
-    pPoints[1] = GLfloat(nY1);
-    pPoints[2] = GLfloat(nX2);
-    pPoints[3] = GLfloat(nY2);
+    std::vector<GLfloat> pPoint {
+        GLfloat(nX1), GLfloat(nY1),
+        GLfloat(nX2), GLfloat(nY2)
+    };
 
     ApplyProgramMatrices(0.5f);
-    mpProgram->SetVertices( pPoints );
-    glDrawArrays( GL_LINES, 0, 2 );
+    mpProgram->DrawArrays(GL_LINES, pPoint);
     CHECK_GL_ERROR();
 }
 
@@ -722,8 +717,7 @@ void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2,
 
     ApplyProgramMatrices(0.0f);
     mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
-    mpProgram->SetVertices(aVertices.data());
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, aVertices.size() / 2);
+    mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices);
 
     CHECK_GL_ERROR();
 }
@@ -749,8 +743,7 @@ void OpenGLSalGraphicsImpl::DrawLineSegment(float x1, float y1, float x2, float
 
     ApplyProgramMatrices(0.0f);
     mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
-    mpProgram->SetVertices(aPoints.data());
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, aPoints.size() / 2);
+    mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aPoints);
 
     CHECK_GL_ERROR();
 }
@@ -944,8 +937,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
 
         ApplyProgramMatrices(0.0f);
         mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
-        mpProgram->SetVertices(aVertices.data());
-        glDrawArrays(GL_TRIANGLE_STRIP, 0, aVertices.size() / 2);
+        mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices);
 
         CHECK_GL_ERROR();
     }
@@ -1109,7 +1101,7 @@ void OpenGLSalGraphicsImpl::ImplDrawLineAA( double nX1, double nY1, double nX2,
         tx = ty = 0;
     }
 
-    GLfloat vertices[]=
+    std::vector<GLfloat> vertices
     {
         GLfloat(x1-tx-Rx), GLfloat(y1-ty-Ry), //fading edge1
         GLfloat(x2-tx-Rx), GLfloat(y2-ty-Ry),
@@ -1124,8 +1116,7 @@ void OpenGLSalGraphicsImpl::ImplDrawLineAA( double nX1, double nY1, double nX2,
     ApplyProgramMatrices(0.0f);
     GLfloat aTexCoord[16] = { 0, 0, 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 0, 7, 0 };
     mpProgram->SetTextureCoord( aTexCoord );
-    mpProgram->SetVertices( vertices );
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
+    mpProgram->DrawArrays(GL_TRIANGLE_STRIP, vertices);
     CHECK_GL_ERROR();
 }
 
@@ -1160,8 +1151,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
     }
 
     ApplyProgramMatrices();
-    mpProgram->SetVertices( &aVertices[0] );
-    glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+    mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
     CHECK_GL_ERROR();
 
     if( !blockAA && mrParent.getAntiAliasB2DDraw())
@@ -1204,8 +1194,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const tools::Polygon& rPolygon, b
     }
 
     ApplyProgramMatrices();
-    mpProgram->SetVertices( &aVertices[0] );
-    glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+    mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
     CHECK_GL_ERROR();
 
     if( !blockAA && mrParent.getAntiAliasB2DDraw())
@@ -1255,8 +1244,7 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi
     }
 
     ApplyProgramMatrices();
-    mpProgram->SetVertices( &aVertices[0] );
-    glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+    mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
     CHECK_GL_ERROR();
 
     if( !blockAA && mrParent.getAntiAliasB2DDraw())
@@ -1369,8 +1357,7 @@ void OpenGLSalGraphicsImpl::DrawRegionBand( const RegionBand& rRegion )
 #undef ADD_VERTICE
 
     ApplyProgramMatrices();
-    mpProgram->SetVertices( &aVertices[0] );
-    glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
+    mpProgram->DrawArrays(GL_TRIANGLES, aVertices);
     CHECK_GL_ERROR();
 }
 
@@ -1449,9 +1436,13 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
 {
     OpenGLZone aZone;
 
-    GLfloat aVertices[8] = {
-        0, (float) rTexture.GetHeight(), 0, 0,
-        (float) rTexture.GetWidth(), 0, (float) rTexture.GetWidth(), (float) rTexture.GetHeight() };
+    std::vector<GLfloat> aVertices = {
+        0, GLfloat(rTexture.GetHeight()),
+        0, 0,
+        GLfloat(rTexture.GetWidth()), 0,
+        GLfloat(rTexture.GetWidth()), GLfloat(rTexture.GetHeight())
+    };
+
     GLfloat aTexCoord[8];
 
     const long nDestWidth = basegfx::fround(basegfx::B2DVector(rX - rNull).getLength());
@@ -1587,8 +1578,7 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
     mpProgram->SetTexture("sampler", aInTexture);
     aInTexture.SetFilter(GL_LINEAR);
     mpProgram->SetTextureCoord( aTexCoord );
-    mpProgram->SetVertices( aVertices );
-    glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+    mpProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
 
     CHECK_GL_ERROR();
     mpProgram->Clean();
@@ -1729,8 +1719,7 @@ void OpenGLSalGraphicsImpl::FlushDeferredDrawing()
             TextureDrawParameters& rParameters = rColorTwoRectPair.second;
             ApplyProgramMatrices();
             mpProgram->SetTextureCoord(rParameters.maTextureCoords.data());
-            mpProgram->SetVertices(rParameters.maVertices.data());
-            glDrawArrays(GL_TRIANGLES, 0, rParameters.getNumberOfVertices());
+            mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
         }
     }
 #endif
@@ -1750,8 +1739,7 @@ void OpenGLSalGraphicsImpl::FlushDeferredDrawing()
             TextureDrawParameters& rParameters = rColorTwoRectPair.second;
             ApplyProgramMatrices();
             mpProgram->SetTextureCoord(rParameters.maTextureCoords.data());
-            mpProgram->SetVertices(rParameters.maVertices.data());
-            glDrawArrays(GL_TRIANGLES, 0, rParameters.getNumberOfVertices());
+            mpProgram->DrawArrays(GL_TRIANGLES, rParameters.maVertices);
         }
     }
     mpProgram->Clean();
@@ -1919,20 +1907,15 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
         GLfloat fX2(nX + nWidth - 1);
         GLfloat fY2(nY + nHeight - 1);
 
-        GLfloat pPoints[8];
-
-        pPoints[0] = fX1;
-        pPoints[1] = fY1;
-        pPoints[2] = fX2;
-        pPoints[3] = fY1;
-        pPoints[4] = fX2;
-        pPoints[5] = fY2;
-        pPoints[6] = fX1;
-        pPoints[7] = fY2;
+        std::vector<GLfloat> pPoints {
+            fX1, fY1,
+            fX2, fY1,
+            fX2, fY2,
+            fX1, fY2
+        };
 
         ApplyProgramMatrices(0.5f);
-        mpProgram->SetVertices(pPoints);
-        glDrawArrays(GL_LINE_LOOP, 0, 4);
+        mpProgram->DrawArrays(GL_LINE_LOOP, pPoints);
         CHECK_GL_ERROR();
     }
 
@@ -2288,13 +2271,15 @@ bool OpenGLSalGraphicsImpl::blendBitmap(
 
     VCL_GL_INFO( "::blendBitmap" );
     PreDraw();
-    glEnable( GL_BLEND );
-    CHECK_GL_ERROR();
-    glBlendFunc( GL_ZERO, GL_SRC_COLOR );
-    CHECK_GL_ERROR();
-    DrawTexture( rTexture, rPosAry );
-    glDisable( GL_BLEND );
-    CHECK_GL_ERROR();
+
+    if (!UseProgram("textureVertexShader", "textureFragmentShader"))
+        return true;
+
+    mpProgram->SetBlendMode(GL_ZERO, GL_SRC_COLOR);
+    mpProgram->SetTexture("sampler", rTexture);
+    DrawTextureRect(rTexture, rPosAry, false);
+    mpProgram->Clean();
+
     PostDraw();
     return true;
 }
@@ -2577,14 +2562,15 @@ void OpenGLSalGraphicsImpl::doFlush()
 
         GLfloat fWidth( maOffscreenTex.GetWidth() );
         GLfloat fHeight( maOffscreenTex.GetHeight() );
-        const GLfloat aVertices[] = { 0, fHeight,
-                                      0, 0,
-                                      fWidth, 0,
-                                      fWidth, fHeight };
+        std::vector<GLfloat> aVertices {
+            0, fHeight,
+            0, 0,
+            fWidth, 0,
+            fWidth, fHeight
+        };
 
         pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0);
-        pProgram->SetVertices( &aVertices[0] );
-        glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+        pProgram->DrawArrays(GL_TRIANGLE_FAN, aVertices);
 
         pProgram->Clean();
 
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index eafd0c6..c095ad4 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -51,13 +51,19 @@ bool OpenGLProgram::Load( const OUString& rVertexShader,
     return ( mnId != 0 );
 }
 
+void OpenGLProgram::Reuse()
+{
+    mbBlending = false;
+}
+
 bool OpenGLProgram::Use()
 {
-    if( !mnId )
+    if (!mnId)
         return false;
 
-    glUseProgram( mnId );
+    glUseProgram(mnId);
     CHECK_GL_ERROR();
+    Reuse();
     return true;
 }
 
@@ -84,14 +90,6 @@ bool OpenGLProgram::Clean()
         mnEnabledAttribs = 0;
     }
 
-    // disable blending if enabled
-    if( mbBlending )
-    {
-        mbBlending = false;
-        glDisable( GL_BLEND );
-        CHECK_GL_ERROR();
-    }
-
     return true;
 }
 
@@ -151,6 +149,15 @@ GLuint OpenGLProgram::GetUniformLocation( const OString& rName )
     return it->second;
 }
 
+void OpenGLProgram::DrawArrays(GLenum aMode, std::vector<GLfloat>& aVertices)
+{
+    if (!mbBlending)
+        OpenGLContext::getVCLContext()->state()->blend().disable();
+
+    SetVertices(aVertices.data());
+    glDrawArrays(aMode, 0, aVertices.size() / 2);
+}
+
 void OpenGLProgram::SetUniform1f( const OString& rName, GLfloat v1 )
 {
     GLuint nUniform = GetUniformLocation( rName );
@@ -301,12 +308,10 @@ void OpenGLProgram::ApplyMatrix(float fWidth, float fHeight, float fPixelOffset)
     CHECK_GL_ERROR();
 }
 
-void OpenGLProgram::SetBlendMode( GLenum nSFactor, GLenum nDFactor )
+void OpenGLProgram::SetBlendMode(GLenum nSFactor, GLenum nDFactor)
 {
-    glEnable( GL_BLEND );
-    CHECK_GL_ERROR();
-    glBlendFunc( nSFactor, nDFactor );
-    CHECK_GL_ERROR();
+    OpenGLContext::getVCLContext()->state()->blend().enable();
+    OpenGLContext::getVCLContext()->state()->blend().func(nSFactor, nDFactor);
     mbBlending = true;
 }
 
@@ -323,14 +328,18 @@ bool OpenGLProgram::DrawTexture( const OpenGLTexture& rTexture )
     float fMinY = 0.0f;
     float fMaxY = fHeight;
 
-    GLfloat aPosition[8] = { fMinX, fMaxY, fMinX, fMinY, fMaxX, fMinY, fMaxX, fMaxY };
+    std::vector<GLfloat> aPosition {
+        fMinX, fMaxY,
+        fMinX, fMinY,
+        fMaxX, fMinY,
+        fMaxX, fMaxY
+    };
     GLfloat aTexCoord[8];
 
     rTexture.GetWholeCoord( aTexCoord );
-    SetVertices( aPosition );
     SetTextureCoord( aTexCoord );
     ApplyMatrix(fWidth, fHeight);
-    glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+    DrawArrays(GL_TRIANGLE_FAN, aPosition);
     CHECK_GL_ERROR();
 
     return true;
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 1ac5f4d..03d0a5d 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -1789,8 +1789,12 @@ OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const O
 
     OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader, preamble );
 
-    if( pProgram == mpCurrentProgram )
+    if (pProgram == mpCurrentProgram)
+    {
+        VCL_GL_INFO("Context::UseProgram: Reusing existing program " << pProgram->Id());
+        pProgram->Reuse();
         return pProgram;
+    }
 
     mpCurrentProgram = pProgram;
 


More information about the Libreoffice-commits mailing list