[Libreoffice-commits] core.git: Branch 'feature/fixes36' - vcl/opengl

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Sun Oct 23 21:56:39 UTC 2016


 vcl/opengl/areaScaleFragmentShader.glsl |  144 +++++++++++---------------------
 1 file changed, 50 insertions(+), 94 deletions(-)

New commits:
commit a7801582728f7caffb1d50d516997066f579883f
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Sun Oct 23 23:54:21 2016 +0200

    opengl: array-less area scale fragment shader
    
    This reduces problems with this shader - like using of the array.
    All calculations are done right away now.
    
    Change-Id: I8c02ab617a144821fa8db9ebfb4abe686acafbcd

diff --git a/vcl/opengl/areaScaleFragmentShader.glsl b/vcl/opengl/areaScaleFragmentShader.glsl
index c83c5e0..714cb7d 100644
--- a/vcl/opengl/areaScaleFragmentShader.glsl
+++ b/vcl/opengl/areaScaleFragmentShader.glsl
@@ -13,8 +13,6 @@ int min( int a, int b ) { return a < b ? a : b; }
 float min( float a, float b ) { return a < b ? a : b; }
 #endif
 
-/* TODO Use textureOffset for newest version of GLSL */
-
 uniform sampler2D sampler;
 uniform int swidth;
 uniform int sheight;
@@ -34,118 +32,76 @@ varying vec2 mask_coord;
 uniform sampler2D mask;
 #endif
 
+float calculateContribution(float fLow, float fHigh, int value)
+{
+    float start = max(0.0, fLow - value);
+    float end   = max(0.0, (value + 1) - fHigh);
+    return (1.0 - start - end) / (fHigh - fLow);
+}
+
 void main(void)
 {
     // Convert to pixel coordinates again.
-    int dx = int( tex_coord.s * xdestconvert );
-    int dy = int( tex_coord.t * ydestconvert );
-
-    // Note: These values are always the same for the same X (or Y),
-    // so they could be precalculated in C++ and passed to the shader,
-    // but GLSL has limits on the size of uniforms passed to it,
-    // so it'd need something like texture buffer objects from newer
-    // GLSL versions, and it seems the hassle is not really worth it.
-
-    // How much each column/row will contribute to the resulting pixel.
-    // assert( xscale <= 100 ); assert( yscale <= 100 );
-    float xratio[ 16 + 2 ];
-    float yratio[ 16 + 2 ];
-    // For finding the first and last source pixel.
-    int xpixel[ 16 + 2 ];
-    int ypixel[ 16 + 2 ];
-
-    int xpos = 0;
-    int ypos = 0;
+    int dx = int(tex_coord.s * xdestconvert);
+    int dy = int(tex_coord.t * ydestconvert);
 
     // Compute the range of source pixels which will make up this destination pixel.
-    float fsx1 = dx * xscale;
-    float fsx2 = fsx1 + xscale;
+    float fsx1 = min(dx * xscale,   float(swidth - 1));
+    float fsx2 = min(fsx1 + xscale, float(swidth - 1));
+
+    float fsy1 = min(dy * yscale,   float(sheight - 1));
+    float fsy2 = min(fsy1 + yscale, float(sheight - 1));
+
     // To whole pixel coordinates.
-    int sx1 = int( ceil( fsx1 ) );
-    int sx2 = int( floor( fsx2 ) );
-    // Range checking.
-    sx2 = min( sx2, swidth - 1 );
-    sx1 = min( sx1, sx2 );
-
-    // How much one full column contributes to the resulting pixel.
-    float width = min( xscale, swidth - fsx1 );
-
-    if( sx1 - fsx1 > 0.001 )
-    {   // The first column contributes only partially.
-        xpixel[ xpos ] = sx1 - 1;
-        xratio[ xpos ] = ( sx1 - fsx1 ) / width;
-        ++xpos;
-    }
-    for( int sx = sx1; sx < sx2; ++sx )
-    {   // Columns that fully contribute to the resulting pixel.
-        xpixel[ xpos ] = sx;
-        xratio[ xpos ] = 1.0 / width;
-        ++xpos;
-    }
-    if( fsx2 - sx2 > 0.001 )
-    {   // The last column contributes only partially.
-        xpixel[ xpos ] = sx2;
-        xratio[ xpos ] = min( min( fsx2 - sx2, 1.0 ) / width, 1.0 );
-        ++xpos;
-    }
+    int xstart = int(floor(fsx1));
+    int xend   = int(floor(fsx2));
 
-    // The same for Y.
-    float fsy1 = dy * yscale;
-    float fsy2 = fsy1 + yscale;
-    int sy1 = int( ceil( fsy1 ) );
-    int sy2 = int( floor( fsy2 ) );
-    sy2 = min( sy2, sheight - 1 );
-    sy1 = min( sy1, sy2 );
+    int ystart = int(floor(fsy1));
+    int yend   = int(floor(fsy2));
 
-    float height = min( yscale, sheight - fsy1 );
+#ifdef ARRAY_BASED
+    int posX = 0;
+    float ratio[16];
 
-    if( sy1 - fsy1 > 0.001 )
-    {
-        ypixel[ ypos ] = sy1 - 1;
-        yratio[ ypos ] = ( sy1 - fsy1 ) / height;
-        ++ypos;
-    }
-    for( int sy = sy1; sy < sy2; ++sy )
+    for (int x = xstart; x <= xend; ++x)
     {
-        ypixel[ ypos ] = sy;
-        yratio[ ypos ] = 1.0 / height;
-        ++ypos;
+        float contributionX = calculateContribution(fsx1, fsx2, x);
+        ratio[posX] = contributionX;
+        posX++;
     }
-    if( fsy2 - sy2 > 0.001 )
-    {
-        ypixel[ ypos ] = sy2;
-        yratio[ ypos ] = min( min( fsy2 - sy2, 1.0 ) / height, 1.0 );
-        ++ypos;
-    }
-
-    int xstart = xpixel[ 0 ];
-    int xend = xpixel[ xpos - 1 ];
-    int ystart = ypixel[ 0 ];
-    int yend = ypixel[ ypos - 1 ];
+#endif
 
-    vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
+    vec4 sumAll = vec4(0.0, 0.0, 0.0, 0.0);
 
-    ypos = 0;
-    for( int y = ystart; y <= yend; ++y, ++ypos )
+    for (int y = ystart; y <= yend; ++y)
     {
-        vec4 tmp = vec4( 0.0, 0.0, 0.0, 0.0 );
-        xpos = 0;
-        for( int x = xstart; x <= xend; ++x, ++xpos )
+        vec4 sumX = vec4(0.0, 0.0, 0.0, 0.0);
+
+#ifdef ARRAY_BASED
+        posX = 0;
+#endif
+        for (int x = xstart; x <= xend; ++x)
         {
-            vec2 offset = vec2( x * xsrcconvert, y * ysrcconvert );
-#ifndef MASKED
-            tmp += texture2D( sampler, offset ) * xratio[ xpos ];
+#ifdef ARRAY_BASED
+            float contributionX = ratio[posX];
+            posX++;
 #else
-            vec4 texel;
-            texel = texture2D( sampler, offset );
-            texel.a = 1.0 - texture2D( mask, offset ).r;
-            tmp += texel * xratio[ xpos ];
+            float contributionX = calculateContribution(fsx1, fsx2, x);
+#endif
+            vec2 offset = vec2(x * xsrcconvert, y * ysrcconvert);
+            vec4 texel = texture2D(sampler, offset);
+#ifdef MASKED
+            texel.a = 1.0 - texture2D(mask, offset).r;
 #endif
+            sumX += texel * contributionX;
         }
-        sum += tmp * yratio[ ypos ];
+
+        float contributionY = calculateContribution(fsy1, fsy2, y);
+
+        sumAll += sumX * contributionY;
     }
 
-    gl_FragColor = sum;
+    gl_FragColor = sumAll;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list