Title: [269328] trunk
Revision
269328
Author
[email protected]
Date
2020-11-03 12:32:45 -0800 (Tue, 03 Nov 2020)

Log Message

[TextureMapper] Crashed in TextureMapperLayer::paintUsingOverlapRegions
https://bugs.webkit.org/show_bug.cgi?id=214817
<rdar://problem/66489090>

Reviewed by Don Olmstead.

Source/WebCore:

TextureMapperLayer::paintUsingOverlapRegions has the _expression_
`overlapRegion.bounds().size().area()` which crashes for a very
large layer.

computeOverlapRegions returned very large overlap and non-overlap
regions without taking the clip bounds into account.

Change computeOverlapRegions to return clipped regions.
paintUsingOverlapRegions no longer needs to clip the returned
regions.

Test: compositing/tiling/huge-layer-with-opacity.html

* platform/graphics/texmap/TextureMapperLayer.cpp:
(WebCore::TextureMapperLayer::computeOverlapRegions):
(WebCore::TextureMapperLayer::paintUsingOverlapRegions):
* platform/graphics/texmap/TextureMapperLayer.h:

LayoutTests:

* compositing/tiling/huge-layer-with-opacity-expected.html: Added.
* compositing/tiling/huge-layer-with-opacity.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (269327 => 269328)


--- trunk/LayoutTests/ChangeLog	2020-11-03 20:20:37 UTC (rev 269327)
+++ trunk/LayoutTests/ChangeLog	2020-11-03 20:32:45 UTC (rev 269328)
@@ -1,3 +1,14 @@
+2020-11-03  Fujii Hironori  <[email protected]>
+
+        [TextureMapper] Crashed in TextureMapperLayer::paintUsingOverlapRegions
+        https://bugs.webkit.org/show_bug.cgi?id=214817
+        <rdar://problem/66489090>
+
+        Reviewed by Don Olmstead.
+
+        * compositing/tiling/huge-layer-with-opacity-expected.html: Added.
+        * compositing/tiling/huge-layer-with-opacity.html: Added.
+
 2020-11-03  Yusuke Suzuki  <[email protected]>
 
         REGRESSION (r254038): Simple.com money transfer UI is very laggy (multiple seconds per keypress)

Added: trunk/LayoutTests/compositing/tiling/huge-layer-with-opacity-expected.html (0 => 269328)


--- trunk/LayoutTests/compositing/tiling/huge-layer-with-opacity-expected.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/tiling/huge-layer-with-opacity-expected.html	2020-11-03 20:32:45 UTC (rev 269328)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <style>
+            html {
+                overflow: hidden;
+            }
+            div {
+                width: 1000px;
+                height: 1000px;
+                background: green;
+                border: 10px solid blue;
+                opacity: 0.5;
+                will-change: transform;
+            }
+        </style>
+    </head>
+    <body>
+        Rendering a huge opacity layer shouldn't crash <a href="" 214817</a>.
+        <div>
+            <div>
+                <div></div>
+            </div>
+        </div>
+    </body>
+</html>

Added: trunk/LayoutTests/compositing/tiling/huge-layer-with-opacity.html (0 => 269328)


--- trunk/LayoutTests/compositing/tiling/huge-layer-with-opacity.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/tiling/huge-layer-with-opacity.html	2020-11-03 20:32:45 UTC (rev 269328)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <style>
+            html {
+                overflow: hidden;
+            }
+            div {
+                width: 100000px;
+                height: 100000px;
+                background: green;
+                border: 10px solid blue;
+                opacity: 0.5;
+                will-change: transform;
+            }
+        </style>
+    </head>
+    <body>
+        Rendering a huge opacity layer shouldn't crash <a href="" 214817</a>.
+        <div>
+            <div>
+                <div></div>
+            </div>
+        </div>
+    </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (269327 => 269328)


--- trunk/Source/WebCore/ChangeLog	2020-11-03 20:20:37 UTC (rev 269327)
+++ trunk/Source/WebCore/ChangeLog	2020-11-03 20:32:45 UTC (rev 269328)
@@ -1,3 +1,29 @@
+2020-11-03  Fujii Hironori  <[email protected]>
+
+        [TextureMapper] Crashed in TextureMapperLayer::paintUsingOverlapRegions
+        https://bugs.webkit.org/show_bug.cgi?id=214817
+        <rdar://problem/66489090>
+
+        Reviewed by Don Olmstead.
+
+        TextureMapperLayer::paintUsingOverlapRegions has the _expression_
+        `overlapRegion.bounds().size().area()` which crashes for a very
+        large layer.
+
+        computeOverlapRegions returned very large overlap and non-overlap
+        regions without taking the clip bounds into account.
+
+        Change computeOverlapRegions to return clipped regions.
+        paintUsingOverlapRegions no longer needs to clip the returned
+        regions.
+
+        Test: compositing/tiling/huge-layer-with-opacity.html
+
+        * platform/graphics/texmap/TextureMapperLayer.cpp:
+        (WebCore::TextureMapperLayer::computeOverlapRegions):
+        (WebCore::TextureMapperLayer::paintUsingOverlapRegions):
+        * platform/graphics/texmap/TextureMapperLayer.h:
+
 2020-11-03  Stephan Szabo  <[email protected]>
 
         [WinCairo/PlayStation] ICU 68.1 no longer exposes FALSE and TRUE macros by default

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


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp	2020-11-03 20:20:37 UTC (rev 269327)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp	2020-11-03 20:32:45 UTC (rev 269328)
@@ -330,18 +330,18 @@
     if (!m_state.visible || !m_state.contentsVisible)
         return;
 
-    FloatRect boundingRect;
+    FloatRect localBoundingRect;
     if (m_backingStore || m_state.masksToBounds || m_state.maskLayer || hasFilters())
-        boundingRect = layerRect();
+        localBoundingRect = layerRect();
     else if (m_contentsLayer || m_state.solidColor.isVisible())
-        boundingRect = m_state.contentsRect;
+        localBoundingRect = m_state.contentsRect;
 
     if (m_currentFilters.hasOutsets()) {
         auto 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);
+        IntRect unfilteredTargetRect(localBoundingRect);
+        localBoundingRect.move(std::max(0, -outsets.left()), std::max(0, -outsets.top()));
+        localBoundingRect.expand(outsets.left() + outsets.right(), outsets.top() + outsets.bottom());
+        localBoundingRect.unite(unfilteredTargetRect);
     }
 
     TransformationMatrix transform;
@@ -351,14 +351,18 @@
     TransformationMatrix replicaMatrix;
     if (m_state.replicaLayer) {
         replicaMatrix = replicaTransform();
-        boundingRect.unite(replicaMatrix.mapRect(boundingRect));
+        localBoundingRect.unite(replicaMatrix.mapRect(localBoundingRect));
     }
 
-    boundingRect = transform.mapRect(boundingRect);
+    IntRect clipBounds(options.textureMapper.clipBounds());
+    clipBounds.move(-options.offset);
 
+    IntRect viewportBoundingRect = enclosingIntRect(transform.mapRect(localBoundingRect));
+    viewportBoundingRect.intersect(clipBounds);
+
     // 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));
+        Region newOverlapRegion(viewportBoundingRect);
         nonOverlapRegion.subtract(newOverlapRegion);
         overlapRegion.unite(newOverlapRegion);
         return;
@@ -365,7 +369,7 @@
     }
 
     Region newOverlapRegion;
-    Region newNonOverlapRegion(enclosingIntRect(boundingRect));
+    Region newNonOverlapRegion(viewportBoundingRect);
 
     if (!m_state.masksToBounds) {
         for (auto* child : m_children)
@@ -408,9 +412,6 @@
     auto rects = nonOverlapRegion.rects();
 
     for (auto& rect : rects) {
-        if (!rect.intersects(options.textureMapper.clipBounds()))
-            continue;
-
         options.textureMapper.beginClip(TransformationMatrix(), FloatRoundedRect(rect));
         paintSelfAndChildrenWithReplica(options);
         options.textureMapper.endClip();
@@ -424,15 +425,11 @@
     }
 
     IntSize maxTextureSize = options.textureMapper.maxTextureSize();
-    IntRect adjustedClipBounds(options.textureMapper.clipBounds());
-    adjustedClipBounds.move(-options.offset);
     for (auto& rect : rects) {
         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);
-                if (!tileRect.intersects(adjustedClipBounds))
-                    continue;
 
                 paintWithIntermediateSurface(options, tileRect);
             }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to