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