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

New commits:
commit c7e71eb50dbefe505823f408709088c9eeb43c18
Author: László Németh <laszlo.nem...@collabora.com>
Date:   Tue Oct 25 12:56:02 2016 +0200

    Revert "opengl: array-less area scale..." + process idles
    
    This reverts commit a7801582728f7caffb1d50d516997066f579883f.

diff --git a/vcl/opengl/areaScaleFragmentShader.glsl 
b/vcl/opengl/areaScaleFragmentShader.glsl
index 714cb7d..c83c5e0 100644
--- a/vcl/opengl/areaScaleFragmentShader.glsl
+++ b/vcl/opengl/areaScaleFragmentShader.glsl
@@ -13,6 +13,8 @@ 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;
@@ -32,76 +34,118 @@ 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);
+    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;
 
     // Compute the range of source pixels which will make up this destination 
pixel.
-    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));
-
+    float fsx1 = dx * xscale;
+    float fsx2 = fsx1 + xscale;
     // To whole pixel coordinates.
-    int xstart = int(floor(fsx1));
-    int xend   = int(floor(fsx2));
+    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 ystart = int(floor(fsy1));
-    int yend   = int(floor(fsy2));
+    // 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 );
 
-#ifdef ARRAY_BASED
-    int posX = 0;
-    float ratio[16];
+    float height = min( yscale, sheight - fsy1 );
 
-    for (int x = xstart; x <= xend; ++x)
+    if( sy1 - fsy1 > 0.001 )
     {
-        float contributionX = calculateContribution(fsx1, fsx2, x);
-        ratio[posX] = contributionX;
-        posX++;
+        ypixel[ ypos ] = sy1 - 1;
+        yratio[ ypos ] = ( sy1 - fsy1 ) / height;
+        ++ypos;
+    }
+    for( int sy = sy1; sy < sy2; ++sy )
+    {
+        ypixel[ ypos ] = sy;
+        yratio[ ypos ] = 1.0 / height;
+        ++ypos;
+    }
+    if( fsy2 - sy2 > 0.001 )
+    {
+        ypixel[ ypos ] = sy2;
+        yratio[ ypos ] = min( min( fsy2 - sy2, 1.0 ) / height, 1.0 );
+        ++ypos;
     }
-#endif
 
-    vec4 sumAll = vec4(0.0, 0.0, 0.0, 0.0);
+    int xstart = xpixel[ 0 ];
+    int xend = xpixel[ xpos - 1 ];
+    int ystart = ypixel[ 0 ];
+    int yend = ypixel[ ypos - 1 ];
 
-    for (int y = ystart; y <= yend; ++y)
-    {
-        vec4 sumX = vec4(0.0, 0.0, 0.0, 0.0);
+    vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
 
-#ifdef ARRAY_BASED
-        posX = 0;
-#endif
-        for (int x = xstart; x <= xend; ++x)
+    ypos = 0;
+    for( int y = ystart; y <= yend; ++y, ++ypos )
+    {
+        vec4 tmp = vec4( 0.0, 0.0, 0.0, 0.0 );
+        xpos = 0;
+        for( int x = xstart; x <= xend; ++x, ++xpos )
         {
-#ifdef ARRAY_BASED
-            float contributionX = ratio[posX];
-            posX++;
+            vec2 offset = vec2( x * xsrcconvert, y * ysrcconvert );
+#ifndef MASKED
+            tmp += texture2D( sampler, offset ) * xratio[ xpos ];
 #else
-            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;
+            vec4 texel;
+            texel = texture2D( sampler, offset );
+            texel.a = 1.0 - texture2D( mask, offset ).r;
+            tmp += texel * xratio[ xpos ];
 #endif
-            sumX += texel * contributionX;
         }
-
-        float contributionY = calculateContribution(fsy1, fsy2, y);
-
-        sumAll += sumX * contributionY;
+        sum += tmp * yratio[ ypos ];
     }
 
-    gl_FragColor = sumAll;
+    gl_FragColor = sum;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to