https://bugs.webkit.org/show_bug.cgi?id=189812
<rdar://problem/
44532782>
Reviewed by Simon Fraser.
Source/WebCore:
If the total area of all backdrop filters on the page gets
too large, the universe collapses in on itself and we enter
the Quantum Realm (i.e. crash horribly).
Put a hard limit on the total coverage, and ignore any backdrop
filters after the limit. This might break some content, but
such content is likely not doing things in the most optimal manner.
There isn't any reason to have a backdrop larger than the size of
the screen, because you'd be better off applying a foreground
filter to the main content and showing something above it.
Tests: css3/filters/backdrop/resource-use-add-more-layers.html
css3/filters/backdrop/resource-use-excessive.html
css3/filters/backdrop/resource-use-ok.html
css3/filters/backdrop/resource-use-remove-some-layers.html
* platform/graphics/ca/GraphicsLayerCA.cpp: Pick a fairly small maximum size. We
can consider increasing this if necessary, and as devices with less RAM are
upgraded.
(WebCore::GraphicsLayerCA::recursiveCommitChanges): Gather the accumulated size
of backdrop filters into the commit state as we are recursing through the tree.
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Force any layer
with backdrop filters, or any that is removing backdrop filters, into an update.
(WebCore::GraphicsLayerCA::updateBackdropFilters): Update the logic to first
check if this backdrop layer causes us to exceed the total allowed size, and if
it does, forbid it from getting the GraphicsLayer that composits the backdrop.
* platform/graphics/ca/GraphicsLayerCA.h: Remove const from some parameters so
that we can use the CommitState to hold the accumulated size.
LayoutTests:
Tests that have an acceptable number of backdrops, an excessive
number of backdrops, and then some that add and remove backdrops
at various points in the tree to confirm we do recursive checks
correctly.
* css3/filters/backdrop/layer-tree-as-text.js: Added.
* css3/filters/backdrop/resource-use-add-more-layers-expected.txt: Added.
* css3/filters/backdrop/resource-use-add-more-layers.html: Added.
* css3/filters/backdrop/resource-use-excessive-expected.txt: Added.
* css3/filters/backdrop/resource-use-excessive.html: Added.
* css3/filters/backdrop/resource-use-ok-expected.txt: Added.
* css3/filters/backdrop/resource-use-ok.html: Added.
* css3/filters/backdrop/resource-use-remove-some-layers-expected.txt: Added.
* css3/filters/backdrop/resource-use-remove-some-layers.html: Added.
* css3/filters/backdrop/resource-use.css: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236306
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2018-09-20 Dean Jackson <dino@apple.com>
+
+ Restrict the total combined size of backdrop filters
+ https://bugs.webkit.org/show_bug.cgi?id=189812
+ <rdar://problem/44532782>
+
+ Reviewed by Simon Fraser.
+
+ Tests that have an acceptable number of backdrops, an excessive
+ number of backdrops, and then some that add and remove backdrops
+ at various points in the tree to confirm we do recursive checks
+ correctly.
+
+ * css3/filters/backdrop/layer-tree-as-text.js: Added.
+ * css3/filters/backdrop/resource-use-add-more-layers-expected.txt: Added.
+ * css3/filters/backdrop/resource-use-add-more-layers.html: Added.
+ * css3/filters/backdrop/resource-use-excessive-expected.txt: Added.
+ * css3/filters/backdrop/resource-use-excessive.html: Added.
+ * css3/filters/backdrop/resource-use-ok-expected.txt: Added.
+ * css3/filters/backdrop/resource-use-ok.html: Added.
+ * css3/filters/backdrop/resource-use-remove-some-layers-expected.txt: Added.
+ * css3/filters/backdrop/resource-use-remove-some-layers.html: Added.
+ * css3/filters/backdrop/resource-use.css: Added.
+
2018-09-20 Truitt Savell <tsavell@apple.com>
Continued test gardening after r236236
--- /dev/null
+const addLayerTree = () => {
+ if (!window.internals)
+ return;
+ const layerTree = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CONTENT_LAYERS);
+ const output = document.createElement("pre");
+ output.textContent = layerTree;
+ document.body.insertBefore(output, document.body.firstChild);
+};
+
+const addLayerTreeAndFinish = () => {
+ addLayerTree();
+ testRunner.notifyDone();
+};
+
+if (window.internals) {
+ window.addEventListener("load", () => {
+ if (window.doNotAutomaticallyCallLayerTree != undefined && window.doNotAutomaticallyCallLayerTree) {
+ testRunner.waitUntilDone();
+ return;
+ }
+ addLayerTree();
+ }, false);
+
+ testRunner.dumpAsText();
+}
--- /dev/null
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 1243.00 2209.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 1243.00 2209.00)
+ (contentsOpaque 1)
+ (children 3
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ (children 10
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!DOCTYPE html>
+<link rel="stylesheet" href="resource-use.css">
+<!-- start with a small number of backdrop filters, so each should get a backdrop layer at first -->
+<div></div>
+<div></div>
+<div></div>
+<!-- then add a bunch via script, as children to the first div, eventually pushing us over the limit -->
+<script>
+const doNotAutomaticallyCallLayerTree = true;
+
+window.addEventListener("load", () => {
+ const firstDiv = document.querySelector("div");
+ for (let i = 0; i < 10; i++) {
+ const newDiv = document.createElement("div");
+ firstDiv.appendChild(newDiv);
+ }
+ setTimeout(() => {
+ addLayerTreeAndFinish();
+ }, 0);
+}, false);
+</script>
+<script src="layer-tree-as-text.js"></script>
--- /dev/null
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 1245.00 2211.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 1245.00 2211.00)
+ (contentsOpaque 1)
+ (children 8
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ (children 1
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ (children 1
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ (children 1
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ (children 1
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (children 1
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!DOCTYPE html>
+<link rel="stylesheet" href="resource-use.css">
+<!-- these first few elements will get a backdrop layer -->
+<div></div>
+<div><div></div></div>
+<div></div>
+<div><div><div><div></div></div></div></div>
+<div></div>
+<div></div>
+<!-- and by here we're exceeding the limits, so they won't get a backdrop layer -->
+<div><div></div></div>
+<div></div>
+<script src="layer-tree-as-text.js"></script>
--- /dev/null
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 1243.00 2209.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 1243.00 2209.00)
+ (contentsOpaque 1)
+ (children 3
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ (children 1
+ (GraphicsLayer
+ (position 1.00 1.00)
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 622.00, 1105.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!DOCTYPE html>
+<link rel="stylesheet" href="resource-use.css">
+<!-- this is a small number of backdrop filters, so each should get a backdrop layer -->
+<div></div>
+<div><div></div></div>
+<div></div>
+<script src="layer-tree-as-text.js"></script>
--- /dev/null
+(GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 1242.00 2208.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (contentsOpaque 1)
+ (children 7
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ (GraphicsLayer
+ (bounds 1242.00 2208.00)
+ (usingTiledLayer 1)
+ (drawsContent 1)
+ (structural layer 621.00, 1104.00 1242.00 x 2208.00)
+ (backdrop layer 0.00, 0.00 1242.00 x 2208.00)
+ )
+ )
+ )
+ )
+)
+
--- /dev/null
+<!DOCTYPE html>
+<link rel="stylesheet" href="resource-use.css">
+<!-- start with a large number of backdrop filters, so we exceed the limit -->
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<div></div>
+<!-- then remove some from the start, getting us back under the limit -->
+<script>
+const doNotAutomaticallyCallLayerTree = true;
+
+window.addEventListener("load", () => {
+ for (let i = 0; i < 10; i++) {
+ const firstDiv = document.querySelector("div");
+ firstDiv.remove();
+ }
+ setTimeout(() => {
+ addLayerTreeAndFinish();
+ }, 0);
+}, false);
+</script>
+<script src="layer-tree-as-text.js"></script>
--- /dev/null
+/* The total backdrop filter limit is 1242 * 2208 * 10, so make each div 1/10th of that */
+div {
+ -webkit-backdrop-filter: blur(1px);
+ width: 1242px;
+ height: 2208px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ border: 1px solid blue;
+ box-sizing: border-box;
+}
+2018-09-20 Dean Jackson <dino@apple.com>
+
+ Restrict the total combined size of backdrop filters
+ https://bugs.webkit.org/show_bug.cgi?id=189812
+ <rdar://problem/44532782>
+
+ Reviewed by Simon Fraser.
+
+ If the total area of all backdrop filters on the page gets
+ too large, the universe collapses in on itself and we enter
+ the Quantum Realm (i.e. crash horribly).
+
+ Put a hard limit on the total coverage, and ignore any backdrop
+ filters after the limit. This might break some content, but
+ such content is likely not doing things in the most optimal manner.
+ There isn't any reason to have a backdrop larger than the size of
+ the screen, because you'd be better off applying a foreground
+ filter to the main content and showing something above it.
+
+ Tests: css3/filters/backdrop/resource-use-add-more-layers.html
+ css3/filters/backdrop/resource-use-excessive.html
+ css3/filters/backdrop/resource-use-ok.html
+ css3/filters/backdrop/resource-use-remove-some-layers.html
+
+ * platform/graphics/ca/GraphicsLayerCA.cpp: Pick a fairly small maximum size. We
+ can consider increasing this if necessary, and as devices with less RAM are
+ upgraded.
+ (WebCore::GraphicsLayerCA::recursiveCommitChanges): Gather the accumulated size
+ of backdrop filters into the commit state as we are recursing through the tree.
+ (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): Force any layer
+ with backdrop filters, or any that is removing backdrop filters, into an update.
+ (WebCore::GraphicsLayerCA::updateBackdropFilters): Update the logic to first
+ check if this backdrop layer causes us to exceed the total allowed size, and if
+ it does, forbid it from getting the GraphicsLayer that composits the backdrop.
+
+ * platform/graphics/ca/GraphicsLayerCA.h: Remove const from some parameters so
+ that we can use the CommitState to hold the accumulated size.
+
2018-09-20 Benjamin Poulain <benjamin@webkit.org>
Adopt safe-area-insets on ImageDocument
#include <QuartzCore/CATransform3D.h>
#include <limits.h>
#include <pal/spi/cf/CFUtilitiesSPI.h>
+#include <wtf/CheckedArithmetic.h>
#include <wtf/MathExtras.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/SetForScope.h>
#endif
// Derived empirically: <rdar://problem/13401861>
-static const int cMaxLayerTreeDepth = 250;
+static const unsigned cMaxLayerTreeDepth = 250;
+
+// About 10 screens of an iPhone 6 Plus. <rdar://problem/44532782>
+static const unsigned cMaxTotalBackdropFilterArea = 1242 * 2208 * 10;
// If we send a duration of 0 to CA, then it will use the default duration
// of 250ms. So send a very small value instead.
// rootRelativeTransformForScaling is a transform from the root, but for layers with transform animations, it cherry-picked the state of the
// animation that contributes maximally to the scale (on every layer with animations down the hierarchy).
-void GraphicsLayerCA::recursiveCommitChanges(const CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
+void GraphicsLayerCA::recursiveCommitChanges(CommitState& commitState, const TransformState& state, float pageScaleFactor, const FloatPoint& positionRelativeToBase, bool affectedByPageScale)
{
if (!needsCommit(commitState))
return;
hasDescendantsWithRunningTransformAnimations = true;
}
+ commitState.totalBackdropFilterArea = childCommitState.totalBackdropFilterArea;
+
if (GraphicsLayerCA* replicaLayer = downcast<GraphicsLayerCA>(m_replicaLayer.get()))
replicaLayer->recursiveCommitChanges(childCommitState, localState, pageScaleFactor, baseRelativePosition, affectedByPageScale);
if (m_uncommittedChanges & FiltersChanged)
updateFilters();
- if (m_uncommittedChanges & BackdropFiltersChanged)
- updateBackdropFilters();
+ // If there are backdrop filters, we need to always check the resource usage
+ // because something up the tree may have changed its usage.
+ if (m_uncommittedChanges & BackdropFiltersChanged || needsBackdrop())
+ updateBackdropFilters(commitState);
if (m_uncommittedChanges & BackdropFiltersRectChanged)
updateBackdropFiltersRect();
}
}
-void GraphicsLayerCA::updateBackdropFilters()
+void GraphicsLayerCA::updateBackdropFilters(CommitState& commitState)
{
- if (m_backdropFilters.isEmpty()) {
+ bool canHaveBackdropFilters = needsBackdrop();
+
+ if (canHaveBackdropFilters) {
+ Checked<unsigned, RecordOverflow> backdropFilterArea = Checked<unsigned>(static_cast<int>(m_backdropFiltersRect.rect().width())) * Checked<unsigned>(static_cast<int>(m_backdropFiltersRect.rect().height()));
+ if (backdropFilterArea.hasOverflowed())
+ canHaveBackdropFilters = false;
+ else {
+ Checked<unsigned, RecordOverflow> newTotalBackdropFilterArea = Checked<unsigned, RecordOverflow>(commitState.totalBackdropFilterArea) + backdropFilterArea;
+ if (newTotalBackdropFilterArea.hasOverflowed() || newTotalBackdropFilterArea.unsafeGet() > cMaxTotalBackdropFilterArea)
+ canHaveBackdropFilters = false;
+ else
+ commitState.totalBackdropFilterArea = newTotalBackdropFilterArea.unsafeGet();
+ }
+ }
+
+ if (!canHaveBackdropFilters) {
if (m_backdropLayer) {
m_backdropLayer->removeFromSuperlayer();
m_backdropLayer->setOwner(nullptr);
return;
}
+ // If nothing actually changed, no need to touch the layer properties.
+ if (!(m_uncommittedChanges & BackdropFiltersChanged))
+ return;
+
bool madeLayer = !m_backdropLayer;
if (!m_backdropLayer) {
m_backdropLayer = createPlatformCALayer(PlatformCALayer::LayerTypeBackdropLayer, this);
FloatSize pixelAlignmentOffset() const override { return m_pixelAlignmentOffset; }
struct CommitState {
- int treeDepth { 0 };
+ unsigned treeDepth { 0 };
+ unsigned totalBackdropFilterArea { 0 };
bool ancestorHadChanges { false };
bool ancestorHasTransformAnimation { false };
bool ancestorStartedOrEndedTransformAnimation { false };
bool ancestorIsViewportConstrained { false };
};
bool needsCommit(const CommitState&);
- void recursiveCommitChanges(const CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
+ void recursiveCommitChanges(CommitState&, const TransformState&, float pageScaleFactor = 1, const FloatPoint& positionRelativeToBase = FloatPoint(), bool affectedByPageScale = false);
WEBCORE_EXPORT void flushCompositingState(const FloatRect&) override;
WEBCORE_EXPORT void flushCompositingStateForThisLayerOnly() override;
void updateOpacityOnLayer();
void updateFilters();
- void updateBackdropFilters();
+ void updateBackdropFilters(CommitState&);
void updateBackdropFiltersRect();
#if ENABLE(CSS_COMPOSITING)