Title: [295717] trunk
Revision
295717
Author
hironori.fu...@sony.com
Date
2022-06-21 20:09:26 -0700 (Tue, 21 Jun 2022)

Log Message

TextureMapper: mask should be applied after filter is applied
https://bugs.webkit.org/show_bug.cgi?id=241772

Reviewed by Don Olmstead.

If an element has both a mask-image and filters, the mask should be
applied after the filters.

BitmapTextureGL::applyFilters didn't actually apply the last filter.
It stored the last filter information in it, and applied the last
filter when blitting onto the target. If the element has a mask,
applyFilters should apply all filters before applying the mask.

* LayoutTests/compositing/masks/mask-and-drop-shadow-expected.html: Added.
* LayoutTests/compositing/masks/mask-and-drop-shadow.html: Added.
* Source/WebCore/platform/graphics/texmap/BitmapTexture.h:
(WebCore::BitmapTexture::applyFilters):
* Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp:
(WebCore::BitmapTextureGL::applyFilters):
* Source/WebCore/platform/graphics/texmap/BitmapTextureGL.h:
* Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp:
(WebCore::TextureMapperLayer::computeOverlapRegions):
(WebCore::TextureMapperLayer::paintIntoSurface):

Canonical link: https://commits.webkit.org/251722@main

Modified Paths

Added Paths

Diff

Added: trunk/LayoutTests/compositing/masks/mask-and-drop-shadow-expected.html (0 => 295717)


--- trunk/LayoutTests/compositing/masks/mask-and-drop-shadow-expected.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/mask-and-drop-shadow-expected.html	2022-06-22 03:09:26 UTC (rev 295717)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+    div {
+        width: 200px;
+        height: 200px;
+        background: green;
+        will-change: transform;
+        position: absolute;
+        -webkit-mask-image: linear-gradient(45deg, black, transparent);
+    }
+</style>
+
+You should see no red.
+
+<div></div>

Added: trunk/LayoutTests/compositing/masks/mask-and-drop-shadow.html (0 => 295717)


--- trunk/LayoutTests/compositing/masks/mask-and-drop-shadow.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/masks/mask-and-drop-shadow.html	2022-06-22 03:09:26 UTC (rev 295717)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>
+    div {
+        width: 200px;
+        height: 200px;
+        background: green;
+        filter: drop-shadow(50px 50px 0px red);
+        will-change: transform;
+        position: absolute;
+        -webkit-mask-image: linear-gradient(45deg, black, transparent);
+    }
+</style>
+
+You should see no red.
+
+<div></div>

Modified: trunk/Source/WebCore/platform/graphics/texmap/BitmapTexture.h (295716 => 295717)


--- trunk/Source/WebCore/platform/graphics/texmap/BitmapTexture.h	2022-06-22 03:00:34 UTC (rev 295716)
+++ trunk/Source/WebCore/platform/graphics/texmap/BitmapTexture.h	2022-06-22 03:09:26 UTC (rev 295717)
@@ -78,7 +78,7 @@
     inline int numberOfBytes() const { return size().width() * size().height() * bpp() >> 3; }
     inline bool isOpaque() const { return !(m_flags & SupportsAlpha); }
 
-    virtual RefPtr<BitmapTexture> applyFilters(TextureMapper&, const FilterOperations&) { return this; }
+    virtual RefPtr<BitmapTexture> applyFilters(TextureMapper&, const FilterOperations&, bool) { return this; }
 
 protected:
     IntSize m_contentSize;

Modified: trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp (295716 => 295717)


--- trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp	2022-06-22 03:00:34 UTC (rev 295716)
+++ trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.cpp	2022-06-22 03:09:26 UTC (rev 295717)
@@ -202,7 +202,7 @@
     }
 }
 
-RefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper& textureMapper, const FilterOperations& filters)
+RefPtr<BitmapTexture> BitmapTextureGL::applyFilters(TextureMapper& textureMapper, const FilterOperations& filters, bool defersLastFilter)
 {
     if (filters.isEmpty())
         return this;
@@ -222,17 +222,14 @@
         int numPasses = getPassesRequiredForFilter(filter->type());
         for (int j = 0; j < numPasses; ++j) {
             bool last = (i == filters.size() - 1) && (j == numPasses - 1);
-            if (!last) {
-                if (!intermediateSurface)
-                    intermediateSurface = texmapGL.acquireTextureFromPool(contentSize(), BitmapTexture::SupportsAlpha);
-                texmapGL.bindSurface(intermediateSurface.get());
-            }
-
-            if (last) {
+            if (defersLastFilter && last) {
                 toBitmapTextureGL(resultSurface.get())->m_filterInfo = BitmapTextureGL::FilterInfo(filter.copyRef(), j, spareSurface.copyRef());
                 break;
             }
 
+            if (!intermediateSurface)
+                intermediateSurface = texmapGL.acquireTextureFromPool(contentSize(), BitmapTexture::SupportsAlpha);
+            texmapGL.bindSurface(intermediateSurface.get());
             texmapGL.drawFiltered(*resultSurface.get(), spareSurface.get(), *filter, j);
             if (!j && filter->type() == FilterOperation::DROP_SHADOW) {
                 spareSurface = resultSurface;

Modified: trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.h (295716 => 295717)


--- trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.h	2022-06-22 03:00:34 UTC (rev 295716)
+++ trunk/Source/WebCore/platform/graphics/texmap/BitmapTextureGL.h	2022-06-22 03:09:26 UTC (rev 295717)
@@ -60,7 +60,7 @@
     void updateContents(const void*, const IntRect& target, const IntPoint& sourceOffset, int bytesPerLine) override;
     bool isBackedByOpenGL() const override { return true; }
 
-    RefPtr<BitmapTexture> applyFilters(TextureMapper&, const FilterOperations&) override;
+    RefPtr<BitmapTexture> applyFilters(TextureMapper&, const FilterOperations&, bool defersLastFilter) override;
     struct FilterInfo {
         RefPtr<FilterOperation> filter;
         unsigned pass;

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp (295716 => 295717)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp	2022-06-22 03:00:34 UTC (rev 295716)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp	2022-06-22 03:09:26 UTC (rev 295717)
@@ -343,7 +343,7 @@
     else if (m_contentsLayer || m_state.solidColor.isVisible())
         localBoundingRect = m_state.contentsRect;
 
-    if (m_currentFilters.hasOutsets() && !m_state.backdropLayer) {
+    if (m_currentFilters.hasOutsets() && !m_state.backdropLayer && !m_state.masksToBounds && !m_state.maskLayer) {
         auto outsets = m_currentFilters.outsets();
         localBoundingRect.move(-outsets.left(), -outsets.top());
         localBoundingRect.expand(outsets.left() + outsets.right(), outsets.top() + outsets.bottom());
@@ -485,14 +485,16 @@
         rootLayer().paintSelfAndChildren(options);
     } else
         paintSelfAndChildren(options);
-    if (options.replicaLayer == this) {
-        if (m_state.replicaLayer->m_state.maskLayer)
-            m_state.replicaLayer->m_state.maskLayer->applyMask(options);
-    }
-    if (m_state.maskLayer)
+
+    bool hasMask = !!m_state.maskLayer;
+    bool hasReplicaMask = options.replicaLayer == this && m_state.replicaLayer->m_state.maskLayer;
+    bool defersLastFilter = !hasMask && !hasReplicaMask;
+    options.surface = options.surface->applyFilters(options.textureMapper, m_currentFilters, defersLastFilter);
+    options.textureMapper.bindSurface(options.surface.get());
+    if (hasMask)
         m_state.maskLayer->applyMask(options);
-    options.surface = options.surface->applyFilters(options.textureMapper, m_currentFilters);
-    options.textureMapper.bindSurface(options.surface.get());
+    if (hasReplicaMask)
+        m_state.replicaLayer->m_state.maskLayer->applyMask(options);
 }
 
 static void commitSurface(TextureMapperPaintOptions& options, BitmapTexture& surface, const IntRect& rect, float opacity)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to