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

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Mon May 23 23:34:54 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 3cac38b2311538a0aecca765eb62c30c5098a85c
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
    
    Combine most common shaders for non-texture drawing and texture
    drawing into two combined shaders. Inside the shader we switch
    between the code paths with if statements.
    
    Using if statements (or any other branching statements) is
    discouraged inside shaders but on the other hand we reduce program
    state changes if we have less shader changes - which is more
    important for us as we want to push more work to the GPU.
    
    Change-Id: I6701b93faa9b0f55dd0af6d983ce4c2de4539c70
    Reviewed-on: https://gerrit.libreoffice.org/25357
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    Tested-by: Tomaž Vajngerl <quikee at gmail.com>

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 a92e5b3..58b4d62 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -544,8 +544,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;
@@ -560,8 +561,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,12 +927,13 @@ 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.
-    // Good AA value is 0.5
+    // Good AA value is 0.5f, no AA if feather 0.0f
     mpProgram->SetUniform1f("feather", bUseAA ? 0.5f : 0.0f);
     // We need blending or AA won't work correctly
     mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
@@ -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();
@@ -1530,15 +1544,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);
@@ -2048,11 +2063,13 @@ 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);
     mpProgram->Clean();
 
@@ -2332,12 +2349,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 71530cb..2331080 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