[Texmap] TextureMapper is too eager to use intermediate surfaces
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Feb 2013 16:16:16 +0000 (16:16 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Feb 2013 16:16:16 +0000 (16:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=110762

Patch by No'am Rosenthal <noam@webkit.org> on 2013-02-27
Reviewed by Allan Sandfeld Jensen.

Source/WebCore:

Refactor the way intermediate surfaces are handled in TextureMapperLayer.
Beforehand, we would create an intermediate surface whenever there is a chance of overlap, and
the intermediate surface would be the largest possible. The result would then be drawn to the
target surface with the layer's opacity and mask.

This would make it so that (1) surfaces are created even when they're not needed, i.e. when there
is no actual overlap, and (2) mask wouldn't be applied correctly.

In this patch the behavior is changed so that the area to be painted is divided to "overlapping"
and "non overlapping" regions. The non-overlapping regions are painted directly, while the overlapping
regions are tiled to smaller rectangles painted using an intermediate surface.
Masks are applied to those intermediate surfaces based on the transform of the actual mask, not drawn
together with the content texture like before.

This optimizes for the more common case of opacity animations on a large tree, while making the quite
rare case of composited masks slightly less optimized but always correct.

Tests: compositing/overlap-blending/children-opacity-huge.html
       compositing/overlap-blending/reflection-opacity-huge.html
       compositing/overlap-blending/children-opacity-no-overlap.html

* platform/graphics/cairo/GraphicsContext3DPrivate.cpp:
(WebCore::GraphicsContext3DPrivate::paintToTextureMapper):
* platform/graphics/cairo/GraphicsContext3DPrivate.h:
(GraphicsContext3DPrivate):
* platform/graphics/efl/GraphicsContext3DPrivate.cpp:
(WebCore::GraphicsContext3DPrivate::paintToTextureMapper):
* platform/graphics/efl/GraphicsContext3DPrivate.h:
(GraphicsContext3DPrivate):
* platform/graphics/qt/GraphicsContext3DQt.cpp:
(GraphicsContext3DPrivate):
(WebCore::GraphicsContext3DPrivate::paintToTextureMapper):
* platform/graphics/qt/MediaPlayerPrivateQt.cpp:
(WebCore::MediaPlayerPrivateQt::paintToTextureMapper):
* platform/graphics/qt/MediaPlayerPrivateQt.h:
(MediaPlayerPrivateQt):
* platform/graphics/surfaces/GraphicsSurface.cpp:
(WebCore::GraphicsSurface::paintToTextureMapper):
* platform/graphics/surfaces/GraphicsSurface.h:
(GraphicsSurface):
* platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp:
(WebCore::GraphicsSurface::platformPaintToTextureMapper):
* platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp:
(WebCore::GraphicsSurface::platformPaintToTextureMapper):
* platform/graphics/surfaces/win/GraphicsSurfaceWin.cpp:
(WebCore::GraphicsSurface::platformPaintToTextureMapper):
* platform/graphics/texmap/TextureMapperBackingStore.h:
(TextureMapperBackingStore):
* platform/graphics/texmap/TextureMapperPlatformLayer.h:
(TextureMapperPlatformLayer):
* platform/graphics/texmap/TextureMapperSurfaceBackingStore.cpp:
(WebCore::TextureMapperSurfaceBackingStore::paintToTextureMapper):
* platform/graphics/texmap/TextureMapperSurfaceBackingStore.h:
(TextureMapperSurfaceBackingStore):
* platform/graphics/texmap/TextureMapperTile.cpp:
(WebCore::TextureMapperTile::paint):
* platform/graphics/texmap/TextureMapperTile.h:
(TextureMapperTile):
* platform/graphics/texmap/TextureMapperTiledBackingStore.cpp:
(WebCore::TextureMapperTiledBackingStore::paintToTextureMapper):
* platform/graphics/texmap/TextureMapperTiledBackingStore.h:
(TextureMapperTiledBackingStore):
* platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp:
(WebCore::CoordinatedBackingStore::paintTilesToTextureMapper):
(WebCore::CoordinatedBackingStore::paintToTextureMapper):
* platform/graphics/texmap/coordinated/CoordinatedBackingStore.h:
(CoordinatedBackingStore):
        Removed the "mask" parameter from TextureMapperPlatformLayer and overrides, since
        we no longer paint the contents and the mask in the same pass.

* platform/graphics/texmap/TextureMapper.cpp:
(WebCore::TextureMapper::TextureMapper):
* platform/graphics/texmap/TextureMapper.h:
(WebCore::TextureMapper::setMaskMode):
(TextureMapper):
(WebCore::TextureMapper::isInMaskMode):
* platform/graphics/texmap/TextureMapperGL.cpp:
(WebCore::TextureMapperGL::drawNumber):
(WebCore::TextureMapperGL::drawTexture):
(WebCore::TextureMapperGL::draw):
(WebCore):
(WebCore::TextureMapperGL::drawTexturedQuadWithProgram):
(WebCore::TextureMapperGL::drawFiltered):
* platform/graphics/texmap/TextureMapperGL.h:
(TextureMapperGL):
* platform/graphics/texmap/TextureMapperImageBuffer.cpp:
(WebCore::TextureMapperImageBuffer::drawTexture):
(WebCore::TextureMapperImageBuffer::drawSolidColor):
* platform/graphics/texmap/TextureMapperImageBuffer.h:
(TextureMapperImageBuffer):
        Instead of painting the mask together with the texture/color, paint the mask
        by drawing with DestinationIn to an existing surface.

* platform/graphics/texmap/TextureMapperLayer.cpp:
(TextureMapperPaintOptions):
(WebCore::TextureMapperLayer::paintSelf):
(WebCore::TextureMapperLayer::shouldBlend):
(WebCore::TextureMapperLayer::paintSelfAndChildrenWithReplica):
(WebCore::TextureMapperLayer::replicaTransform):
(WebCore):
(WebCore::applyFilters):
(WebCore::resolveOverlaps):
(WebCore::TextureMapperLayer::computeOverlapRegions):
(WebCore::TextureMapperLayer::paintUsingOverlapRegions):
(WebCore::TextureMapperLayer::applyMask):
(WebCore::TextureMapperLayer::paintIntoSurface):
(WebCore::commitSurface):
(WebCore::TextureMapperLayer::paintWithIntermediateSurface):
(WebCore::TextureMapperLayer::paintRecursive):
* platform/graphics/texmap/TextureMapperLayer.h:
(WebCore):
(TextureMapperLayer):
(WebCore::TextureMapperLayer::hasFilters):
* platform/graphics/texmap/TextureMapperShaderProgram.cpp:
(WebCore):
(WebCore::TextureMapperShaderProgram::create):
* platform/graphics/texmap/TextureMapperShaderProgram.h:

LayoutTests:

Added a few ref-tests for correct overlap blending in accelearated compositing mode.
Skipping the new reflection test on Mac/Chromium since it's not rendered
properly on those platforms.

* compositing/overlap-blending/children-opacity-huge-expected.html: Added.
* compositing/overlap-blending/children-opacity-huge.html: Added.
* compositing/overlap-blending/children-opacity-no-overlap-expected.html: Added.
* compositing/overlap-blending/children-opacity-no-overlap.html: Added.
* compositing/overlap-blending/reflection-opacity-huge-expected.html: Added.
* compositing/overlap-blending/reflection-opacity-huge.html: Added.

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

42 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/overlap-blending/children-opacity-huge-expected.html [new file with mode: 0644]
LayoutTests/compositing/overlap-blending/children-opacity-huge.html [new file with mode: 0644]
LayoutTests/compositing/overlap-blending/children-opacity-no-overlap-expected.html [new file with mode: 0644]
LayoutTests/compositing/overlap-blending/children-opacity-no-overlap.html [new file with mode: 0644]
LayoutTests/compositing/overlap-blending/reflection-opacity-huge-expected.html [new file with mode: 0644]
LayoutTests/compositing/overlap-blending/reflection-opacity-huge.html [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/cairo/GraphicsContext3DPrivate.cpp
Source/WebCore/platform/graphics/cairo/GraphicsContext3DPrivate.h
Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.cpp
Source/WebCore/platform/graphics/efl/GraphicsContext3DPrivate.h
Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp
Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h
Source/WebCore/platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp
Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
Source/WebCore/platform/graphics/surfaces/win/GraphicsSurfaceWin.cpp
Source/WebCore/platform/graphics/texmap/TextureMapper.cpp
Source/WebCore/platform/graphics/texmap/TextureMapper.h
Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h
Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperGL.h
Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h
Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h
Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h
Source/WebCore/platform/graphics/texmap/TextureMapperSurfaceBackingStore.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperSurfaceBackingStore.h
Source/WebCore/platform/graphics/texmap/TextureMapperTile.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperTile.h
Source/WebCore/platform/graphics/texmap/TextureMapperTiledBackingStore.cpp
Source/WebCore/platform/graphics/texmap/TextureMapperTiledBackingStore.h
Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp
Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStore.h

index e91de82..aa19d6e 100644 (file)
@@ -1,3 +1,21 @@
+2013-02-27  No'am Rosenthal  <noam@webkit.org>
+
+        [Texmap] TextureMapper is too eager to use intermediate surfaces
+        https://bugs.webkit.org/show_bug.cgi?id=110762
+
+        Reviewed by Allan Sandfeld Jensen.
+
+        Added a few ref-tests for correct overlap blending in accelearated compositing mode. 
+        Skipping the new reflection test on Mac/Chromium since it's not rendered
+        properly on those platforms.
+
+        * compositing/overlap-blending/children-opacity-huge-expected.html: Added.
+        * compositing/overlap-blending/children-opacity-huge.html: Added.
+        * compositing/overlap-blending/children-opacity-no-overlap-expected.html: Added.
+        * compositing/overlap-blending/children-opacity-no-overlap.html: Added.
+        * compositing/overlap-blending/reflection-opacity-huge-expected.html: Added.
+        * compositing/overlap-blending/reflection-opacity-huge.html: Added.
+
 2013-02-27  Zan Dobersek  <zdobersek@igalia.com>
 
         Unreviewed GTK gardening.
diff --git a/LayoutTests/compositing/overlap-blending/children-opacity-huge-expected.html b/LayoutTests/compositing/overlap-blending/children-opacity-huge-expected.html
new file mode 100644 (file)
index 0000000..c9905e9
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <style type="text/css" media="screen">
+      
+      div {
+        -webkit-box-sizing: border-box;
+      }
+      .solid {
+        position: absolute;
+        width: 2150px;
+        height: 200px;
+        background-color: green;
+      }
+
+      .opacity { opacity: .5; }
+      .a { top: 0px; left: 0px;}
+      .b { top: 100px; left: 0px;}
+      
+      .composited {
+        -webkit-transform: translateZ(0);
+      }
+      * { margin: 0; padding: 0; }
+
+    </style>
+  </head>
+    <div class="opacity">
+    <div class="solid a">1</div>
+    <div class="solid b">2</div>
+  </div>
+
+</html>
diff --git a/LayoutTests/compositing/overlap-blending/children-opacity-huge.html b/LayoutTests/compositing/overlap-blending/children-opacity-huge.html
new file mode 100644 (file)
index 0000000..d71b064
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <style type="text/css" media="screen">
+      
+      div {
+        -webkit-box-sizing: border-box;
+      }
+      .solid {
+        position: absolute;
+        width: 2150px;
+        height: 200px;
+        background-color: green;
+      }
+
+      .opacity { opacity: .5; }
+      .a { top: 0px; left: 0px;}
+      .b { top: 100px; left: 0px;}
+      
+      .composited {
+        -webkit-transform: translateZ(0);
+      }
+
+      * { margin: 0; padding: 0; }
+    </style>
+  </head>
+    <div class="opacity composited">
+    <div class="solid a composited">1</div>
+    <div class="solid b composited">2</div>
+  </div>
+
+</html>
diff --git a/LayoutTests/compositing/overlap-blending/children-opacity-no-overlap-expected.html b/LayoutTests/compositing/overlap-blending/children-opacity-no-overlap-expected.html
new file mode 100644 (file)
index 0000000..f9bd5f1
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <style type="text/css" media="screen">
+      
+      div {
+        -webkit-box-sizing: border-box;
+      }
+      .solid {
+        position: absolute;
+        width: 100px;
+        height: 100px;
+        background-color: green;
+      }
+
+      .opacity { opacity: .5; }
+      .a { top: 0px; left: 0px;}
+      .b { top: 200px; left: 200px;}
+      .c { top: 200px; left: 0px;}
+      .d { top: 0px; left: 200px;}
+      * { margin: 0; padding: 0; }
+      .composited {
+        -webkit-transform: translateZ(0);
+      }
+
+    </style>
+  </head>
+    <div class="opacity">
+      <div class="solid a">1</div>
+      <div class="solid b">2</div>
+      <div class="solid c">3</div>
+      <div class="solid d"></div>
+    </div>
+
+</html>
diff --git a/LayoutTests/compositing/overlap-blending/children-opacity-no-overlap.html b/LayoutTests/compositing/overlap-blending/children-opacity-no-overlap.html
new file mode 100644 (file)
index 0000000..731840a
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <style type="text/css" media="screen">
+      
+      div {
+        -webkit-box-sizing: border-box;
+      }
+      .solid {
+        position: absolute;
+        width: 100px;
+        height: 100px;
+        background-color: green;
+      }
+
+      .opacity { opacity: .5; }
+      .a { top: 0px; left: 0px;}
+      .b { top: 200px; left: 200px;}
+      .c { top: 200px; left: 0px;}
+      .d { top: 0px; left: 200px;}
+      
+      .composited {
+        -webkit-transform: translateZ(0);
+      }
+      * { margin: 0; padding: 0; }
+
+    </style>
+  </head>
+    <div class="composited opacity">
+      <div class="solid composited a">1</div>
+      <div class="solid composited b">2</div>
+      <div class="solid composited c">3</div>
+      <div class="solid composited d"></div>
+    </div>
+
+</html>
diff --git a/LayoutTests/compositing/overlap-blending/reflection-opacity-huge-expected.html b/LayoutTests/compositing/overlap-blending/reflection-opacity-huge-expected.html
new file mode 100644 (file)
index 0000000..149b14c
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <style type="text/css" media="screen">
+      .reflected {
+        position: relative;
+        width: 2150px;
+        height: 200px;
+        background-color: green;
+        opacity: 0.5;
+        -webkit-box-reflect: below -50px;
+      }
+      
+      * { margin: 0; padding: 0; }
+
+    </style>
+  </head>
+  
+  <p>Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and reflection should not be visible.</p>
+  <div class="reflected">1
+  </div>
+
+</html>
diff --git a/LayoutTests/compositing/overlap-blending/reflection-opacity-huge.html b/LayoutTests/compositing/overlap-blending/reflection-opacity-huge.html
new file mode 100644 (file)
index 0000000..1781794
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <style type="text/css" media="screen">
+      .reflected {
+        position: relative;
+        width: 2150px;
+        height: 200px;
+        background-color: green;
+        opacity: 0.5;
+        -webkit-box-reflect: below -50px;
+      }
+      
+      .composited { -webkit-transform: translateZ(0);}
+      * { margin: 0; padding: 0; }
+
+    </style>
+  </head>
+  
+  <p>Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and reflection should not be visible.</p>
+  <div class="reflected composited">1
+  </div>
+
+</html>
index ccfeb5b..68b428e 100644 (file)
@@ -3805,6 +3805,9 @@ webkit.org/b/94353 platform/chromium/virtual/softwarecompositing/overflow/overfl
 webkit.org/b/94353 compositing/overflow/overflow-overlay-with-touch.html [ Failure ]
 webkit.org/b/94353 platform/chromium/virtual/softwarecompositing/overflow/overflow-overlay-with-touch.html [ Failure ]
 
+webkit.org/b/110871 compositing/overlap-blending/ [ Skip ]
+webkit.org/b/110871 platform/chromium/virtual/softwarecompositing/overlap-blending/ [ Skip ]
+
 webkit.org/b/90488 [ Win ] http/tests/inspector/network-preflight-options.html [ Pass Slow ]
 webkit.org/b/90488 [ Win ] inspector/extensions/extensions-reload.html [ Pass Slow ]
 
index 7d64f43..2040a0a 100644 (file)
@@ -916,6 +916,9 @@ compositing/overflow/textarea-scroll-touch.html
 compositing/overflow/updating-scrolling-content.html
 compositing/overflow/scrolling-without-painting.html
 
+# https://bugs.webkit.org/show_bug.cgi?id=110871
+compositing/overlap-blending/reflection-opacity-huge.html
+
 # https://bugs.webkit.org/show_bug.cgi?id=95027
 fast/block/float/016.html
 
index cea8c5a..c6ce9ad 100644 (file)
@@ -1,3 +1,128 @@
+2013-02-27  No'am Rosenthal  <noam@webkit.org>
+
+        [Texmap] TextureMapper is too eager to use intermediate surfaces
+        https://bugs.webkit.org/show_bug.cgi?id=110762
+
+        Reviewed by Allan Sandfeld Jensen.
+
+        Refactor the way intermediate surfaces are handled in TextureMapperLayer.
+        Beforehand, we would create an intermediate surface whenever there is a chance of overlap, and
+        the intermediate surface would be the largest possible. The result would then be drawn to the
+        target surface with the layer's opacity and mask.
+
+        This would make it so that (1) surfaces are created even when they're not needed, i.e. when there
+        is no actual overlap, and (2) mask wouldn't be applied correctly.
+
+        In this patch the behavior is changed so that the area to be painted is divided to "overlapping"
+        and "non overlapping" regions. The non-overlapping regions are painted directly, while the overlapping
+        regions are tiled to smaller rectangles painted using an intermediate surface.
+        Masks are applied to those intermediate surfaces based on the transform of the actual mask, not drawn
+        together with the content texture like before.
+
+        This optimizes for the more common case of opacity animations on a large tree, while making the quite
+        rare case of composited masks slightly less optimized but always correct.
+
+        Tests: compositing/overlap-blending/children-opacity-huge.html
+               compositing/overlap-blending/reflection-opacity-huge.html
+               compositing/overlap-blending/children-opacity-no-overlap.html
+
+        * platform/graphics/cairo/GraphicsContext3DPrivate.cpp:
+        (WebCore::GraphicsContext3DPrivate::paintToTextureMapper):
+        * platform/graphics/cairo/GraphicsContext3DPrivate.h:
+        (GraphicsContext3DPrivate):
+        * platform/graphics/efl/GraphicsContext3DPrivate.cpp:
+        (WebCore::GraphicsContext3DPrivate::paintToTextureMapper):
+        * platform/graphics/efl/GraphicsContext3DPrivate.h:
+        (GraphicsContext3DPrivate):
+        * platform/graphics/qt/GraphicsContext3DQt.cpp:
+        (GraphicsContext3DPrivate):
+        (WebCore::GraphicsContext3DPrivate::paintToTextureMapper):
+        * platform/graphics/qt/MediaPlayerPrivateQt.cpp:
+        (WebCore::MediaPlayerPrivateQt::paintToTextureMapper):
+        * platform/graphics/qt/MediaPlayerPrivateQt.h:
+        (MediaPlayerPrivateQt):
+        * platform/graphics/surfaces/GraphicsSurface.cpp:
+        (WebCore::GraphicsSurface::paintToTextureMapper):
+        * platform/graphics/surfaces/GraphicsSurface.h:
+        (GraphicsSurface):
+        * platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp:
+        (WebCore::GraphicsSurface::platformPaintToTextureMapper):
+        * platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp:
+        (WebCore::GraphicsSurface::platformPaintToTextureMapper):
+        * platform/graphics/surfaces/win/GraphicsSurfaceWin.cpp:
+        (WebCore::GraphicsSurface::platformPaintToTextureMapper):
+        * platform/graphics/texmap/TextureMapperBackingStore.h:
+        (TextureMapperBackingStore):
+        * platform/graphics/texmap/TextureMapperPlatformLayer.h:
+        (TextureMapperPlatformLayer):
+        * platform/graphics/texmap/TextureMapperSurfaceBackingStore.cpp:
+        (WebCore::TextureMapperSurfaceBackingStore::paintToTextureMapper):
+        * platform/graphics/texmap/TextureMapperSurfaceBackingStore.h:
+        (TextureMapperSurfaceBackingStore):
+        * platform/graphics/texmap/TextureMapperTile.cpp:
+        (WebCore::TextureMapperTile::paint):
+        * platform/graphics/texmap/TextureMapperTile.h:
+        (TextureMapperTile):
+        * platform/graphics/texmap/TextureMapperTiledBackingStore.cpp:
+        (WebCore::TextureMapperTiledBackingStore::paintToTextureMapper):
+        * platform/graphics/texmap/TextureMapperTiledBackingStore.h:
+        (TextureMapperTiledBackingStore):
+        * platform/graphics/texmap/coordinated/CoordinatedBackingStore.cpp:
+        (WebCore::CoordinatedBackingStore::paintTilesToTextureMapper):
+        (WebCore::CoordinatedBackingStore::paintToTextureMapper):
+        * platform/graphics/texmap/coordinated/CoordinatedBackingStore.h:
+        (CoordinatedBackingStore):
+                Removed the "mask" parameter from TextureMapperPlatformLayer and overrides, since
+                we no longer paint the contents and the mask in the same pass.
+
+        * platform/graphics/texmap/TextureMapper.cpp:
+        (WebCore::TextureMapper::TextureMapper):
+        * platform/graphics/texmap/TextureMapper.h:
+        (WebCore::TextureMapper::setMaskMode):
+        (TextureMapper):
+        (WebCore::TextureMapper::isInMaskMode):
+        * platform/graphics/texmap/TextureMapperGL.cpp:
+        (WebCore::TextureMapperGL::drawNumber):
+        (WebCore::TextureMapperGL::drawTexture):
+        (WebCore::TextureMapperGL::draw):
+        (WebCore):
+        (WebCore::TextureMapperGL::drawTexturedQuadWithProgram):
+        (WebCore::TextureMapperGL::drawFiltered):
+        * platform/graphics/texmap/TextureMapperGL.h:
+        (TextureMapperGL):
+        * platform/graphics/texmap/TextureMapperImageBuffer.cpp:
+        (WebCore::TextureMapperImageBuffer::drawTexture):
+        (WebCore::TextureMapperImageBuffer::drawSolidColor):
+        * platform/graphics/texmap/TextureMapperImageBuffer.h:
+        (TextureMapperImageBuffer):
+                Instead of painting the mask together with the texture/color, paint the mask
+                by drawing with DestinationIn to an existing surface.
+
+        * platform/graphics/texmap/TextureMapperLayer.cpp:
+        (TextureMapperPaintOptions):
+        (WebCore::TextureMapperLayer::paintSelf):
+        (WebCore::TextureMapperLayer::shouldBlend):
+        (WebCore::TextureMapperLayer::paintSelfAndChildrenWithReplica):
+        (WebCore::TextureMapperLayer::replicaTransform):
+        (WebCore):
+        (WebCore::applyFilters):
+        (WebCore::resolveOverlaps):
+        (WebCore::TextureMapperLayer::computeOverlapRegions):
+        (WebCore::TextureMapperLayer::paintUsingOverlapRegions):
+        (WebCore::TextureMapperLayer::applyMask):
+        (WebCore::TextureMapperLayer::paintIntoSurface):
+        (WebCore::commitSurface):
+        (WebCore::TextureMapperLayer::paintWithIntermediateSurface):
+        (WebCore::TextureMapperLayer::paintRecursive):
+        * platform/graphics/texmap/TextureMapperLayer.h:
+        (WebCore):
+        (TextureMapperLayer):
+        (WebCore::TextureMapperLayer::hasFilters):
+        * platform/graphics/texmap/TextureMapperShaderProgram.cpp:
+        (WebCore):
+        (WebCore::TextureMapperShaderProgram::create):
+        * platform/graphics/texmap/TextureMapperShaderProgram.h:
+
 2013-02-27  Alexander Pavlov  <apavlov@chromium.org>
 
         Web Inspector: [REGRESSION] [Audits] Disabled "Run" button styling is the same as the enabled one
index cd0e09b..df0b262 100644 (file)
@@ -78,7 +78,7 @@ PlatformGraphicsContext3D GraphicsContext3DPrivate::platformContext()
 }
 
 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
-void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, BitmapTexture* mask)
+void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
 {
     if (!m_glContext)
         return;
@@ -142,7 +142,7 @@ void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper
     TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper);
     TextureMapperGL::Flags flags = TextureMapperGL::ShouldFlipTexture | (m_context->m_attrs.alpha ? TextureMapperGL::ShouldBlend : 0);
     IntSize textureSize(m_context->m_currentWidth, m_context->m_currentHeight);
-    texmapGL->drawTexture(m_context->m_texture, flags, textureSize, targetRect, matrix, opacity, mask);
+    texmapGL->drawTexture(m_context->m_texture, flags, textureSize, targetRect, matrix, opacity);
 #endif // USE(ACCELERATED_COMPOSITING_GL)
 }
 #endif // USE(ACCELERATED_COMPOSITING)
index d0dd23f..42eb6c2 100644 (file)
@@ -44,7 +44,7 @@ public:
     GraphicsContext3D::RenderStyle renderStyle() { return m_renderStyle; }
 
 #if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity, BitmapTexture* mask);
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity);
 #endif
 
 private:
index c1935ca..1d150e3 100644 (file)
@@ -197,7 +197,7 @@ bool GraphicsContext3DPrivate::prepareBuffer() const
 }
 
 #if USE(TEXTURE_MAPPER_GL)
-void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper*, const FloatRect& /* target */, const TransformationMatrix&, float /* opacity */, BitmapTexture* /* mask */)
+void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper*, const FloatRect& /* target */, const TransformationMatrix&, float /* opacity */)
 {
     notImplemented();
 }
index b30096a..8f0eb3c 100644 (file)
@@ -48,7 +48,7 @@ public:
     PlatformGraphicsContext3D platformGraphicsContext3D() const;
     void setContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback>);
 #if USE(TEXTURE_MAPPER_GL)
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*) OVERRIDE;
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float) OVERRIDE;
 #endif
 #if USE(GRAPHICS_SURFACE)
     virtual IntSize platformLayerSize() const OVERRIDE;
index 66bdeae..8d5b81d 100644 (file)
@@ -66,7 +66,7 @@ public:
     ~GraphicsContext3DPrivate();
 
 #if USE(ACCELERATED_COMPOSITING)
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity, BitmapTexture* mask);
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& target, const TransformationMatrix&, float opacity);
 #endif
 #if USE(GRAPHICS_SURFACE)
     virtual IntSize platformLayerSize() const;
@@ -209,7 +209,7 @@ static inline quint32 swapBgrToRgb(quint32 pixel)
 }
 
 #if USE(ACCELERATED_COMPOSITING)
-void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, BitmapTexture* mask)
+void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
 {
     m_context->markLayerComposited();
     blitMultisampleFramebufferAndRestoreContext();
@@ -231,7 +231,7 @@ void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper
         currentContext->makeCurrent(currentSurface);
 
         TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper);
-        m_graphicsSurface->paintToTextureMapper(texmapGL, targetRect, matrix, opacity, mask);
+        m_graphicsSurface->paintToTextureMapper(texmapGL, targetRect, matrix, opacity);
 #endif
         return;
     }
index e083e29..1f969b5 100644 (file)
@@ -645,7 +645,7 @@ void MediaPlayerPrivateQt::paintCurrentFrameInContext(GraphicsContext* context,
 }
 
 #if USE(ACCELERATED_COMPOSITING)
-void MediaPlayerPrivateQt::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, BitmapTexture*)
+void MediaPlayerPrivateQt::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity)
 {
 }
 #endif
index 8e31c9d..e74cdcd 100644 (file)
@@ -109,7 +109,7 @@ public:
     virtual void acceleratedRenderingStateChanged() { }
     // Const-casting here is safe, since all of TextureMapperPlatformLayer's functions are const.g
     virtual PlatformLayer* platformLayer() const { return 0; }
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity, BitmapTexture* mask);
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity);
 #endif
 
     virtual PlatformMedia platformMedia() const;
index baefa8a..2a7a4b2 100644 (file)
@@ -63,9 +63,9 @@ void GraphicsSurface::copyFromTexture(uint32_t texture, const IntRect& sourceRec
     platformCopyFromTexture(texture, sourceRect);
 }
 
-void GraphicsSurface::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+void GraphicsSurface::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
 {
-    platformPaintToTextureMapper(textureMapper, targetRect, transform, opacity, mask);
+    platformPaintToTextureMapper(textureMapper, targetRect, transform, opacity);
 }
 
 uint32_t GraphicsSurface::frontBuffer()
index da49369..731af2b 100644 (file)
@@ -79,7 +79,7 @@ public:
     static PassRefPtr<GraphicsSurface> create(const IntSize&, Flags, const GraphicsSurfaceToken&);
     void copyToGLTexture(uint32_t target, uint32_t texture, const IntRect& targetRect, const IntPoint& sourceOffset);
     void copyFromTexture(uint32_t texture, const IntRect& sourceRect);
-    void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity, BitmapTexture* mask);
+    void paintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity);
     uint32_t frontBuffer();
     uint32_t swapBuffers();
     GraphicsSurfaceToken exportToken();
@@ -99,7 +99,7 @@ protected:
     void platformUnlock();
     void platformCopyToGLTexture(uint32_t target, uint32_t texture, const IntRect&, const IntPoint&);
     void platformCopyFromTexture(uint32_t texture, const IntRect& sourceRect);
-    void platformPaintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity, BitmapTexture* mask);
+    void platformPaintToTextureMapper(TextureMapper*, const FloatRect& targetRect, const TransformationMatrix&, float opacity);
     uint32_t platformFrontBuffer() const;
     uint32_t platformSwapBuffers();
     IntSize platformSize() const;
index 4391b59..23f8afb 100644 (file)
@@ -385,7 +385,7 @@ void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& s
     m_private->copyFromTexture(texture, sourceRect);
 }
 
-void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
 {
     IntSize size = m_private->size();
     if (size.isEmpty())
@@ -397,7 +397,7 @@ void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper,
     FloatRect rectOnContents(FloatPoint::zero(), size);
     TransformationMatrix adjustedTransform = transform;
     adjustedTransform.multiply(TransformationMatrix::rectToRect(rectOnContents, targetRect));
-    static_cast<TextureMapperGL*>(textureMapper)->drawTexture(texture, m_private->flags(), size, rectOnContents, adjustedTransform, opacity, mask);
+    static_cast<TextureMapperGL*>(textureMapper)->drawTexture(texture, m_private->flags(), size, rectOnContents, adjustedTransform, opacity);
 }
 
 uint32_t GraphicsSurface::platformFrontBuffer() const
index bf62fb1..c4d2d54 100644 (file)
@@ -333,13 +333,13 @@ void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& s
     m_private->copyFromTexture(texture, sourceRect);
 }
 
-void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
 {
     IntSize size = m_private->size();
     FloatRect rectOnContents(FloatPoint::zero(), size);
     TransformationMatrix adjustedTransform = transform;
     adjustedTransform.multiply(TransformationMatrix::rectToRect(rectOnContents, targetRect));
-    static_cast<TextureMapperGL*>(textureMapper)->drawTexture(m_private->frontBufferTextureID(), TextureMapperGL::ShouldBlend | TextureMapperGL::ShouldUseARBTextureRect, size, rectOnContents, adjustedTransform, opacity, mask);
+    static_cast<TextureMapperGL*>(textureMapper)->drawTexture(m_private->frontBufferTextureID(), TextureMapperGL::ShouldBlend | TextureMapperGL::ShouldUseARBTextureRect, size, rectOnContents, adjustedTransform, opacity);
 }
 
 uint32_t GraphicsSurface::platformFrontBuffer() const
index 9509f09..06f427c 100644 (file)
@@ -421,7 +421,7 @@ void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& s
     m_private->copyFromTexture(texture, sourceRect);
 }
 
-void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
 {
     IntSize size = m_private->size();
     FloatRect rectOnContents(FloatPoint::zero(), size);
index 37f7154..1b54ea3 100644 (file)
@@ -141,6 +141,7 @@ TextureMapper::TextureMapper(AccelerationMode accelerationMode)
     , m_textDrawingMode(TextModeFill)
     , m_texturePool(adoptPtr(new BitmapTexturePool()))
     , m_accelerationMode(accelerationMode)
+    , m_isMaskMode(false)
 { }
 
 TextureMapper::~TextureMapper()
index adeaf3e..71200ec 100644 (file)
@@ -132,7 +132,7 @@ public:
     virtual void drawBorder(const Color&, float borderWidth, const FloatRect&, const TransformationMatrix&) = 0;
     virtual void drawNumber(int number, const Color&, const FloatPoint&, const TransformationMatrix&) = 0;
 
-    virtual void drawTexture(const BitmapTexture&, const FloatRect& target, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0f, const BitmapTexture* maskTexture = 0, unsigned exposedEdges = AllEdges) = 0;
+    virtual void drawTexture(const BitmapTexture&, const FloatRect& target, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0f, unsigned exposedEdges = AllEdges) = 0;
     virtual void drawSolidColor(const FloatRect&, const TransformationMatrix&, const Color&) = 0;
 
     // makes a surface the target for the following drawTexture calls.
@@ -153,6 +153,8 @@ public:
     virtual void beginPainting(PaintFlags = 0) { }
     virtual void endPainting() { }
 
+    void setMaskMode(bool m) { m_isMaskMode = m; }
+
     virtual IntSize maxTextureSize() const = 0;
 
     virtual PassRefPtr<BitmapTexture> acquireTextureFromPool(const IntSize&);
@@ -166,6 +168,8 @@ protected:
 
     GraphicsContext* m_context;
 
+    bool isInMaskMode() const { return m_isMaskMode; }
+
 private:
 #if USE(TEXTURE_MAPPER_GL)
     static PassOwnPtr<TextureMapper> platformCreateAccelerated();
@@ -179,6 +183,7 @@ private:
     TextDrawingModeFlags m_textDrawingMode;
     OwnPtr<BitmapTexturePool> m_texturePool;
     AccelerationMode m_accelerationMode;
+    bool m_isMaskMode;
 };
 
 }
index 6bfb3f1..c600aa2 100644 (file)
@@ -39,7 +39,7 @@ class GraphicsLayer;
 class TextureMapperBackingStore : public TextureMapperPlatformLayer, public RefCounted<TextureMapperBackingStore> {
 public:
     virtual PassRefPtr<BitmapTexture> texture() const = 0;
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*) = 0;
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float) = 0;
     virtual void drawRepaintCounter(TextureMapper*, int /* repaintCount */, const Color&, const FloatRect&, const TransformationMatrix&) { }
     virtual ~TextureMapperBackingStore() { }
 
index 04bfb82..19974f9 100644 (file)
@@ -355,7 +355,7 @@ void TextureMapperGL::drawNumber(int number, const Color& color, const FloatPoin
     RefPtr<BitmapTexture> texture = acquireTextureFromPool(size);
     const uchar* bits = image.bits();
     static_cast<BitmapTextureGL*>(texture.get())->updateContentsNoSwizzle(bits, sourceRect, IntPoint::zero(), image.bytesPerLine());
-    drawTexture(*texture, targetRect, modelViewMatrix, 1.0f, 0, AllEdges);
+    drawTexture(*texture, targetRect, modelViewMatrix, 1.0f, AllEdges);
 
 #elif USE(CAIRO)
     CString counterString = String::number(number).ascii();
@@ -386,7 +386,7 @@ void TextureMapperGL::drawNumber(int number, const Color& color, const FloatPoin
     const unsigned char* bits = cairo_image_surface_get_data(surface);
     int stride = cairo_image_surface_get_stride(surface);
     static_cast<BitmapTextureGL*>(texture.get())->updateContentsNoSwizzle(bits, sourceRect, IntPoint::zero(), stride);
-    drawTexture(*texture, targetRect, modelViewMatrix, 1.0f, 0, AllEdges);
+    drawTexture(*texture, targetRect, modelViewMatrix, 1.0f, AllEdges);
 
     cairo_surface_destroy(surface);
     cairo_destroy(cr);
@@ -400,7 +400,7 @@ void TextureMapperGL::drawNumber(int number, const Color& color, const FloatPoin
 #endif
 }
 
-void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* mask, unsigned exposedEdges)
+void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, unsigned exposedEdges)
 {
     if (!texture.isValid())
         return;
@@ -409,20 +409,17 @@ void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect&
         return;
 
     const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture);
-    drawTexture(textureGL.id(), textureGL.isOpaque() ? 0 : ShouldBlend, textureGL.size(), targetRect, matrix, opacity, mask, exposedEdges);
+    drawTexture(textureGL.id(), textureGL.isOpaque() ? 0 : ShouldBlend, textureGL.size(), targetRect, matrix, opacity, exposedEdges);
 }
 
-void TextureMapperGL::drawTexture(Platform3DObject texture, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges)
+void TextureMapperGL::drawTexture(Platform3DObject texture, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges)
 {
     bool useRect = flags & ShouldUseARBTextureRect;
-    bool masked = !!maskTexture;
     bool useAntialiasing = m_enableEdgeDistanceAntialiasing
         && exposedEdges == AllEdges
         && !modelViewMatrix.mapQuad(targetRect).isRectilinear();
 
     TextureMapperShaderProgram::Options options = TextureMapperShaderProgram::Texture;
-    if (masked)
-        options |= TextureMapperShaderProgram::Mask;
     if (useRect)
         options |= TextureMapperShaderProgram::Rect;
     if (opacity < 1)
@@ -432,12 +429,12 @@ void TextureMapperGL::drawTexture(Platform3DObject texture, Flags flags, const I
         flags |= ShouldAntialias;
     }
 
-    if (masked || useAntialiasing || opacity < 1)
+    if (useAntialiasing || opacity < 1)
         flags |= ShouldBlend;
 
     RefPtr<TextureMapperShaderProgram> program;
     program = data().sharedGLData().getShaderProgram(options);
-    drawTexturedQuadWithProgram(program.get(), texture, flags, textureSize, targetRect, modelViewMatrix, opacity, maskTexture);
+    drawTexturedQuadWithProgram(program.get(), texture, flags, textureSize, targetRect, modelViewMatrix, opacity);
 }
 
 void TextureMapperGL::drawSolidColor(const FloatRect& rect, const TransformationMatrix& matrix, const Color& color)
@@ -510,11 +507,16 @@ void TextureMapperGL::draw(const FloatRect& rect, const TransformationMatrix& mo
     shaderProgram->setMatrix(shaderProgram->modelViewMatrixLocation(), matrix);
     shaderProgram->setMatrix(shaderProgram->projectionMatrixLocation(), data().projectionMatrix);
 
-    if (flags & ShouldBlend) {
-        m_context3D->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+    if (isInMaskMode()) {
+        m_context3D->blendFunc(GraphicsContext3D::ZERO, GraphicsContext3D::SRC_ALPHA);
         m_context3D->enable(GraphicsContext3D::BLEND);
-    } else
-        m_context3D->disable(GraphicsContext3D::BLEND);
+    } else {
+        if (flags & ShouldBlend) {
+            m_context3D->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+            m_context3D->enable(GraphicsContext3D::BLEND);
+        } else
+            m_context3D->disable(GraphicsContext3D::BLEND);
+    }
 
     if (flags & ShouldAntialias)
         drawEdgeTriangles(shaderProgram);
@@ -522,8 +524,11 @@ void TextureMapperGL::draw(const FloatRect& rect, const TransformationMatrix& mo
         drawUnitRect(shaderProgram, drawingMode);
 
     m_context3D->disableVertexAttribArray(shaderProgram->vertexLocation());
+    m_context3D->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA);
+    m_context3D->enable(GraphicsContext3D::BLEND);
 }
-void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* program, uint32_t texture, Flags flags, const IntSize& size, const FloatRect& rect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture)
+
+void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* program, uint32_t texture, Flags flags, const IntSize& size, const FloatRect& rect, const TransformationMatrix& modelViewMatrix, float opacity)
 {
     m_context3D->useProgram(program->programID());
     m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
@@ -539,19 +544,10 @@ void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* pr
     if (flags & ShouldFlipTexture)
         patternTransform.translate(0, -1);
 
-
     program->setMatrix(program->textureSpaceMatrixLocation(), patternTransform);
     m_context3D->uniform1f(program->opacityLocation(), opacity);
 
-    if (maskTexture && maskTexture->isValid()) {
-        const BitmapTextureGL* maskTextureGL = static_cast<const BitmapTextureGL*>(maskTexture);
-        m_context3D->activeTexture(GraphicsContext3D::TEXTURE1);
-        m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, maskTextureGL->id());
-        m_context3D->uniform1i(program->maskLocation(), 1);
-        m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
-    }
-
-    if (opacity < 1 || maskTexture)
+    if (opacity < 1)
         flags |= ShouldBlend;
 
     draw(rect, modelViewMatrix, program, GraphicsContext3D::TRIANGLE_FAN, flags);
@@ -949,7 +945,7 @@ void TextureMapperGL::drawFiltered(const BitmapTexture& sampler, const BitmapTex
 
     prepareFilterProgram(program.get(), filter, pass, sampler.contentSize(), static_cast<const BitmapTextureGL&>(contentTexture).id());
     FloatRect targetRect(IntPoint::zero(), sampler.contentSize());
-    drawTexturedQuadWithProgram(program.get(), static_cast<const BitmapTextureGL&>(sampler).id(), 0, IntSize(1, 1), targetRect, TransformationMatrix(), 1, 0);
+    drawTexturedQuadWithProgram(program.get(), static_cast<const BitmapTextureGL&>(sampler).id(), 0, IntSize(1, 1), targetRect, TransformationMatrix(), 1);
 }
 
 PassRefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper* textureMapper, const BitmapTexture& contentTexture, const FilterOperations& filters)
index 2a80ed2..3416355 100644 (file)
@@ -54,8 +54,8 @@ public:
     // TextureMapper implementation
     virtual void drawBorder(const Color&, float borderWidth, const FloatRect&, const TransformationMatrix&) OVERRIDE;
     virtual void drawNumber(int number, const Color&, const FloatPoint&, const TransformationMatrix&) OVERRIDE;
-    virtual void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges) OVERRIDE;
-    virtual void drawTexture(Platform3DObject texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges = AllEdges);
+    virtual void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, unsigned exposedEdges) OVERRIDE;
+    virtual void drawTexture(Platform3DObject texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, unsigned exposedEdges = AllEdges);
     virtual void drawSolidColor(const FloatRect&, const TransformationMatrix&, const Color&) OVERRIDE;
 
     virtual void bindSurface(BitmapTexture* surface) OVERRIDE;
@@ -107,7 +107,7 @@ private:
 
     TextureMapperGL();
 
-    void drawTexturedQuadWithProgram(TextureMapperShaderProgram*, uint32_t texture, Flags, const IntSize&, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture);
+    void drawTexturedQuadWithProgram(TextureMapperShaderProgram*, uint32_t texture, Flags, const IntSize&, const FloatRect&, const TransformationMatrix& modelViewMatrix, float opacity);
     void draw(const FloatRect&, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram*, GC3Denum drawingMode, Flags);
 
     void drawUnitRect(TextureMapperShaderProgram*, GC3Denum drawingMode);
index 1e49f9b..52a8487 100644 (file)
@@ -114,7 +114,7 @@ void TextureMapperImageBuffer::beginClip(const TransformationMatrix& matrix, con
 #endif
 }
 
-void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture, unsigned /* exposedEdges */)
+void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, unsigned /* exposedEdges */)
 {
     GraphicsContext* context = currentContext();
     if (!context)
@@ -122,22 +122,8 @@ void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const F
 
     const BitmapTextureImageBuffer& textureImageBuffer = static_cast<const BitmapTextureImageBuffer&>(texture);
     ImageBuffer* image = textureImageBuffer.m_image.get();
-    OwnPtr<ImageBuffer> maskedImage;
-
-    if (maskTexture && maskTexture->isValid()) {
-        const BitmapTextureImageBuffer* mask = static_cast<const BitmapTextureImageBuffer*>(maskTexture);
-        maskedImage = ImageBuffer::create(maskTexture->contentSize());
-        GraphicsContext* maskContext = maskedImage->context();
-        maskContext->drawImageBuffer(image, ColorSpaceDeviceRGB, IntPoint::zero(), CompositeCopy);
-        if (opacity < 1) {
-            maskContext->setAlpha(opacity);
-            opacity = 1;
-        }
-        maskContext->drawImageBuffer(mask->m_image.get(), ColorSpaceDeviceRGB, IntPoint::zero(), CompositeDestinationIn);
-        image = maskedImage.get();
-    }
-
     context->save();
+    context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
     context->setAlpha(opacity);
 #if ENABLE(3D_RENDERING)
     context->concat3DTransform(matrix);
@@ -155,6 +141,7 @@ void TextureMapperImageBuffer::drawSolidColor(const FloatRect& rect, const Trans
         return;
 
     context->save();
+    context->setCompositeOperation(isInMaskMode() ? CompositeDestinationIn : CompositeSourceOver);
 #if ENABLE(3D_RENDERING)
     context->concat3DTransform(matrix);
 #else
index 80e6944..35f2b44 100644 (file)
@@ -55,7 +55,7 @@ public:
     // TextureMapper implementation
     virtual void drawBorder(const Color&, float borderWidth, const FloatRect&, const TransformationMatrix&) OVERRIDE;
     virtual void drawNumber(int number, const Color&, const FloatPoint&, const TransformationMatrix&) OVERRIDE;
-    virtual void drawTexture(const BitmapTexture&, const FloatRect& targetRect, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges) OVERRIDE;
+    virtual void drawTexture(const BitmapTexture&, const FloatRect& targetRect, const TransformationMatrix&, float opacity, unsigned exposedEdges) OVERRIDE;
     virtual void drawSolidColor(const FloatRect&, const TransformationMatrix&, const Color&) OVERRIDE;
     virtual void beginClip(const TransformationMatrix&, const FloatRect&) OVERRIDE;
     virtual void bindSurface(BitmapTexture* surface) OVERRIDE { m_currentSurface = surface;}
index 8a2cc99..10bef26 100644 (file)
@@ -20,6 +20,8 @@
 #include "config.h"
 #include "TextureMapperLayer.h"
 
+#include "Region.h"
+
 #if USE(ACCELERATED_COMPOSITING)
 
 namespace WebCore {
@@ -27,7 +29,6 @@ namespace WebCore {
 class TextureMapperPaintOptions {
 public:
     RefPtr<BitmapTexture> surface;
-    RefPtr<BitmapTexture> mask;
     float opacity;
     TransformationMatrix transform;
     IntSize offset;
@@ -108,8 +109,6 @@ void TextureMapperLayer::paintSelf(const TextureMapperPaintOptions& options)
     transform.multiply(m_currentTransform.combined());
 
     float opacity = options.opacity;
-    RefPtr<BitmapTexture> mask = options.mask;
-
     if (m_state.solidColor.isValid() && !m_state.contentsRect.isEmpty()) {
         options.textureMapper->drawSolidColor(m_state.contentsRect, transform, blendWithOpacity(m_state.solidColor, opacity));
         if (m_state.showDebugBorders)
@@ -120,7 +119,7 @@ void TextureMapperLayer::paintSelf(const TextureMapperPaintOptions& options)
     if (m_backingStore) {
         ASSERT(m_state.drawsContent && m_state.contentsVisible && !m_state.size.isEmpty());
         ASSERT(!layerRect().isEmpty());
-        m_backingStore->paintToTextureMapper(options.textureMapper, layerRect(), transform, opacity, mask.get());
+        m_backingStore->paintToTextureMapper(options.textureMapper, layerRect(), transform, opacity);
         if (m_state.showDebugBorders)
             m_backingStore->drawBorder(options.textureMapper, m_state.debugBorderColor, m_state.debugBorderWidth, layerRect(), transform);
         // Only draw repaint count for the main backing store.
@@ -130,7 +129,7 @@ void TextureMapperLayer::paintSelf(const TextureMapperPaintOptions& options)
 
     if (m_contentsLayer) {
         ASSERT(!layerRect().isEmpty());
-        m_contentsLayer->paintToTextureMapper(options.textureMapper, m_state.contentsRect, transform, opacity, mask.get());
+        m_contentsLayer->paintToTextureMapper(options.textureMapper, m_state.contentsRect, transform, opacity);
         if (m_state.showDebugBorders)
             m_contentsLayer->drawBorder(options.textureMapper, m_state.debugBorderColor, m_state.debugBorderWidth, m_state.contentsRect, transform);
     }
@@ -166,82 +165,16 @@ void TextureMapperLayer::paintSelfAndChildren(const TextureMapperPaintOptions& o
         options.textureMapper->endClip();
 }
 
-IntRect TextureMapperLayer::intermediateSurfaceRect()
-{
-    // FIXME: Add an inverse transform to LayerTransform.
-    return intermediateSurfaceRect(m_currentTransform.combined().inverse());
-}
-
-IntRect TextureMapperLayer::intermediateSurfaceRect(const TransformationMatrix& matrix)
-{
-    IntRect rect;
-    TransformationMatrix localTransform = TransformationMatrix(matrix).multiply(m_currentTransform.combined());
-    rect = enclosingIntRect(localTransform.mapRect(layerRect()));
-    if (!m_state.masksToBounds && !m_state.maskLayer) {
-        for (size_t i = 0; i < m_children.size(); ++i)
-            rect.unite(m_children[i]->intermediateSurfaceRect(matrix));
-    }
-
-#if ENABLE(CSS_FILTERS)
-    if (m_currentFilters.hasOutsets()) {
-        FilterOutsets outsets = m_currentFilters.outsets();
-        IntRect unfilteredTargetRect(rect);
-        rect.move(std::max(0, -outsets.left()), std::max(0, -outsets.top()));
-        rect.expand(outsets.left() + outsets.right(), outsets.top() + outsets.bottom());
-        rect.unite(unfilteredTargetRect);
-    }
-#endif
-
-    if (m_state.replicaLayer)
-        rect.unite(m_state.replicaLayer->intermediateSurfaceRect(matrix));
-
-    return rect;
-}
-
-TextureMapperLayer::ContentsLayerCount TextureMapperLayer::countPotentialLayersWithContents() const
+bool TextureMapperLayer::shouldBlend() const
 {
-    int selfLayersWithContents = (m_state.drawsContent ? 1 : 0) + (m_contentsLayer ? 1 : 0);
-    int potentialLayersWithContents = selfLayersWithContents + m_children.size();
-
-    if (!potentialLayersWithContents)
-        return NoLayersWithContent;
-
-    if (potentialLayersWithContents > 1)
-        return MultipleLayersWithContents;
-
-    if (m_children.isEmpty())
-        return SingleLayerWithContents;
-
-    return m_children.first()->countPotentialLayersWithContents();
-}
+    if (m_state.preserves3D)
+        return false;
 
-bool TextureMapperLayer::shouldPaintToIntermediateSurface() const
-{
 #if ENABLE(CSS_FILTERS)
     if (m_currentFilters.size())
         return true;
 #endif
-    bool hasOpacity = m_currentOpacity < 0.99;
-    bool canHaveMultipleLayersWithContent = countPotentialLayersWithContents() == MultipleLayersWithContents;
-    bool hasReplica = !!m_state.replicaLayer;
-    bool hasMask = !!m_state.maskLayer;
-
-    // We don't use two-pass blending for preserves-3d, that's in sync with Safari.
-    if (m_state.preserves3D)
-        return false;
-
-    // We should use an intermediate surface when blending several items with an ancestor opacity.
-    // Tested by compositing/reflections/reflection-opacity.html
-    if (hasOpacity && (canHaveMultipleLayersWithContent || hasReplica))
-        return true;
-
-    // We should use an intermediate surface with a masked ancestor.
-    // In the case of replicas the mask is applied before replicating.
-    // Tested by compositing/masks/masked-ancestor.html
-    if (hasMask && canHaveMultipleLayersWithContent && !hasReplica)
-        return true;
-
-    return false;
+    return m_currentOpacity < 1 || m_state.maskLayer || (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer);
 }
 
 bool TextureMapperLayer::isVisible() const
@@ -261,11 +194,6 @@ void TextureMapperLayer::paintSelfAndChildrenWithReplica(const TextureMapperPain
 {
     if (m_state.replicaLayer) {
         TextureMapperPaintOptions replicaOptions(options);
-        // We choose either the content's mask or the replica's mask.
-        // FIXME: blend the two if both exist.
-        if (m_state.replicaLayer->m_state.maskLayer)
-            replicaOptions.mask = m_state.replicaLayer->m_state.maskLayer->texture();
-
         replicaOptions.transform
             .multiply(m_state.replicaLayer->m_currentTransform.combined())
             .multiply(m_currentTransform.combined().inverse());
@@ -285,6 +213,11 @@ void TextureMapperLayer::setAnimatedOpacity(float opacity)
     m_currentOpacity = opacity;
 }
 
+TransformationMatrix TextureMapperLayer::replicaTransform()
+{
+    return TransformationMatrix(m_state.replicaLayer->m_currentTransform.combined()).multiply(m_currentTransform.combined().inverse());
+}
+
 #if ENABLE(CSS_FILTERS)
 void TextureMapperLayer::setAnimatedFilters(const FilterOperations& filters)
 {
@@ -307,7 +240,7 @@ static bool shouldKeepContentTexture(const FilterOperations& filters)
     return false;
 }
 
-static PassRefPtr<BitmapTexture> applyFilters(const FilterOperations& filters, TextureMapper* textureMapper, BitmapTexture* source, IntRect& targetRect)
+static PassRefPtr<BitmapTexture> applyFilters(const FilterOperations& filters, TextureMapper* textureMapper, BitmapTexture* source)
 {
     if (!filters.size())
         return source;
@@ -317,51 +250,184 @@ static PassRefPtr<BitmapTexture> applyFilters(const FilterOperations& filters, T
 }
 #endif
 
-void TextureMapperLayer::paintRecursive(const TextureMapperPaintOptions& options)
+static void resolveOverlaps(Region newRegion, Region& overlapRegion, Region& nonOverlapRegion)
 {
-    if (!isVisible())
+    Region newOverlapRegion(newRegion);
+    newOverlapRegion.intersect(nonOverlapRegion);
+    nonOverlapRegion.subtract(newOverlapRegion);
+    overlapRegion.unite(newOverlapRegion);
+    newRegion.subtract(overlapRegion);
+    nonOverlapRegion.unite(newRegion);
+}
+
+void TextureMapperLayer::computeOverlapRegions(Region& overlapRegion, Region& nonOverlapRegion, bool alwaysResolveSelfOverlap)
+{
+    if (!m_state.visible || !m_state.contentsVisible)
         return;
 
-    float opacity = options.opacity * m_currentOpacity;
-    RefPtr<BitmapTexture> maskTexture = m_state.maskLayer ? m_state.maskLayer->texture() : 0;
+    FloatRect boundingRect;
+    if (m_backingStore || m_state.masksToBounds || m_state.maskLayer || hasFilters())
+        boundingRect = layerRect();
+    else if (m_contentsLayer || m_state.solidColor.alpha())
+        boundingRect = m_state.contentsRect;
 
-    TextureMapperPaintOptions paintOptions(options);
-    paintOptions.mask = maskTexture.get();
+#if ENABLE(CSS_FILTERS)
+    if (m_currentFilters.hasOutsets()) {
+        FilterOutsets outsets = m_currentFilters.outsets();
+        IntRect unfilteredTargetRect(boundingRect);
+        boundingRect.move(std::max(0, -outsets.left()), std::max(0, -outsets.top()));
+        boundingRect.expand(outsets.left() + outsets.right(), outsets.top() + outsets.bottom());
+        boundingRect.unite(unfilteredTargetRect);
+    }
+#endif
+
+    TransformationMatrix replicaMatrix;
+    if (m_state.replicaLayer) {
+        replicaMatrix = replicaTransform();
+        boundingRect.unite(replicaMatrix.mapRect(boundingRect));
+    }
 
-    if (!shouldPaintToIntermediateSurface()) {
-        paintOptions.opacity = opacity;
-        paintSelfAndChildrenWithReplica(paintOptions);
+    boundingRect = m_currentTransform.combined().mapRect(boundingRect);
+
+    // Count all masks and filters as overlap layers.
+    if (hasFilters() || m_state.maskLayer || (m_state.replicaLayer && m_state.replicaLayer->m_state.maskLayer)) {
+        Region newOverlapRegion(enclosingIntRect(boundingRect));
+        nonOverlapRegion.subtract(newOverlapRegion);
+        overlapRegion.unite(newOverlapRegion);
         return;
     }
 
-    // Prepare a surface to paint into.
-    // We paint into the surface ignoring the opacity/transform of the current layer.
-    IntRect surfaceRect = intermediateSurfaceRect();
-    RefPtr<BitmapTexture> surface = options.textureMapper->acquireTextureFromPool(surfaceRect.size());
-    paintOptions.surface = surface;
-    options.textureMapper->bindSurface(surface.get());
-    paintOptions.opacity = 1;
+    Region newOverlapRegion;
+    Region newNonOverlapRegion(enclosingIntRect(boundingRect));
+
+    if (!m_state.masksToBounds) {
+        for (size_t i = 0; i < m_children.size(); ++i) {
+            TextureMapperLayer* child = m_children[i];
+            bool alwaysResolveSelfOverlapForChildren = false;
+            child->computeOverlapRegions(newOverlapRegion, newNonOverlapRegion, alwaysResolveSelfOverlapForChildren);
+        }
+    }
+
+    if (m_state.replicaLayer) {
+        newOverlapRegion.unite(replicaMatrix.mapRect(newOverlapRegion.bounds()));
+        Region replicaRegion(replicaMatrix.mapRect(newNonOverlapRegion.bounds()));
+        resolveOverlaps(replicaRegion, newOverlapRegion, newNonOverlapRegion);
+    }
 
-    paintOptions.transform = m_currentTransform.combined().inverse();
-    paintOptions.offset = -IntSize(surfaceRect.x(), surfaceRect.y());
+    if (!alwaysResolveSelfOverlap && shouldBlend()) {
+        newNonOverlapRegion.unite(newOverlapRegion);
+        newOverlapRegion = Region();
+    }
 
-    paintSelfAndChildrenWithReplica(paintOptions);
+    overlapRegion.unite(newOverlapRegion);
+    resolveOverlaps(newNonOverlapRegion, overlapRegion, nonOverlapRegion);
+}
 
-    // If we painted the replica, the mask is already applied so we don't need to paint it again.
-    if (m_state.replicaLayer)
-        maskTexture = 0;
+void TextureMapperLayer::paintUsingOverlapRegions(const TextureMapperPaintOptions& options)
+{
+    Region overlapRegion;
+    Region nonOverlapRegion;
+    computeOverlapRegions(overlapRegion, nonOverlapRegion);
+    if (overlapRegion.isEmpty()) {
+        paintSelfAndChildrenWithReplica(options);
+        return;
+    }
+
+    Vector<IntRect> rects = nonOverlapRegion.rects();
+    for (size_t i = 0; i < rects.size(); ++i) {
+        options.textureMapper->beginClip(TransformationMatrix(), rects[i]);
+        paintSelfAndChildrenWithReplica(options);
+        options.textureMapper->endClip();
+    }
+
+    rects = overlapRegion.rects();
+    IntSize maxTextureSize = options.textureMapper->maxTextureSize();
+    for (size_t i = 0; i < rects.size(); ++i) {
+        IntRect rect = rects[i];
+        for (int x = rect.x(); x < rect.maxX(); x += maxTextureSize.width()) {
+            for (int y = rect.y(); y < rect.maxY(); y += maxTextureSize.height()) {
+                IntRect tileRect(IntPoint(x, y), maxTextureSize);
+                tileRect.intersect(rect);
+                paintWithIntermediateSurface(options, tileRect);
+            }
+        }
+    }
+}
 
+void TextureMapperLayer::applyMask(const TextureMapperPaintOptions& options)
+{
+    options.textureMapper->setMaskMode(true);
+    paintSelf(options);
+    options.textureMapper->setMaskMode(false);
+}
+
+PassRefPtr<BitmapTexture> TextureMapperLayer::paintIntoSurface(const TextureMapperPaintOptions& options, const IntSize& size)
+{
+    RefPtr<BitmapTexture> surface = options.textureMapper->acquireTextureFromPool(size);
+    options.textureMapper->bindSurface(surface.get());
+    paintSelfAndChildren(options);
+    if (m_state.maskLayer)
+        m_state.maskLayer->applyMask(options);
 #if ENABLE(CSS_FILTERS)
-    surface = applyFilters(m_currentFilters, options.textureMapper, surface.get(), surfaceRect);
+    if (!m_currentFilters.isEmpty())
+        surface = applyFilters(m_currentFilters, options.textureMapper, surface.get());
 #endif
+    options.textureMapper->bindSurface(surface.get());
+    return surface;
+}
 
+static PassRefPtr<BitmapTexture> commitSurface(const TextureMapperPaintOptions& options, PassRefPtr<BitmapTexture> surface, const IntRect& rect, float opacity)
+{
     options.textureMapper->bindSurface(options.surface.get());
     TransformationMatrix targetTransform;
     targetTransform.translate(options.offset.width(), options.offset.height());
     targetTransform.multiply(options.transform);
-    targetTransform.multiply(m_currentTransform.combined());
+    options.textureMapper->drawTexture(*surface.get(), rect, targetTransform, opacity);
+    return 0;
+}
+
+void TextureMapperLayer::paintWithIntermediateSurface(const TextureMapperPaintOptions& options, const IntRect& rect)
+{
+    RefPtr<BitmapTexture> replicaSurface;
+    RefPtr<BitmapTexture> mainSurface;
+    TextureMapperPaintOptions paintOptions(options);
+    paintOptions.offset = -IntSize(rect.x(), rect.y());
+    paintOptions.opacity = 1;
+    paintOptions.transform = TransformationMatrix();
+    if (m_state.replicaLayer) {
+        paintOptions.transform = replicaTransform();
+        replicaSurface = paintIntoSurface(paintOptions, rect.size());
+        paintOptions.transform = TransformationMatrix();
+        if (m_state.replicaLayer->m_state.maskLayer)
+            m_state.replicaLayer->m_state.maskLayer->applyMask(paintOptions);
+    }
 
-    options.textureMapper->drawTexture(*surface.get(), surfaceRect, targetTransform, opacity, maskTexture.get());
+    if (replicaSurface && options.opacity == 1)
+        replicaSurface = commitSurface(options, replicaSurface, rect, 1);
+
+    mainSurface = paintIntoSurface(paintOptions, rect.size());
+    if (replicaSurface) {
+        options.textureMapper->bindSurface(replicaSurface.get());
+        options.textureMapper->drawTexture(*mainSurface.get(), FloatRect(FloatPoint::zero(), rect.size()));
+        mainSurface = replicaSurface;
+    }
+
+    commitSurface(options, mainSurface, rect, options.opacity);
+}
+
+void TextureMapperLayer::paintRecursive(const TextureMapperPaintOptions& options)
+{
+    if (!isVisible())
+        return;
+
+    if (!shouldBlend()) {
+        paintSelfAndChildrenWithReplica(options);
+        return;
+    }
+
+    TextureMapperPaintOptions paintOptions(options);
+    paintOptions.opacity = options.opacity * m_currentOpacity;
+    paintUsingOverlapRegions(paintOptions);
 }
 
 TextureMapperLayer::~TextureMapperLayer()
index 61fb827..602b2c3 100644 (file)
@@ -31,6 +31,7 @@
 
 namespace WebCore {
 
+class Region;
 class TextureMapperPaintOptions;
 class TextureMapperPlatformLayer;
 
@@ -73,6 +74,16 @@ public:
 #if ENABLE(CSS_FILTERS)
     void setFilters(const FilterOperations&);
 #endif
+
+    bool hasFilters() const
+    {
+#if ENABLE(CSS_FILTERS)
+        return !m_currentFilters.isEmpty();
+#else
+        return false;
+#endif
+    }
+
     void setDebugVisuals(bool showDebugBorders, const Color& debugBorderColor, float debugBorderWidth, bool showRepaintCounter);
     void setRepaintCount(int);
     void setContentsLayer(TextureMapperPlatformLayer*);
@@ -92,8 +103,6 @@ public:
 private:
     const TextureMapperLayer* rootLayer() const;
     void computeTransformsRecursive();
-    IntRect intermediateSurfaceRect(const TransformationMatrix&);
-    IntRect intermediateSurfaceRect();
 
     static int compareGraphicsLayersZValue(const void* a, const void* b);
     static void sortByZOrder(Vector<TextureMapperLayer* >& array, int first, int last);
@@ -101,15 +110,21 @@ private:
     PassRefPtr<BitmapTexture> texture() { return m_backingStore ? m_backingStore->texture() : 0; }
     FloatPoint adjustedPosition() const { return m_state.pos + m_scrollPositionDelta; }
     bool isAncestorFixedToViewport() const;
-
+    TransformationMatrix replicaTransform();
     void addChild(TextureMapperLayer*);
     void removeFromParent();
     void removeAllChildren();
 
+    void computeOverlapRegions(Region& overlapRegion, Region& nonOverlapRegion, bool alwaysResolveSelfOverlap = true);
+
     void paintRecursive(const TextureMapperPaintOptions&);
+    void paintUsingOverlapRegions(const TextureMapperPaintOptions&);
+    PassRefPtr<BitmapTexture> paintIntoSurface(const TextureMapperPaintOptions&, const IntSize&);
+    void paintWithIntermediateSurface(const TextureMapperPaintOptions&, const IntRect&);
     void paintSelf(const TextureMapperPaintOptions&);
     void paintSelfAndChildren(const TextureMapperPaintOptions&);
     void paintSelfAndChildrenWithReplica(const TextureMapperPaintOptions&);
+    void applyMask(const TextureMapperPaintOptions&);
 
     // GraphicsLayerAnimation::Client
     virtual void setAnimatedTransform(const TransformationMatrix&) OVERRIDE;
@@ -125,8 +140,7 @@ private:
         MultipleLayersWithContents
     };
 
-    ContentsLayerCount countPotentialLayersWithContents() const;
-    bool shouldPaintToIntermediateSurface() const;
+    bool shouldBlend() const;
 
     inline FloatRect layerRect() const
     {
index f487952..b9baded 100644 (file)
@@ -32,7 +32,7 @@ namespace WebCore {
 class TextureMapperPlatformLayer {
 public:
     virtual ~TextureMapperPlatformLayer() { }
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0, BitmapTexture* mask = 0) = 0;
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0) = 0;
     virtual void swapBuffers() { }
     virtual void drawBorder(TextureMapper* textureMapper, const Color& color, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& transform)
     {
index 8c131e6..53ee2f0 100644 (file)
@@ -127,7 +127,6 @@ static const char* vertexTemplate =
         uniform mat4 u_textureSpaceMatrix;
 
         varying vec2 v_texCoord;
-        varying vec2 v_maskTexCoord;
         varying float v_antialias;
 
         void noop(inout vec2 dummyParameter) { }
@@ -176,8 +175,6 @@ static const char* vertexTemplate =
             // The texture position needs to be clamped to 0..1 before the texture matrix is applied.
             vec4 clampedPosition = clamp(vec4(position, 0., 1.), 0., 1.);
             v_texCoord = (u_textureSpaceMatrix * clampedPosition).xy;
-
-            v_maskTexCoord = position;
             gl_Position = u_projectionMatrix * u_modelViewMatrix * vec4(position, 0., 1.);
         }
     );
@@ -204,12 +201,10 @@ static const char* fragmentTemplate =
     STRINGIFY(
         precision mediump float;
         uniform SamplerType s_sampler;
-        uniform sampler2D s_mask;
         uniform sampler2D s_contentTexture;
         uniform float u_opacity;
         varying float v_antialias;
         varying vec2 v_texCoord;
-        varying vec2 v_maskTexCoord;
         uniform float u_filterAmount;
         uniform vec2 u_blurRadius;
         uniform vec2 u_shadowOffset;
@@ -223,7 +218,6 @@ static const char* fragmentTemplate =
         void applyTexture(inout vec4 color) { color = SamplerFunction(s_sampler, v_texCoord); }
         void applyOpacity(inout vec4 color) { color *= u_opacity; }
         void applyAntialiasing(inout vec4 color) { color *= antialias(); }
-        void applyMask(inout vec4 color) { color *= texture2D(s_mask, v_maskTexCoord).a; }
 
         void applyGrayscaleFilter(inout vec4 color)
         {
@@ -334,7 +328,6 @@ static const char* fragmentTemplate =
             applyTextureIfNeeded(color);
             applySolidColorIfNeeded(color);
             applyAntialiasingIfNeeded(color);
-            applyMaskIfNeeded(color);
             applyOpacityIfNeeded(color);
             applyGrayscaleFilterIfNeeded(color);
             applySepiaFilterIfNeeded(color);
@@ -362,7 +355,6 @@ PassRefPtr<TextureMapperShaderProgram> TextureMapperShaderProgram::create(PassRe
     SET_APPLIER_FROM_OPTIONS(Rect);
     SET_APPLIER_FROM_OPTIONS(SolidColor);
     SET_APPLIER_FROM_OPTIONS(Opacity);
-    SET_APPLIER_FROM_OPTIONS(Mask);
     SET_APPLIER_FROM_OPTIONS(Antialiasing);
     SET_APPLIER_FROM_OPTIONS(GrayscaleFilter);
     SET_APPLIER_FROM_OPTIONS(SepiaFilter);
index 037e7d6..32fae11 100644 (file)
@@ -42,7 +42,6 @@ public:
         Rect             = 1L << 1,
         SolidColor       = 1L << 2,
         Opacity          = 1L << 3,
-        Mask             = 1L << 4,
         Antialiasing     = 1L << 5,
         GrayscaleFilter  = 1L << 6,
         SepiaFilter      = 1L << 7,
index c7142d7..8d38776 100644 (file)
@@ -44,10 +44,10 @@ PassRefPtr<BitmapTexture> TextureMapperSurfaceBackingStore::texture() const
     return emptyTexture;
 }
 
-void TextureMapperSurfaceBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+void TextureMapperSurfaceBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
 {
     if (m_graphicsSurface)
-        m_graphicsSurface->paintToTextureMapper(textureMapper, targetRect, transform, opacity, mask);
+        m_graphicsSurface->paintToTextureMapper(textureMapper, targetRect, transform, opacity);
 }
 
 } // namespace WebCore
index 4cd1014..793c61d 100644 (file)
@@ -37,7 +37,7 @@ public:
     void setGraphicsSurface(PassRefPtr<GraphicsSurface>);
     void swapBuffersIfNeeded(uint32_t frontBuffer);
     virtual PassRefPtr<BitmapTexture> texture() const;
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*);
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float);
     virtual ~TextureMapperSurfaceBackingStore() { }
 
 private:
index 9b40513..07057ea 100644 (file)
@@ -69,10 +69,10 @@ void TextureMapperTile::updateContents(TextureMapper* textureMapper, GraphicsLay
     m_texture->updateContents(textureMapper, sourceLayer, targetRect, sourceOffset, updateContentsFlag);
 }
 
-void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, BitmapTexture* mask, const unsigned exposedEdges)
+void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, const unsigned exposedEdges)
 {
     if (texture().get())
-        textureMapper->drawTexture(*texture().get(), rect(), transform, opacity, mask, exposedEdges);
+        textureMapper->drawTexture(*texture().get(), rect(), transform, opacity, exposedEdges);
 }
 
 } // namespace WebCore
index acef618..2b45d90 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     void updateContents(TextureMapper*, Image*, const IntRect&, BitmapTexture::UpdateContentsFlag UpdateCanModifyOriginalImageData);
     void updateContents(TextureMapper*, GraphicsLayer*, const IntRect&, BitmapTexture::UpdateContentsFlag UpdateCanModifyOriginalImageData);
-    virtual void paint(TextureMapper*, const TransformationMatrix&, float, BitmapTexture*, const unsigned exposedEdges);
+    virtual void paint(TextureMapper*, const TransformationMatrix&, float, const unsigned exposedEdges);
     virtual ~TextureMapperTile() { }
 
     explicit TextureMapperTile(const FloatRect& rect)
index 8097922..4a60c81 100644 (file)
@@ -47,12 +47,12 @@ TransformationMatrix TextureMapperTiledBackingStore::adjustedTransformForRect(co
     return TransformationMatrix::rectToRect(rect(), targetRect);
 }
 
-void TextureMapperTiledBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+void TextureMapperTiledBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
 {
     updateContentsFromImageIfNeeded(textureMapper);
     TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
     for (size_t i = 0; i < m_tiles.size(); ++i)
-        m_tiles[i].paint(textureMapper, adjustedTransform, opacity, mask, calculateExposedTileEdges(rect(), m_tiles[i].rect()));
+        m_tiles[i].paint(textureMapper, adjustedTransform, opacity, calculateExposedTileEdges(rect(), m_tiles[i].rect()));
 }
 
 void TextureMapperTiledBackingStore::drawBorder(TextureMapper* textureMapper, const Color& borderColor, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& transform)
index 939b185..fc1f9bf 100644 (file)
@@ -38,7 +38,7 @@ public:
     virtual ~TextureMapperTiledBackingStore() { }
 
     virtual PassRefPtr<BitmapTexture> texture() const OVERRIDE;
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*) OVERRIDE;
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float) OVERRIDE;
     virtual void drawBorder(TextureMapper*, const Color&, float borderWidth, const FloatRect&, const TransformationMatrix&) OVERRIDE;
     virtual void drawRepaintCounter(TextureMapper*, int repaintCount, const Color&, const FloatRect&, const TransformationMatrix&) OVERRIDE;
     void updateContents(TextureMapper*, Image*, const FloatSize&, const IntRect&, BitmapTexture::UpdateContentsFlag);
index 105c1cb..cd5a12d 100644 (file)
@@ -106,10 +106,10 @@ void CoordinatedBackingStore::setSize(const FloatSize& size)
     m_pendingSize = size;
 }
 
-void CoordinatedBackingStore::paintTilesToTextureMapper(Vector<TextureMapperTile*>& tiles, TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, BitmapTexture* mask, const FloatRect& rect)
+void CoordinatedBackingStore::paintTilesToTextureMapper(Vector<TextureMapperTile*>& tiles, TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, const FloatRect& rect)
 {
     for (size_t i = 0; i < tiles.size(); ++i)
-        tiles[i]->paint(textureMapper, transform, opacity, mask, calculateExposedTileEdges(rect, tiles[i]->rect()));
+        tiles[i]->paint(textureMapper, transform, opacity, calculateExposedTileEdges(rect, tiles[i]->rect()));
 }
 
 TransformationMatrix CoordinatedBackingStore::adjustedTransformForRect(const FloatRect& targetRect)
@@ -117,7 +117,7 @@ TransformationMatrix CoordinatedBackingStore::adjustedTransformForRect(const Flo
     return TransformationMatrix::rectToRect(rect(), targetRect);
 }
 
-void CoordinatedBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
+void CoordinatedBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
 {
     if (m_tiles.isEmpty())
         return;
@@ -152,8 +152,8 @@ void CoordinatedBackingStore::paintToTextureMapper(TextureMapper* textureMapper,
     // See TiledBackingStore.
     TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);
 
-    paintTilesToTextureMapper(previousTilesToPaint, textureMapper, adjustedTransform, opacity, mask, rect());
-    paintTilesToTextureMapper(tilesToPaint, textureMapper, adjustedTransform, opacity, mask, rect());
+    paintTilesToTextureMapper(previousTilesToPaint, textureMapper, adjustedTransform, opacity, rect());
+    paintTilesToTextureMapper(tilesToPaint, textureMapper, adjustedTransform, opacity, rect());
 }
 
 void CoordinatedBackingStore::drawBorder(TextureMapper* textureMapper, const Color& borderColor, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& transform)
index 819895f..4201454 100644 (file)
@@ -62,7 +62,7 @@ public:
     void commitTileOperations(TextureMapper*);
     PassRefPtr<BitmapTexture> texture() const;
     void setSize(const FloatSize&);
-    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*);
+    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float);
     virtual void drawBorder(TextureMapper*, const Color&, float borderWidth, const FloatRect&, const TransformationMatrix&) OVERRIDE;
     virtual void drawRepaintCounter(TextureMapper*, int repaintCount, const Color&, const FloatRect&, const TransformationMatrix&) OVERRIDE;
 
@@ -70,7 +70,7 @@ private:
     CoordinatedBackingStore()
         : m_scale(1.)
     { }
-    void paintTilesToTextureMapper(Vector<TextureMapperTile*>&, TextureMapper*, const TransformationMatrix&, float, BitmapTexture*, const FloatRect&);
+    void paintTilesToTextureMapper(Vector<TextureMapperTile*>&, TextureMapper*, const TransformationMatrix&, float, const FloatRect&);
     TransformationMatrix adjustedTransformForRect(const FloatRect&);
     FloatRect rect() const { return FloatRect(FloatPoint::zero(), m_size); }