<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[160096] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/160096">160096</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2013-12-04 09:49:30 -0800 (Wed, 04 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>[texmap] Borders on rotating images are hidden/wrongly rendered with edge distance antialiasing
https://bugs.webkit.org/show_bug.cgi?id=124653

Patch by José Dapena Paz &lt;jdapena@igalia.com&gt; on 2013-12-04
Reviewed by Noam Rosenthal.

Texture mapper edge distance antialiasing texture sampling was causing
borders to be shaded (and made them almost disappear in some cases).
This was because calculation of sampling happened on vertex shader, so
the border of the texture would go to the border of the inflation area.

What algorithm should do is sampling the border pixel for all the
inflation area (it is the closest pixel to all the samples in
inflation area), and then use the standard sampling for the other
parts of the texture.

No new test because this is already covered by test
transforms/3d/point-mapping/3d-point-mapping.html

* platform/graphics/texmap/TextureMapperShaderProgram.cpp: fix edge
distance antialiasing texture sampling.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstexmapTextureMapperShaderProgramcpp">trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (160095 => 160096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2013-12-04 17:40:29 UTC (rev 160095)
+++ trunk/Source/WebCore/ChangeLog        2013-12-04 17:49:30 UTC (rev 160096)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2013-12-04  José Dapena Paz  &lt;jdapena@igalia.com&gt;
+
+        [texmap] Borders on rotating images are hidden/wrongly rendered with edge distance antialiasing
+        https://bugs.webkit.org/show_bug.cgi?id=124653
+
+        Reviewed by Noam Rosenthal.
+
+        Texture mapper edge distance antialiasing texture sampling was causing
+        borders to be shaded (and made them almost disappear in some cases).
+        This was because calculation of sampling happened on vertex shader, so
+        the border of the texture would go to the border of the inflation area.
+
+        What algorithm should do is sampling the border pixel for all the
+        inflation area (it is the closest pixel to all the samples in
+        inflation area), and then use the standard sampling for the other
+        parts of the texture.
+
+        No new test because this is already covered by test
+        transforms/3d/point-mapping/3d-point-mapping.html
+
+        * platform/graphics/texmap/TextureMapperShaderProgram.cpp: fix edge
+        distance antialiasing texture sampling.
+
</ins><span class="cx"> 2013-12-04  László Langó  &lt;lango@inf.u-szeged.hu&gt;
</span><span class="cx"> 
</span><span class="cx">         Typo fix after r160074 to fix debug builds.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstexmapTextureMapperShaderProgramcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp (160095 => 160096)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp        2013-12-04 17:40:29 UTC (rev 160095)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp        2013-12-04 17:49:30 UTC (rev 160096)
</span><span class="lines">@@ -127,6 +127,7 @@
</span><span class="cx">         uniform mat4 u_textureSpaceMatrix;
</span><span class="cx"> 
</span><span class="cx">         varying vec2 v_texCoord;
</span><ins>+        varying vec2 v_transformedTexCoord;
</ins><span class="cx">         varying float v_antialias;
</span><span class="cx"> 
</span><span class="cx">         void noop(inout vec2 dummyParameter) { }
</span><span class="lines">@@ -172,9 +173,9 @@
</span><span class="cx">             vec2 position = a_vertex.xy;
</span><span class="cx">             applyAntialiasingIfNeeded(position);
</span><span class="cx"> 
</span><del>-            // The texture position needs to be clamped to 0..1 before the texture matrix is applied.
</del><ins>+            v_texCoord = position;
</ins><span class="cx">             vec4 clampedPosition = clamp(vec4(position, 0., 1.), 0., 1.);
</span><del>-            v_texCoord = (u_textureSpaceMatrix * clampedPosition).xy;
</del><ins>+            v_transformedTexCoord = (u_textureSpaceMatrix * clampedPosition).xy;
</ins><span class="cx">             gl_Position = u_projectionMatrix * u_modelViewMatrix * vec4(position, 0., 1.);
</span><span class="cx">         }
</span><span class="cx">     );
</span><span class="lines">@@ -188,6 +189,13 @@
</span><span class="cx">         GLSL_DIRECTIVE(define SamplerFunction texture2D) \
</span><span class="cx">     GLSL_DIRECTIVE(endif)
</span><span class="cx"> 
</span><ins>+#define ANTIALIASING_TEX_COORD_DIRECTIVE \
+    GLSL_DIRECTIVE(if defined(ENABLE_Antialiasing) &amp;&amp; defined(ENABLE_Texture)) \
+        GLSL_DIRECTIVE(define transformTexCoord fragmentTransformTexCoord) \
+    GLSL_DIRECTIVE(else) \
+        GLSL_DIRECTIVE(define transformTexCoord vertexTransformTexCoord) \
+    GLSL_DIRECTIVE(endif)
+
</ins><span class="cx"> #define ENABLE_APPLIER(Name) &quot;#define ENABLE_&quot;#Name&quot;\n#define apply&quot;#Name&quot;IfNeeded apply&quot;#Name&quot;\n&quot;
</span><span class="cx"> #define DISABLE_APPLIER(Name) &quot;#define apply&quot;#Name&quot;IfNeeded noop\n&quot;
</span><span class="cx"> #define BLUR_CONSTANTS \
</span><span class="lines">@@ -197,6 +205,7 @@
</span><span class="cx"> 
</span><span class="cx"> static const char* fragmentTemplate =
</span><span class="cx">     RECT_TEXTURE_DIRECTIVE
</span><ins>+    ANTIALIASING_TEX_COORD_DIRECTIVE
</ins><span class="cx">     BLUR_CONSTANTS
</span><span class="cx">     STRINGIFY(
</span><span class="cx">         precision mediump float;
</span><span class="lines">@@ -205,17 +214,28 @@
</span><span class="cx">         uniform float u_opacity;
</span><span class="cx">         varying float v_antialias;
</span><span class="cx">         varying vec2 v_texCoord;
</span><ins>+        varying vec2 v_transformedTexCoord;
</ins><span class="cx">         uniform float u_filterAmount;
</span><span class="cx">         uniform vec2 u_blurRadius;
</span><span class="cx">         uniform vec2 u_shadowOffset;
</span><span class="cx">         uniform vec4 u_color;
</span><span class="cx">         uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
</span><ins>+        uniform mat4 u_textureSpaceMatrix;
</ins><span class="cx"> 
</span><span class="cx">         void noop(inout vec4 dummyParameter) { }
</span><ins>+        void noop(inout vec4 dummyParameter, vec2 texCoord) { }
</ins><span class="cx"> 
</span><del>-        float antialias() { return smoothstep(v_antialias, 0., 1.); }
</del><ins>+        float antialias() { return smoothstep(0., 1., v_antialias); }
</ins><span class="cx"> 
</span><del>-        void applyTexture(inout vec4 color) { color = SamplerFunction(s_sampler, v_texCoord); }
</del><ins>+        vec2 fragmentTransformTexCoord()
+        {
+            vec4 clampedPosition = clamp(vec4(v_texCoord, 0., 1.), 0., 1.);
+            return (u_textureSpaceMatrix * clampedPosition).xy;
+        }
+
+        vec2 vertexTransformTexCoord() { return v_transformedTexCoord; }
+
+        void applyTexture(inout vec4 color, vec2 texCoord) { color = SamplerFunction(s_sampler, texCoord); }
</ins><span class="cx">         void applyOpacity(inout vec4 color) { color *= u_opacity; }
</span><span class="cx">         void applyAntialiasing(inout vec4 color) { color *= antialias(); }
</span><span class="cx"> 
</span><span class="lines">@@ -278,35 +298,35 @@
</span><span class="cx">             color = vec4(color.r, color.g, color.b, color.a * u_filterAmount);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        vec4 sampleColorAtRadius(float radius)
</del><ins>+        vec4 sampleColorAtRadius(float radius, vec2 texCoord)
</ins><span class="cx">         {
</span><del>-            vec2 coord = v_texCoord + radius * u_blurRadius;
</del><ins>+            vec2 coord = texCoord + radius * u_blurRadius;
</ins><span class="cx">             return SamplerFunction(s_sampler, coord) * float(coord.x &gt; 0. &amp;&amp; coord.y &gt; 0. &amp;&amp; coord.x &lt; 1. &amp;&amp; coord.y &lt; 1.);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        float sampleAlphaAtRadius(float radius)
</del><ins>+        float sampleAlphaAtRadius(float radius, vec2 texCoord)
</ins><span class="cx">         {
</span><del>-            vec2 coord = v_texCoord - u_shadowOffset + radius * u_blurRadius;
</del><ins>+            vec2 coord = texCoord - u_shadowOffset + radius * u_blurRadius;
</ins><span class="cx">             return SamplerFunction(s_sampler, coord).a * float(coord.x &gt; 0. &amp;&amp; coord.y &gt; 0. &amp;&amp; coord.x &lt; 1. &amp;&amp; coord.y &lt; 1.);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        void applyBlurFilter(inout vec4 color)
</del><ins>+        void applyBlurFilter(inout vec4 color, vec2 texCoord)
</ins><span class="cx">         {
</span><del>-            vec4 total = sampleColorAtRadius(0.) * u_gaussianKernel[0];
</del><ins>+            vec4 total = sampleColorAtRadius(0., texCoord) * u_gaussianKernel[0];
</ins><span class="cx">             for (int i = 1; i &lt; GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
</span><del>-                total += sampleColorAtRadius(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
-                total += sampleColorAtRadius(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
</del><ins>+                total += sampleColorAtRadius(float(i) * GAUSSIAN_KERNEL_STEP, texCoord) * u_gaussianKernel[i];
+                total += sampleColorAtRadius(float(-1 * i) * GAUSSIAN_KERNEL_STEP, texCoord) * u_gaussianKernel[i];
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             color = total;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        void applyAlphaBlur(inout vec4 color)
</del><ins>+        void applyAlphaBlur(inout vec4 color, vec2 texCoord)
</ins><span class="cx">         {
</span><del>-            float total = sampleAlphaAtRadius(0.) * u_gaussianKernel[0];
</del><ins>+            float total = sampleAlphaAtRadius(0., texCoord) * u_gaussianKernel[0];
</ins><span class="cx">             for (int i = 1; i &lt; GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
</span><del>-                total += sampleAlphaAtRadius(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
-                total += sampleAlphaAtRadius(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
</del><ins>+                total += sampleAlphaAtRadius(float(i) * GAUSSIAN_KERNEL_STEP, texCoord) * u_gaussianKernel[i];
+                total += sampleAlphaAtRadius(float(-1 * i) * GAUSSIAN_KERNEL_STEP, texCoord) * u_gaussianKernel[i];
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             color *= total;
</span><span class="lines">@@ -314,9 +334,9 @@
</span><span class="cx"> 
</span><span class="cx">         vec4 sourceOver(vec4 src, vec4 dst) { return src + dst * (1. - dst.a); }
</span><span class="cx"> 
</span><del>-        void applyContentTexture(inout vec4 color)
</del><ins>+        void applyContentTexture(inout vec4 color, vec2 texCoord)
</ins><span class="cx">         {
</span><del>-            vec4 contentColor = texture2D(s_contentTexture, v_texCoord);
</del><ins>+            vec4 contentColor = texture2D(s_contentTexture, texCoord);
</ins><span class="cx">             color = sourceOver(contentColor, color);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -325,7 +345,8 @@
</span><span class="cx">         void main(void)
</span><span class="cx">         {
</span><span class="cx">             vec4 color = vec4(1., 1., 1., 1.);
</span><del>-            applyTextureIfNeeded(color);
</del><ins>+            vec2 texCoord = transformTexCoord();
+            applyTextureIfNeeded(color, texCoord);
</ins><span class="cx">             applySolidColorIfNeeded(color);
</span><span class="cx">             applyAntialiasingIfNeeded(color);
</span><span class="cx">             applyOpacityIfNeeded(color);
</span><span class="lines">@@ -337,9 +358,9 @@
</span><span class="cx">             applyBrightnessFilterIfNeeded(color);
</span><span class="cx">             applyContrastFilterIfNeeded(color);
</span><span class="cx">             applyOpacityFilterIfNeeded(color);
</span><del>-            applyBlurFilterIfNeeded(color);
-            applyAlphaBlurIfNeeded(color);
-            applyContentTextureIfNeeded(color);
</del><ins>+            applyBlurFilterIfNeeded(color, texCoord);
+            applyAlphaBlurIfNeeded(color, texCoord);
+            applyContentTextureIfNeeded(color, texCoord);
</ins><span class="cx">             gl_FragColor = color;
</span><span class="cx">         }
</span><span class="cx">     );
</span></span></pre>
</div>
</div>

</body>
</html>