[chromium] Pass mask scale and offset to shaders for correct masking
authorshawnsingh@chromium.org <shawnsingh@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Aug 2012 19:39:24 +0000 (19:39 +0000)
committershawnsingh@chromium.org <shawnsingh@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Aug 2012 19:39:24 +0000 (19:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=93558

Reviewed by Adrienne Walker.

Source/WebCore:

In chromium compositor code, the mask was accidentally mapped 1:1
to the layer's renderSurface, rather than the layer itself. This
patch adds a layout test that reproduces the error and fixes the
problem. The solution we opted for in this patch is to pass a
scale and offset to the fragment shader, so that the correct
texture coordinate lookup is computed by the fragment shader.

Test: compositing/masks/mask-of-clipped-layer.html

* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::drawRenderPassQuad):
* platform/graphics/chromium/ShaderChromium.cpp:
(WebCore::FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask):
(WebCore::FragmentShaderRGBATexAlphaMask::init):
(WebCore::FragmentShaderRGBATexAlphaMask::getShaderString):
(WebCore::FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA):
(WebCore::FragmentShaderRGBATexAlphaMaskAA::init):
(WebCore::FragmentShaderRGBATexAlphaMaskAA::getShaderString):
* platform/graphics/chromium/ShaderChromium.h:
(WebCore::FragmentShaderRGBATexAlphaMask::maskTexCoordScaleLocation):
(WebCore::FragmentShaderRGBATexAlphaMask::maskTexCoordOffsetLocation):
(FragmentShaderRGBATexAlphaMask):
(WebCore::FragmentShaderRGBATexAlphaMaskAA::maskTexCoordScaleLocation):
(WebCore::FragmentShaderRGBATexAlphaMaskAA::maskTexCoordOffsetLocation):
(FragmentShaderRGBATexAlphaMaskAA):
* platform/graphics/chromium/cc/CCRenderPassDrawQuad.cpp:
(WebCore::CCRenderPassDrawQuad::create):
(WebCore::CCRenderPassDrawQuad::CCRenderPassDrawQuad):
* platform/graphics/chromium/cc/CCRenderPassDrawQuad.h:
(CCRenderPassDrawQuad):
(WebCore::CCRenderPassDrawQuad::maskTexCoordScaleX):
(WebCore::CCRenderPassDrawQuad::maskTexCoordScaleY):
(WebCore::CCRenderPassDrawQuad::maskTexCoordOffsetX):
(WebCore::CCRenderPassDrawQuad::maskTexCoordOffsetY):
* platform/graphics/chromium/cc/CCRenderSurface.cpp:
(WebCore::CCRenderSurface::appendQuads):

Source/WebKit/chromium:

Updated one unit test that needed additional args in a
constructor, but no change in behavior of the test.

* tests/CCLayerTreeHostImplTest.cpp:

LayoutTests:

Added a layout test that checks the mask does not accidentally get
resized when it is inside of an overflow div.

* compositing/masks/mask-of-clipped-layer-expected.png: Added.
* compositing/masks/mask-of-clipped-layer-expected.txt: Added.
* compositing/masks/mask-of-clipped-layer.html: Added.
* compositing/resources/alpha-blocks.png: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@125193 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/masks/mask-of-clipped-layer-expected.png [new file with mode: 0644]
LayoutTests/compositing/masks/mask-of-clipped-layer-expected.txt [new file with mode: 0644]
LayoutTests/compositing/masks/mask-of-clipped-layer.html [new file with mode: 0644]
LayoutTests/compositing/resources/alpha-blocks.png [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp
Source/WebCore/platform/graphics/chromium/ShaderChromium.h
Source/WebCore/platform/graphics/chromium/cc/CCRenderPassDrawQuad.cpp
Source/WebCore/platform/graphics/chromium/cc/CCRenderPassDrawQuad.h
Source/WebCore/platform/graphics/chromium/cc/CCRenderSurface.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp

index 8d0ae5a..c4cd44a 100644 (file)
@@ -1,3 +1,18 @@
+2012-08-09  Shawn Singh  <shawnsingh@chromium.org>
+
+        [chromium] Pass mask scale and offset to shaders for correct masking
+        https://bugs.webkit.org/show_bug.cgi?id=93558
+
+        Reviewed by Adrienne Walker.
+
+        Added a layout test that checks the mask does not accidentally get
+        resized when it is inside of an overflow div.
+
+        * compositing/masks/mask-of-clipped-layer-expected.png: Added.
+        * compositing/masks/mask-of-clipped-layer-expected.txt: Added.
+        * compositing/masks/mask-of-clipped-layer.html: Added.
+        * compositing/resources/alpha-blocks.png: Added.
+
 2012-08-09  Mihnea Ovidenie  <mihnea@adobe.com>
 
         CSSRegions: Crash when attaching a region to the removed named flow
diff --git a/LayoutTests/compositing/masks/mask-of-clipped-layer-expected.png b/LayoutTests/compositing/masks/mask-of-clipped-layer-expected.png
new file mode 100644 (file)
index 0000000..99ad6f9
Binary files /dev/null and b/LayoutTests/compositing/masks/mask-of-clipped-layer-expected.png differ
diff --git a/LayoutTests/compositing/masks/mask-of-clipped-layer-expected.txt b/LayoutTests/compositing/masks/mask-of-clipped-layer-expected.txt
new file mode 100644 (file)
index 0000000..a5abe5b
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x216
+  RenderBlock {HTML} at (0,0) size 800x216
+    RenderBody {BODY} at (8,8) size 784x200
+layer at (8,8) size 200x200 scrollWidth 300 scrollHeight 300
+  RenderBlock {DIV} at (0,0) size 200x200 [bgcolor=#0000FF]
+    RenderBlock {DIV} at (0,0) size 140x140 [bgcolor=#FF0000]
+layer at (8,8) size 300x300 backgroundClip at (8,8) size 200x200 clip at (8,8) size 200x200 outlineClip at (8,8) size 200x200
+  RenderBlock {DIV} at (0,0) size 300x300 [bgcolor=#00FF00]
diff --git a/LayoutTests/compositing/masks/mask-of-clipped-layer.html b/LayoutTests/compositing/masks/mask-of-clipped-layer.html
new file mode 100644 (file)
index 0000000..5607806
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style type="text/css" media="screen">
+      .hidesOverflow {
+        background-color: blue;
+        width: 200px;
+        height: 200px;
+        overflow: hidden;
+      }
+
+      .shouldNotBeVisible {
+        background-color: red;
+        width: 140px;
+        height: 140px;
+      }
+
+      .composited {
+        -webkit-transform: translatez(0);
+      }
+
+      .masked {
+        -webkit-mask-box-image: url(../resources/alpha-blocks.png);
+        background-color: lime;
+        width: 300px;
+        height: 300px;
+      }
+  </style>
+</head>
+<body>
+<!-- 
+ https://bugs.webkit.org/show_bug.cgi?id=93558 
+
+ Scenario: The alpha-blocks mask has a checkerboard pattern of opaque/transparent
+ sections. The top-left section of the mask should be opaque, so the red div should not be
+ visible underneath the mask. However, in chromium there was a bug where the mask was
+ accidentally being resized to the clip area, incorrectly exposing the red div.
+-->
+  <div class="hidesOverflow">
+    <div class="shouldNotBeVisible">
+    <div class="composited masked">
+    </div>
+  </div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/resources/alpha-blocks.png b/LayoutTests/compositing/resources/alpha-blocks.png
new file mode 100644 (file)
index 0000000..31a15c3
Binary files /dev/null and b/LayoutTests/compositing/resources/alpha-blocks.png differ
index 0b22c49..13fccea 100644 (file)
@@ -3492,6 +3492,9 @@ BUGWK93567 DEBUG : fast/parser/javascript-url-compat-mode.html = PASS TEXT
 BUGWK93569 DEBUG : http/tests/navigation/lockedhistory-iframe.html = PASS TIMEOUT TEXT
 BUGWK93568 DEBUG : http/tests/misc/window-dot-stop.html = PASS TEXT
 
+// Should only need rebaselining after bug 93558, if both squares are fully green.
+BUGWK93558 : compositing/masks/layer-mask-placement.html = IMAGE
+
 BUGWK93586 : fast/forms/autocomplete-off-with-default-value-does-not-clear.html = TIMEOUT
 
 // Tests requiring rebaseling afer bug 93475
index 29410e9..30031c1 100644 (file)
@@ -1,3 +1,47 @@
+2012-08-09  Shawn Singh  <shawnsingh@chromium.org>
+
+        [chromium] Pass mask scale and offset to shaders for correct masking
+        https://bugs.webkit.org/show_bug.cgi?id=93558
+
+        Reviewed by Adrienne Walker.
+
+        In chromium compositor code, the mask was accidentally mapped 1:1
+        to the layer's renderSurface, rather than the layer itself. This
+        patch adds a layout test that reproduces the error and fixes the
+        problem. The solution we opted for in this patch is to pass a
+        scale and offset to the fragment shader, so that the correct
+        texture coordinate lookup is computed by the fragment shader.
+
+        Test: compositing/masks/mask-of-clipped-layer.html
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::drawRenderPassQuad):
+        * platform/graphics/chromium/ShaderChromium.cpp:
+        (WebCore::FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask):
+        (WebCore::FragmentShaderRGBATexAlphaMask::init):
+        (WebCore::FragmentShaderRGBATexAlphaMask::getShaderString):
+        (WebCore::FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA):
+        (WebCore::FragmentShaderRGBATexAlphaMaskAA::init):
+        (WebCore::FragmentShaderRGBATexAlphaMaskAA::getShaderString):
+        * platform/graphics/chromium/ShaderChromium.h:
+        (WebCore::FragmentShaderRGBATexAlphaMask::maskTexCoordScaleLocation):
+        (WebCore::FragmentShaderRGBATexAlphaMask::maskTexCoordOffsetLocation):
+        (FragmentShaderRGBATexAlphaMask):
+        (WebCore::FragmentShaderRGBATexAlphaMaskAA::maskTexCoordScaleLocation):
+        (WebCore::FragmentShaderRGBATexAlphaMaskAA::maskTexCoordOffsetLocation):
+        (FragmentShaderRGBATexAlphaMaskAA):
+        * platform/graphics/chromium/cc/CCRenderPassDrawQuad.cpp:
+        (WebCore::CCRenderPassDrawQuad::create):
+        (WebCore::CCRenderPassDrawQuad::CCRenderPassDrawQuad):
+        * platform/graphics/chromium/cc/CCRenderPassDrawQuad.h:
+        (CCRenderPassDrawQuad):
+        (WebCore::CCRenderPassDrawQuad::maskTexCoordScaleX):
+        (WebCore::CCRenderPassDrawQuad::maskTexCoordScaleY):
+        (WebCore::CCRenderPassDrawQuad::maskTexCoordOffsetX):
+        (WebCore::CCRenderPassDrawQuad::maskTexCoordOffsetY):
+        * platform/graphics/chromium/cc/CCRenderSurface.cpp:
+        (WebCore::CCRenderSurface::appendQuads):
+
 2012-08-09  Mihnea Ovidenie  <mihnea@adobe.com>
 
         CSSRegions: Crash when attaching a region to the removed named flow
index 7ea1c4b..d2c6ce5 100644 (file)
@@ -686,6 +686,8 @@ void LayerRendererChromium::drawRenderPassQuad(DrawingFrame& frame, const CCRend
     int shaderQuadLocation = -1;
     int shaderEdgeLocation = -1;
     int shaderMaskSamplerLocation = -1;
+    int shaderMaskTexCoordScaleLocation = -1;
+    int shaderMaskTexCoordOffsetLocation = -1;
     int shaderMatrixLocation = -1;
     int shaderAlphaLocation = -1;
     if (useAA && maskTextureId) {
@@ -696,6 +698,8 @@ void LayerRendererChromium::drawRenderPassQuad(DrawingFrame& frame, const CCRend
         shaderQuadLocation = program->vertexShader().pointLocation();
         shaderEdgeLocation = program->fragmentShader().edgeLocation();
         shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocation();
+        shaderMaskTexCoordScaleLocation = program->fragmentShader().maskTexCoordScaleLocation();
+        shaderMaskTexCoordOffsetLocation = program->fragmentShader().maskTexCoordOffsetLocation();
         shaderMatrixLocation = program->vertexShader().matrixLocation();
         shaderAlphaLocation = program->fragmentShader().alphaLocation();
     } else if (!useAA && maskTextureId) {
@@ -704,6 +708,8 @@ void LayerRendererChromium::drawRenderPassQuad(DrawingFrame& frame, const CCRend
         GLC(context(), context()->uniform1i(program->fragmentShader().samplerLocation(), 0));
 
         shaderMaskSamplerLocation = program->fragmentShader().maskSamplerLocation();
+        shaderMaskTexCoordScaleLocation = program->fragmentShader().maskTexCoordScaleLocation();
+        shaderMaskTexCoordOffsetLocation = program->fragmentShader().maskTexCoordOffsetLocation();
         shaderMatrixLocation = program->vertexShader().matrixLocation();
         shaderAlphaLocation = program->fragmentShader().alphaLocation();
     } else if (useAA && !maskTextureId) {
@@ -725,8 +731,12 @@ void LayerRendererChromium::drawRenderPassQuad(DrawingFrame& frame, const CCRend
     }
 
     if (shaderMaskSamplerLocation != -1) {
+        ASSERT(shaderMaskTexCoordScaleLocation != 1);
+        ASSERT(shaderMaskTexCoordOffsetLocation != 1);
         GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE1));
         GLC(context(), context()->uniform1i(shaderMaskSamplerLocation, 1));
+        GLC(context(), context()->uniform2f(shaderMaskTexCoordScaleLocation, quad->maskTexCoordScaleX(), quad->maskTexCoordScaleY()));
+        GLC(context(), context()->uniform2f(shaderMaskTexCoordOffsetLocation, quad->maskTexCoordOffsetX(), quad->maskTexCoordOffsetY()));
         context()->bindTexture(GraphicsContext3D::TEXTURE_2D, maskTextureId);
         GLC(context(), context()->activeTexture(GraphicsContext3D::TEXTURE0));
     }
index 7ee5a21..8823d1a 100644 (file)
@@ -656,6 +656,7 @@ FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
     : m_samplerLocation(-1)
     , m_maskSamplerLocation(-1)
     , m_alphaLocation(-1)
+    , m_maskTexCoordScaleLocation(-1)
 {
 }
 
@@ -665,14 +666,18 @@ void FragmentShaderRGBATexAlphaMask::init(WebGraphicsContext3D* context, unsigne
         "s_texture",
         "s_mask",
         "alpha",
+        "maskTexCoordScale",
+        "maskTexCoordOffset",
     };
-    int locations[3];
+    int locations[5];
 
     getProgramUniformLocations(context, program, shaderUniforms, WTF_ARRAY_LENGTH(shaderUniforms), WTF_ARRAY_LENGTH(locations), locations, usingBindUniform, baseUniformIndex);
 
     m_samplerLocation = locations[0];
     m_maskSamplerLocation = locations[1];
     m_alphaLocation = locations[2];
+    m_maskTexCoordScaleLocation = locations[3];
+    m_maskTexCoordOffsetLocation = locations[4];
     ASSERT(m_samplerLocation != -1 && m_maskSamplerLocation != -1 && m_alphaLocation != -1);
 }
 
@@ -683,11 +688,14 @@ String FragmentShaderRGBATexAlphaMask::getShaderString() const
         varying vec2 v_texCoord;
         uniform sampler2D s_texture;
         uniform sampler2D s_mask;
+        uniform vec2 maskTexCoordScale;
+        uniform vec2 maskTexCoordOffset;
         uniform float alpha;
         void main()
         {
             vec4 texColor = texture2D(s_texture, v_texCoord);
-            vec4 maskColor = texture2D(s_mask, v_texCoord);
+            vec2 maskTexCoord = vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
+            vec4 maskColor = texture2D(s_mask, maskTexCoord);
             gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w;
         }
     );
@@ -698,6 +706,7 @@ FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
     , m_maskSamplerLocation(-1)
     , m_alphaLocation(-1)
     , m_edgeLocation(-1)
+    , m_maskTexCoordScaleLocation(-1)
 {
 }
 
@@ -708,8 +717,10 @@ void FragmentShaderRGBATexAlphaMaskAA::init(WebGraphicsContext3D* context, unsig
         "s_mask",
         "alpha",
         "edge",
+        "maskTexCoordScale",
+        "maskTexCoordOffset",
     };
-    int locations[4];
+    int locations[6];
 
     getProgramUniformLocations(context, program, shaderUniforms, WTF_ARRAY_LENGTH(shaderUniforms), WTF_ARRAY_LENGTH(locations), locations, usingBindUniform, baseUniformIndex);
 
@@ -717,6 +728,8 @@ void FragmentShaderRGBATexAlphaMaskAA::init(WebGraphicsContext3D* context, unsig
     m_maskSamplerLocation = locations[1];
     m_alphaLocation = locations[2];
     m_edgeLocation = locations[3];
+    m_maskTexCoordScaleLocation = locations[4];
+    m_maskTexCoordOffsetLocation = locations[5];
     ASSERT(m_samplerLocation != -1 && m_maskSamplerLocation != -1 && m_alphaLocation != -1 && m_edgeLocation != -1);
 }
 
@@ -727,12 +740,15 @@ String FragmentShaderRGBATexAlphaMaskAA::getShaderString() const
         varying vec2 v_texCoord;
         uniform sampler2D s_texture;
         uniform sampler2D s_mask;
+        uniform vec2 maskTexCoordScale;
+        uniform vec2 maskTexCoordOffset;
         uniform float alpha;
         uniform vec3 edge[8];
         void main()
         {
             vec4 texColor = texture2D(s_texture, v_texCoord);
-            vec4 maskColor = texture2D(s_mask, v_texCoord);
+            vec2 maskTexCoord = vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x, maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
+            vec4 maskColor = texture2D(s_mask, maskTexCoord);
             vec3 pos = vec3(gl_FragCoord.xy, 1);
             float a0 = clamp(dot(edge[0], pos), 0.0, 1.0);
             float a1 = clamp(dot(edge[1], pos), 0.0, 1.0);
index 00872e4..5af95d8 100644 (file)
@@ -282,11 +282,15 @@ public:
     int alphaLocation() const { return m_alphaLocation; }
     int samplerLocation() const { return m_samplerLocation; }
     int maskSamplerLocation() const { return m_maskSamplerLocation; }
+    int maskTexCoordScaleLocation() const { return m_maskTexCoordScaleLocation; }
+    int maskTexCoordOffsetLocation() const { return m_maskTexCoordOffsetLocation; }
 
 private:
     int m_samplerLocation;
     int m_maskSamplerLocation;
     int m_alphaLocation;
+    int m_maskTexCoordScaleLocation;
+    int m_maskTexCoordOffsetLocation;
 };
 
 class FragmentShaderRGBATexAlphaMaskAA {
@@ -299,12 +303,16 @@ public:
     int samplerLocation() const { return m_samplerLocation; }
     int maskSamplerLocation() const { return m_maskSamplerLocation; }
     int edgeLocation() const { return m_edgeLocation; }
+    int maskTexCoordScaleLocation() const { return m_maskTexCoordScaleLocation; }
+    int maskTexCoordOffsetLocation() const { return m_maskTexCoordOffsetLocation; }
 
 private:
     int m_samplerLocation;
     int m_maskSamplerLocation;
     int m_alphaLocation;
     int m_edgeLocation;
+    int m_maskTexCoordScaleLocation;
+    int m_maskTexCoordOffsetLocation;
 };
 
 class FragmentShaderYUVVideo {
index ca08111..3b0a48a 100644 (file)
 
 namespace WebCore {
 
-PassOwnPtr<CCRenderPassDrawQuad> CCRenderPassDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, int renderPassId, bool isReplica, const CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame)
+PassOwnPtr<CCRenderPassDrawQuad> CCRenderPassDrawQuad::create(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, int renderPassId, bool isReplica, const CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame, float maskTexCoordScaleX, float maskTexCoordScaleY, float maskTexCoordOffsetX, float maskTexCoordOffsetY)
 {
-    return adoptPtr(new CCRenderPassDrawQuad(sharedQuadState, quadRect, renderPassId, isReplica, maskResourceId, contentsChangedSinceLastFrame));
+    return adoptPtr(new CCRenderPassDrawQuad(sharedQuadState, quadRect, renderPassId, isReplica, maskResourceId, contentsChangedSinceLastFrame, maskTexCoordScaleX, maskTexCoordScaleY, maskTexCoordOffsetX, maskTexCoordOffsetY));
 }
 
-CCRenderPassDrawQuad::CCRenderPassDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, int renderPassId, bool isReplica, CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame)
+CCRenderPassDrawQuad::CCRenderPassDrawQuad(const CCSharedQuadState* sharedQuadState, const IntRect& quadRect, int renderPassId, bool isReplica, CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame, float maskTexCoordScaleX, float maskTexCoordScaleY, float maskTexCoordOffsetX, float maskTexCoordOffsetY)
     : CCDrawQuad(sharedQuadState, CCDrawQuad::RenderPass, quadRect)
     , m_renderPassId(renderPassId)
     , m_isReplica(isReplica)
     , m_maskResourceId(maskResourceId)
     , m_contentsChangedSinceLastFrame(contentsChangedSinceLastFrame)
+    , m_maskTexCoordScaleX(maskTexCoordScaleX)
+    , m_maskTexCoordScaleY(maskTexCoordScaleY)
+    , m_maskTexCoordOffsetX(maskTexCoordOffsetX)
+    , m_maskTexCoordOffsetY(maskTexCoordOffsetY)
 {
     ASSERT(m_renderPassId > 0);
 }
index 29b33a1..df8ce0c 100644 (file)
@@ -38,7 +38,7 @@ class CCRenderPass;
 class CCRenderPassDrawQuad : public CCDrawQuad {
     WTF_MAKE_NONCOPYABLE(CCRenderPassDrawQuad);
 public:
-    static PassOwnPtr<CCRenderPassDrawQuad> create(const CCSharedQuadState*, const IntRect&, int renderPassId, bool isReplica, CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame);
+    static PassOwnPtr<CCRenderPassDrawQuad> create(const CCSharedQuadState*, const IntRect&, int renderPassId, bool isReplica, CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame, float maskTexCoordScaleX, float maskTexCoordScaleY, float maskTexCoordOffsetX, float maskTexCoordOffsetY);
 
     int renderPassId() const { return m_renderPassId; }
     bool isReplica() const { return m_isReplica; }
@@ -46,13 +46,22 @@ public:
     const IntRect& contentsChangedSinceLastFrame() const { return m_contentsChangedSinceLastFrame; }
 
     static const CCRenderPassDrawQuad* materialCast(const CCDrawQuad*);
+    float maskTexCoordScaleX() const { return m_maskTexCoordScaleX; }
+    float maskTexCoordScaleY() const { return m_maskTexCoordScaleY; }
+    float maskTexCoordOffsetX() const { return m_maskTexCoordOffsetX; }
+    float maskTexCoordOffsetY() const { return m_maskTexCoordOffsetY; }
+
 private:
-    CCRenderPassDrawQuad(const CCSharedQuadState*, const IntRect&, int renderPassId, bool isReplica, CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame);
+    CCRenderPassDrawQuad(const CCSharedQuadState*, const IntRect&, int renderPassId, bool isReplica, CCResourceProvider::ResourceId maskResourceId, const IntRect& contentsChangedSinceLastFrame, float maskTexCoordScaleX, float maskTexCoordScaleY, float maskTexCoordOffsetX, float maskTexCoordOffsetY);
 
     int m_renderPassId;
     bool m_isReplica;
     CCResourceProvider::ResourceId m_maskResourceId;
     IntRect m_contentsChangedSinceLastFrame;
+    float m_maskTexCoordScaleX;
+    float m_maskTexCoordScaleY;
+    float m_maskTexCoordOffsetX;
+    float m_maskTexCoordOffsetY;
 };
 
 }
index 425d727..4b271e1 100644 (file)
@@ -207,10 +207,22 @@ void CCRenderSurface::appendQuads(CCQuadSink& quadList, CCSharedQuadState* share
             maskLayer = 0;
     }
 
+    float maskTexCoordScaleX = 1;
+    float maskTexCoordScaleY = 1;
+    float maskTexCoordOffsetX = 1;
+    float maskTexCoordOffsetY = 1;
+    if (maskLayer) {
+        maskTexCoordScaleX = static_cast<float>(contentRect().width()) / maskLayer->contentBounds().width();
+        maskTexCoordScaleY = static_cast<float>(contentRect().height()) / maskLayer->contentBounds().height();
+        maskTexCoordOffsetX = static_cast<float>(contentRect().x()) / contentRect().width() * maskTexCoordScaleX;
+        maskTexCoordOffsetY = static_cast<float>(contentRect().y()) / contentRect().height() * maskTexCoordScaleY;
+    }
+
     CCResourceProvider::ResourceId maskResourceId = maskLayer ? maskLayer->contentsResourceId() : 0;
     IntRect contentsChangedSinceLastFrame = contentsChanged() ? m_contentRect : IntRect();
 
-    quadList.append(CCRenderPassDrawQuad::create(sharedQuadState, contentRect(), renderPassId, forReplica, maskResourceId, contentsChangedSinceLastFrame));
+    quadList.append(CCRenderPassDrawQuad::create(sharedQuadState, contentRect(), renderPassId, forReplica, maskResourceId, contentsChangedSinceLastFrame,
+                                                 maskTexCoordScaleX, maskTexCoordScaleY, maskTexCoordOffsetX, maskTexCoordOffsetY));
 }
 
 }
index 2c7ea00..82d7a85 100644 (file)
@@ -1,3 +1,15 @@
+2012-08-09  Shawn Singh  <shawnsingh@chromium.org>
+
+        [chromium] Pass mask scale and offset to shaders for correct masking
+        https://bugs.webkit.org/show_bug.cgi?id=93558
+
+        Reviewed by Adrienne Walker.
+
+        Updated one unit test that needed additional args in a
+        constructor, but no change in behavior of the test.
+
+        * tests/CCLayerTreeHostImplTest.cpp:
+
 2012-08-09  Pavel Feldman  <pfeldman@chromium.org>
 
         Web Inspector: add codemirror library as an experiment
index 957a589..752abc1 100644 (file)
@@ -3802,7 +3802,7 @@ static void configureRenderPassTestData(const char* testScript, RenderPassRemova
 
                 IntRect quadRect = IntRect(0, 0, 1, 1);
                 IntRect contentsChangedRect = contentsChanged ? quadRect : IntRect();
-                OwnPtr<CCRenderPassDrawQuad> quad = CCRenderPassDrawQuad::create(testData.sharedQuadState.get(), quadRect, newRenderPassId, isReplica, 1, contentsChangedRect);
+                OwnPtr<CCRenderPassDrawQuad> quad = CCRenderPassDrawQuad::create(testData.sharedQuadState.get(), quadRect, newRenderPassId, isReplica, 1, contentsChangedRect, 1, 1, 0, 0);
                 static_cast<CCTestRenderPass*>(renderPass.get())->appendQuad(quad.release());
             }
         }