Avoid repaints for invisible animations on tumblr.com/search/aww
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Apr 2017 12:15:37 +0000 (12:15 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Apr 2017 12:15:37 +0000 (12:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170986
<rdar://problem/28644580>

Reviewed by Andreas Kling.

Source/WebCore:

Test: fast/repaint/mutate-non-visible.html

* rendering/style/RenderStyle.cpp:
(WebCore::requiresPainting):
(WebCore::RenderStyle::changeRequiresRepaint):

    If an element is invisible it does not require repaint even if something else changes.

LayoutTests:

* fast/repaint/mutate-non-visible-expected.txt: Added.
* fast/repaint/mutate-non-visible.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/repaint/mutate-non-visible-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/mutate-non-visible.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/style/RenderStyle.cpp

index f97032f..9e0b5b5 100644 (file)
@@ -1,3 +1,14 @@
+2017-04-19  Antti Koivisto  <antti@apple.com>
+
+        Avoid repaints for invisible animations on tumblr.com/search/aww
+        https://bugs.webkit.org/show_bug.cgi?id=170986
+        <rdar://problem/28644580>
+
+        Reviewed by Andreas Kling.
+
+        * fast/repaint/mutate-non-visible-expected.txt: Added.
+        * fast/repaint/mutate-non-visible.html: Added.
+
 2017-04-18  John Wilander  <wilander@apple.com>
 
         Resource Load Statistics: Check both origins and cookieHostNames for domain matches in data removal
diff --git a/LayoutTests/fast/repaint/mutate-non-visible-expected.txt b/LayoutTests/fast/repaint/mutate-non-visible-expected.txt
new file mode 100644 (file)
index 0000000..d555d73
--- /dev/null
@@ -0,0 +1,7 @@
+Test repaint-only style changes in non-visible elements don't trigger repaints.
+(repaint rects
+  (rect 10 28 100 100)
+  (rect 10 28 100 100)
+  (rect 10 28 100 100)
+)
+
diff --git a/LayoutTests/fast/repaint/mutate-non-visible.html b/LayoutTests/fast/repaint/mutate-non-visible.html
new file mode 100644 (file)
index 0000000..bb50714
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.container {
+    width: 100px;
+    border: 2px solid black;
+}
+.test {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+}
+.visibility-hidden { visibility: hidden; }
+.opacity-zero { opacity: 0; }
+</style>
+<script src="resources/text-based-repaint.js"></script>
+<script>
+function repaintTest() {
+    var tests = document.querySelectorAll(".test");
+    for (let test of tests)
+        test.style.backgroundColor = "green";
+}
+</script>
+
+</head>
+<body onload="runRepaintTest()">
+
+Test repaint-only style changes in non-visible elements don't trigger repaints.
+
+<div class="container">
+<div class="test" ></div>
+<div class="test visibility-hidden"></div>
+<div class="test opacity-zero"></div>
+</div>
+
+</body>
+</html>
index 9c5a3ce..f88ef80 100644 (file)
@@ -1,3 +1,19 @@
+2017-04-19  Antti Koivisto  <antti@apple.com>
+
+        Avoid repaints for invisible animations on tumblr.com/search/aww
+        https://bugs.webkit.org/show_bug.cgi?id=170986
+        <rdar://problem/28644580>
+
+        Reviewed by Andreas Kling.
+
+        Test: fast/repaint/mutate-non-visible.html
+
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::requiresPainting):
+        (WebCore::RenderStyle::changeRequiresRepaint):
+
+            If an element is invisible it does not require repaint even if something else changes.
+
 2017-04-19  Dean Jackson  <dino@apple.com>
 
         Non-muxable GPUs shouldn't allow offline rendering
index 812a804..3f48034 100644 (file)
@@ -843,8 +843,20 @@ bool RenderStyle::changeRequiresLayerRepaint(const RenderStyle& other, unsigned&
     return false;
 }
 
+static bool requiresPainting(const RenderStyle& style)
+{
+    if (style.visibility() == HIDDEN)
+        return false;
+    if (!style.opacity())
+        return false;
+    return true;
+}
+
 bool RenderStyle::changeRequiresRepaint(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
 {
+    if (!requiresPainting(*this) && !requiresPainting(other))
+        return false;
+
     if (m_inheritedFlags.visibility != other.m_inheritedFlags.visibility
         || m_inheritedFlags.printColorAdjust != other.m_inheritedFlags.printColorAdjust
         || m_inheritedFlags.insideLink != other.m_inheritedFlags.insideLink