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

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Fri May 20 13:20:33 UTC 2016


 vcl/Package_opengl.mk                         |    4 +
 vcl/inc/opengl/program.hxx                    |   19 +++++++
 vcl/opengl/combinedFragmentShader.glsl        |   45 ++++++++++++++++
 vcl/opengl/combinedTextureFragmentShader.glsl |   64 ++++++++++++++++++++++++
 vcl/opengl/combinedTextureVertexShader.glsl   |   32 ++++++++++++
 vcl/opengl/combinedVertexShader.glsl          |   47 +++++++++++++++++
 vcl/opengl/gdiimpl.cxx                        |   69 ++++++++++++++++----------
 vcl/opengl/program.cxx                        |   18 ++++++
 8 files changed, 273 insertions(+), 25 deletions(-)

New commits:
commit df30dea13bd87ff94a1894805f43b5e03c61dc29
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri May 20 14:59:24 2016 +0900

    opengl: combined shaders to reduce shader switching
    
    Change-Id: I6701b93faa9b0f55dd0af6d983ce4c2de4539c70

diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index a0f6e9a..2fa917e 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -21,6 +21,10 @@ $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
     invert50FragmentShader.glsl \
 	convolutionFragmentShader.glsl \
 	linearGradientFragmentShader.glsl \
+	combinedTextureFragmentShader.glsl \
+	combinedTextureVertexShader.glsl \
+	combinedFragmentShader.glsl \
+	combinedVertexShader.glsl \
 	lineFragmentShader.glsl \
 	lineVertexShader.glsl \
 	maskFragmentShader.glsl \
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
index 5944c72..2fab98c 100644
--- a/vcl/inc/opengl/program.hxx
+++ b/vcl/inc/opengl/program.hxx
@@ -27,6 +27,21 @@
 typedef std::unordered_map< OString, GLuint, OStringHash > UniformCache;
 typedef std::list< OpenGLTexture > TextureList;
 
+enum class TextureShaderType
+{
+    Normal = 0,
+    Blend,
+    Masked,
+    Diff,
+    MaskedColor
+};
+
+enum class DrawShaderType
+{
+    Normal = 0,
+    Line
+};
+
 class VCL_PLUGIN_PUBLIC OpenGLProgram
 {
 private:
@@ -78,6 +93,10 @@ public:
     void SetTransform( const OString& rName, const OpenGLTexture& rTexture,
                        const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX,
                        const basegfx::B2DPoint& rY );
+    void SetIdentityTransform(const OString& rName);
+    void SetShaderType(TextureShaderType eTextureShaderType);
+    void SetShaderType(DrawShaderType eDrawShaderType);
+
     void SetBlendMode( GLenum nSFactor, GLenum nDFactor );
 
     void ApplyMatrix(float fWidth, float fHeight, float fPixelOffset = 0.0f);
diff --git a/vcl/opengl/combinedFragmentShader.glsl b/vcl/opengl/combinedFragmentShader.glsl
new file mode 100644
index 0000000..c44e75c
--- /dev/null
+++ b/vcl/opengl/combinedFragmentShader.glsl
@@ -0,0 +1,45 @@
+/* -*- 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/.
+ */
+
+varying float fade_factor; // 0->1 fade factor used for AA
+uniform vec4 color;
+
+uniform float line_width;
+uniform float feather;
+
+#define TYPE_NORMAL 0
+#define TYPE_LINE   1
+
+uniform int type;
+
+void main()
+{
+    float alpha = 1.0;
+
+    if (type == TYPE_LINE)
+    {
+        float start = (line_width / 2.0) - feather; // where we start to apply alpha
+        float end = (line_width / 2.0) + feather; // where we end to apply alpha
+
+        // Calculate the multiplier so we can transform the 0->1 fade factor
+        // to take feather and line width into account.
+        float multiplied = 1.0 / (1.0 - (start / end));
+
+        float dist = (1.0 - abs(fade_factor)) * multiplied;
+
+        alpha = clamp(dist, 0.0, 1.0);
+    }
+
+    vec4 result_color = color;
+    result_color.a = result_color.a * alpha;
+
+    gl_FragColor = result_color;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/combinedTextureFragmentShader.glsl b/vcl/opengl/combinedTextureFragmentShader.glsl
new file mode 100644
index 0000000..d8864cf
--- /dev/null
+++ b/vcl/opengl/combinedTextureFragmentShader.glsl
@@ -0,0 +1,64 @@
+/* -*- 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/.
+ */
+
+varying vec2 tex_coord;
+varying vec2 alpha_coord;
+varying vec2 mask_coord;
+
+uniform sampler2D texture;
+uniform sampler2D mask;
+uniform sampler2D alpha;
+
+uniform vec4 color;
+
+uniform int type;
+
+#define TYPE_NORMAL       0
+#define TYPE_BLEND        1
+#define TYPE_MASKED       2
+#define TYPE_DIFF         3
+#define TYPE_MASKED_COLOR 4
+
+void main()
+{
+    vec4 texelTexture = texture2D(texture, tex_coord);
+
+    if (type == TYPE_NORMAL)
+    {
+        gl_FragColor = texelTexture;
+    }
+    else if (type == TYPE_BLEND)
+    {
+        vec4 texelMask = texture2D(mask, mask_coord);
+        vec4 texelAlpha = texture2D(alpha, alpha_coord);
+        gl_FragColor = texelTexture;
+        gl_FragColor.a = 1.0 - (1.0 - floor(texelAlpha.r)) * texelMask.r;
+    }
+    else if (type == TYPE_MASKED)
+    {
+        vec4 texelMask = texture2D(mask, mask_coord);
+        gl_FragColor = texelTexture;
+        gl_FragColor.a = 1.0 - texelMask.r;
+    }
+    else if (type == TYPE_DIFF)
+    {
+        vec4 texelMask = texture2D(mask, mask_coord);
+        float alpha = 1.0 - abs(texelTexture.r - texelMask.r);
+        if (alpha > 0.0)
+            gl_FragColor = texelMask / alpha;
+        gl_FragColor.a = alpha;
+    }
+    else if (type == TYPE_MASKED_COLOR)
+    {
+        gl_FragColor = color;
+        gl_FragColor.a = 1.0 - texelTexture.r;
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/combinedTextureVertexShader.glsl b/vcl/opengl/combinedTextureVertexShader.glsl
new file mode 100644
index 0000000..883ec63
--- /dev/null
+++ b/vcl/opengl/combinedTextureVertexShader.glsl
@@ -0,0 +1,32 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+attribute vec2 mask_coord_in;
+attribute vec2 alpha_coord_in;
+
+varying vec2 tex_coord;
+varying vec2 mask_coord;
+varying vec2 alpha_coord;
+
+uniform mat4 mvp;
+uniform mat4 transform;
+
+uniform int type;
+
+void main()
+{
+   gl_Position = mvp * transform * position;
+   tex_coord = tex_coord_in;
+   mask_coord = mask_coord_in;
+   alpha_coord = alpha_coord_in;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/combinedVertexShader.glsl b/vcl/opengl/combinedVertexShader.glsl
new file mode 100644
index 0000000..9272544
--- /dev/null
+++ b/vcl/opengl/combinedVertexShader.glsl
@@ -0,0 +1,47 @@
+/* -*- 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/.
+ */
+
+attribute vec2 position;
+attribute vec4 extrusion_vectors;
+
+varying float fade_factor; // fade factor for anti-aliasing
+
+uniform float line_width;
+uniform float feather; // width where we fade the line
+
+uniform mat4 mvp;
+
+#define TYPE_NORMAL 0
+#define TYPE_LINE   1
+
+uniform int type;
+
+void main()
+{
+   vec4 final_position = vec4(position, 0.0, 1.0);
+
+   if (type == TYPE_LINE)
+   {
+      vec2 extrusion_vector = extrusion_vectors.xy;
+      // miter factor to additionaly lenghten the distance of vertex (needed for miter)
+      // if 1.0 - miter_factor has no effect
+      float miter_factor = 1.0f / abs(extrusion_vectors.z);
+      // fade factor is always -1.0 or 1.0 -> we transport that info together with length
+      fade_factor = sign(extrusion_vectors.z);
+
+      float rendered_thickness = (line_width + feather * 2.0) * miter_factor;
+
+      // lengthen the vertex in directon of the extrusion vector by line width.
+      final_position = vec4(position + (extrusion_vector * (rendered_thickness / 2.0) ), 0.0, 1.0);
+   }
+
+   gl_Position = mvp * final_position;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 48871d5..40df037 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -542,8 +542,9 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, sal_uInt8 nTransparency )
 {
     if( nColor == SALCOLOR_NONE )
         return false;
-    if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) )
+    if (!UseProgram("combinedVertexShader", "combinedFragmentShader"))
         return false;
+    mpProgram->SetShaderType(DrawShaderType::Normal);
     mpProgram->SetColor( "color", nColor, nTransparency );
 #ifdef DBG_UTIL
     mProgramIsSolidColor = true;
@@ -558,8 +559,9 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency )
 {
     if( nColor == SALCOLOR_NONE )
         return false;
-    if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) )
+    if (!UseProgram("combinedVertexShader", "combinedFragmentShader"))
         return false;
+    mpProgram->SetShaderType(DrawShaderType::Normal);
     mpProgram->SetColorf( "color", nColor, fTransparency );
 #ifdef DBG_UTIL
     mProgramIsSolidColor = true;
@@ -925,8 +927,9 @@ bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLflo
 {
     if( nColor == SALCOLOR_NONE )
         return false;
-    if( !UseProgram( "lineVertexShader", "lineFragmentShader" ) )
+    if (!UseProgram("combinedVertexShader", "combinedFragmentShader"))
         return false;
+    mpProgram->SetShaderType(DrawShaderType::Line);
     mpProgram->SetColorf("color", nColor, fTransparency);
     mpProgram->SetUniform1f("line_width", fLineWidth);
     // The width of the feather - area we make lineary transparent in VS.
@@ -970,7 +973,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
 #endif
         SalColor lastSolidColor = mProgramSolidColor;
         double lastSolidTransparency = mProgramSolidTransparency;
-        if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true))
+        if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f, true))
         {
             for( i = 0; i < nPoints; ++i )
             {
@@ -1013,7 +1016,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const tools::Polygon& rPolygon, b
 #endif
         SalColor lastSolidColor = mProgramSolidColor;
         double lastSolidTransparency = mProgramSolidTransparency;
-        if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true))
+        if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f, true))
         {
             for( i = 0; i < nPoints; ++i )
             {
@@ -1063,7 +1066,7 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi
 #endif
         SalColor lastSolidColor = mProgramSolidColor;
         double lastSolidTransparency = mProgramSolidTransparency;
-        if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true))
+        if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f, true))
         {
             for( i = 0; i < nPoints; ++i )
             {
@@ -1184,9 +1187,11 @@ void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRe
 
     SAL_INFO("vcl.opengl", "draw texture");
 
-    if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) )
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return;
-    mpProgram->SetTexture( "sampler", rTexture );
+    mpProgram->SetShaderType(TextureShaderType::Normal);
+    mpProgram->SetIdentityTransform("transform");
+    mpProgram->SetTexture("texture", rTexture);
     DrawTextureRect( rTexture, pPosAry, bInverted );
     mpProgram->Clean();
 }
@@ -1393,9 +1398,11 @@ void OpenGLSalGraphicsImpl::DrawAlphaTexture( OpenGLTexture& rTexture, const Sal
 {
     OpenGLZone aZone;
 
-    if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) )
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return;
-    mpProgram->SetTexture( "sampler", rTexture );
+    mpProgram->SetShaderType(TextureShaderType::Normal);
+    mpProgram->SetIdentityTransform("transform");
+    mpProgram->SetTexture("texture", rTexture);
     mpProgram->SetBlendMode( bPremultiplied ? GL_ONE : GL_SRC_ALPHA,
                              GL_ONE_MINUS_SRC_ALPHA );
     DrawTextureRect( rTexture, rPosAry, bInverted );
@@ -1406,8 +1413,10 @@ void OpenGLSalGraphicsImpl::DrawTextureDiff( OpenGLTexture& rTexture, OpenGLText
 {
     OpenGLZone aZone;
 
-    if( !UseProgram( "maskedTextureVertexShader", "diffTextureFragmentShader" ) )
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return;
+    mpProgram->SetShaderType(TextureShaderType::Diff);
+    mpProgram->SetIdentityTransform("transform");
     mpProgram->SetTexture( "texture", rTexture );
     mpProgram->SetTexture( "mask", rMask );
     mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
@@ -1424,9 +1433,11 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGL
 {
     OpenGLZone aZone;
 
-    if( !UseProgram( "maskedTextureVertexShader", "maskedTextureFragmentShader" ) )
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return;
-    mpProgram->SetTexture( "sampler", rTexture );
+    mpProgram->SetShaderType(TextureShaderType::Masked);
+    mpProgram->SetIdentityTransform("transform");
+    mpProgram->SetTexture( "texture", rTexture );
     mpProgram->SetTexture( "mask", rMask );
     mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
@@ -1446,9 +1457,10 @@ void OpenGLSalGraphicsImpl::DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLT
 {
     OpenGLZone aZone;
 
-    if( !UseProgram( "blendedTextureVertexShader", "blendedTextureFragmentShader" ) )
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return;
-    mpProgram->SetTexture( "sampler", rTexture );
+    mpProgram->SetShaderType(TextureShaderType::Blend);
+    mpProgram->SetTexture( "texture", rTexture );
     mpProgram->SetTexture( "mask", rMask );
     mpProgram->SetTexture( "alpha", rAlpha );
 
@@ -1469,10 +1481,12 @@ void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor,
 {
     OpenGLZone aZone;
 
-    if( !UseProgram( "textureVertexShader", "maskFragmentShader" ) )
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return;
+    mpProgram->SetShaderType(TextureShaderType::MaskedColor);
+    mpProgram->SetIdentityTransform("transform");
     mpProgram->SetColor( "color", nMaskColor, 0 );
-    mpProgram->SetTexture( "sampler", rMask );
+    mpProgram->SetTexture("texture", rMask);
     mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
     DrawTextureRect( rMask, pPosAry );
     mpProgram->Clean();
@@ -1529,15 +1543,16 @@ void OpenGLSalGraphicsImpl::FlushDeferredDrawing()
     }
 #endif
 
-    if( !UseProgram( "textureVertexShader", "maskFragmentShader" ) )
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return;
-
+    mpProgram->SetShaderType(TextureShaderType::MaskedColor);
+    mpProgram->SetIdentityTransform("transform");
     mpProgram->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
     for (auto& rPair : mpAccumulatedTextures->getAccumulatedTexturesMap())
     {
         OpenGLTexture& rTexture = rPair.second->maTexture;
-        mpProgram->SetTexture("sampler", rTexture);
+        mpProgram->SetTexture("texture", rTexture);
         for (auto& rColorTwoRectPair: rPair.second->maColorTextureDrawParametersMap)
         {
             mpProgram->SetColor("color", rColorTwoRectPair.first, 0);
@@ -2039,12 +2054,14 @@ bool OpenGLSalGraphicsImpl::blendBitmap(
     VCL_GL_INFO( "::blendBitmap" );
     PreDraw();
 
-    if (!UseProgram("textureVertexShader", "textureFragmentShader"))
+    if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader"))
         return true;
 
+    mpProgram->SetShaderType(TextureShaderType::Normal);
+    mpProgram->SetIdentityTransform("transform");
+    mpProgram->SetTexture("texture", rTexture);
     mpProgram->SetBlendMode(GL_ZERO, GL_SRC_COLOR);
-    mpProgram->SetTexture("sampler", rTexture);
-    DrawTextureRect(rTexture, rPosAry, false);
+    DrawTextureRect(rTexture, rPosAry);
     mpProgram->Clean();
 
     PostDraw();
@@ -2313,12 +2330,14 @@ void OpenGLSalGraphicsImpl::doFlush()
     VCL_GL_INFO( "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() );
 
     OpenGLProgram *pProgram =
-        mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "// flush shader\n" ); // flush helps profiling
+        mpWindowContext->UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader", "// flush shader\n" ); // flush helps profiling
     if( !pProgram )
         VCL_GL_INFO( "Can't compile simple copying shader !" );
     else
     {
-        pProgram->SetTexture( "sampler", maOffscreenTex );
+        pProgram->SetShaderType(TextureShaderType::Normal);
+        pProgram->SetIdentityTransform("transform");
+        pProgram->SetTexture("texture", maOffscreenTex);
 
         SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(),
                             0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() );
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index c095ad4..563a295 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -135,6 +135,16 @@ void OpenGLProgram::SetExtrusionVectors(const GLvoid* pData)
     SetVertexAttrib(mnNormalAttrib, "extrusion_vectors", pData, 3);
 }
 
+void OpenGLProgram::SetShaderType(TextureShaderType eTextureShaderType)
+{
+    SetUniform1i("type", GLint(eTextureShaderType));
+}
+
+void OpenGLProgram::SetShaderType(DrawShaderType eDrawShaderType)
+{
+    SetUniform1i("type", GLint(eDrawShaderType));
+}
+
 GLuint OpenGLProgram::GetUniformLocation( const OString& rName )
 {
     auto it = maUniformLocations.find( rName );
@@ -286,6 +296,14 @@ void OpenGLProgram::SetTransform(
     CHECK_GL_ERROR();
 }
 
+void OpenGLProgram::SetIdentityTransform(const OString& rName)
+{
+    GLuint nUniform = GetUniformLocation(rName);
+    glm::mat4 aMatrix = glm::mat4();
+    glUniformMatrix4fv(nUniform, 1, GL_FALSE, glm::value_ptr( aMatrix ) );
+    CHECK_GL_ERROR();
+}
+
 void OpenGLProgram::ApplyMatrix(float fWidth, float fHeight, float fPixelOffset)
 {
 


More information about the Libreoffice-commits mailing list