vcl/opengl/areaScaleFragmentShader.glsl | 144 +++++++++++--------------------- 1 file changed, 50 insertions(+), 94 deletions(-)
New commits: commit 20bef6e93403c2b207b055870b3985af93a74d8a Author: Tomaž Vajngerl <tomaz.vajng...@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: */
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits