Title: [181941] releases/WebKitGTK/webkit-2.8
Revision
181941
Author
[email protected]
Date
2015-03-25 03:02:37 -0700 (Wed, 25 Mar 2015)

Log Message

Merge r181710 - Avoid repaints when changing transform on an element with multiple background images
https://bugs.webkit.org/show_bug.cgi?id=142841

Reviewed by Zalan Bujtas.

Source/WebCore:

Replace the cheap test for changed images in RenderElement::updateFillImages()
with an exhaustive test that walks the entire list of background images,
since any ensuing repaint is way more expensive than a slightly more expensive check here.

Test: fast/repaint/multiple-backgrounds-style-change.html

* rendering/RenderElement.cpp:
(WebCore::RenderElement::updateFillImages):
* rendering/style/FillLayer.cpp:
(WebCore::layerImagesIdentical): See if both images are the same (either none
or both mask images, and same image pointer).
(WebCore::FillLayer::imagesIdentical): Walk the two FillLayer lists, checking the images
on each one. Returns false if we reach the end of one list before the other, or the images
are different.
* rendering/style/FillLayer.h: New static function; static because
it compares two FillLayer lists, and I think that makes more sense than
a member function.

LayoutTests:

Test that changes transform on a composited element with 2 background images,
and tests for no repaints.

* fast/repaint/multiple-backgrounds-style-change-expected.txt: Added.
* fast/repaint/multiple-backgrounds-style-change.html: Added.

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog (181940 => 181941)


--- releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog	2015-03-25 09:53:47 UTC (rev 181940)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/ChangeLog	2015-03-25 10:02:37 UTC (rev 181941)
@@ -1,3 +1,16 @@
+2015-03-18  Simon Fraser  <[email protected]>
+
+        Avoid repaints when changing transform on an element with multiple background images
+        https://bugs.webkit.org/show_bug.cgi?id=142841
+
+        Reviewed by Zalan Bujtas.
+        
+        Test that changes transform on a composited element with 2 background images,
+        and tests for no repaints.
+
+        * fast/repaint/multiple-backgrounds-style-change-expected.txt: Added.
+        * fast/repaint/multiple-backgrounds-style-change.html: Added.
+
 2015-03-18  Manuel Rego Casasnovas  <[email protected]>
 
         Flex and grid items should be painted as inline-blocks

Added: releases/WebKitGTK/webkit-2.8/LayoutTests/fast/repaint/multiple-backgrounds-style-change-expected.txt (0 => 181941)


--- releases/WebKitGTK/webkit-2.8/LayoutTests/fast/repaint/multiple-backgrounds-style-change-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/fast/repaint/multiple-backgrounds-style-change-expected.txt	2015-03-25 10:02:37 UTC (rev 181941)
@@ -0,0 +1,10 @@
+Tests that a transform change on an element with multiple background images doesn't cause a repaint.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS layerTreeAsText.indexOf('(repaint rects') == -1 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.8/LayoutTests/fast/repaint/multiple-backgrounds-style-change.html (0 => 181941)


--- releases/WebKitGTK/webkit-2.8/LayoutTests/fast/repaint/multiple-backgrounds-style-change.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.8/LayoutTests/fast/repaint/multiple-backgrounds-style-change.html	2015-03-25 10:02:37 UTC (rev 181941)
@@ -0,0 +1,74 @@
+<html>
+<head>
+    <style>
+        .box {
+            height: 200px;
+            width: 200px;
+            border: 1px solid black;
+            background-repeat: no-repeat;
+            background-size: 100px 100px;
+            background-position: 0 0, 100px 100px;
+        }
+        
+        .apply-images {
+            background-image: url('../images/resources/green-256x256.jpg'), url('../images/resources/dice.png');
+        }
+
+        .composited {
+            -webkit-transform: translate3d(0, 0, 0);
+        }
+        
+        .composited.changed {
+            -webkit-transform: translate3d(50px, 50px, 0);
+        }
+    </style>
+<script>jsTestIsAsync = true;</script>
+<script src=""
+<script>
+    description("Tests that a transform change on an element with multiple background images doesn't cause a repaint.");
+    function startTrackingRepaints()
+    {
+        if (window.internals)
+            window.internals.startTrackingRepaints();
+        document.getElementById('test').classList.add('changed');
+        setTimeout(logRepaints, 0)
+    }
+
+    function logRepaints()
+    {
+        layerTreeAsText =  window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+        window.internals.stopTrackingRepaints();
+        shouldBeTrue("layerTreeAsText.indexOf('(repaint rects') == -1");
+
+        finishJSTest();
+    }
+    
+    var loadedRemaining = 2;
+    function imageLoaded()
+    {
+        if (!--loadedRemaining) {
+            document.getElementById('test').classList.add('apply-images');
+            setTimeout(startTrackingRepaints, 0);
+        }
+    }
+
+    function doTest()
+    {
+        // We have to know that the images to be used by CSS are loaded to avoid spurious repaints later.
+        var firstImage = new Image();
+        firstImage._onload_ = imageLoaded;
+        firstImage.src = '';
+
+        var secondImage = new Image();
+        secondImage._onload_ = imageLoaded;
+        secondImage.src = '';
+    }
+
+    window.addEventListener('load', doTest, false);
+</script>
+</head>
+<body>
+    <div id="test" class="composited box">
+    </div>
+<script src=""
+</html>

Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog (181940 => 181941)


--- releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog	2015-03-25 09:53:47 UTC (rev 181940)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/ChangeLog	2015-03-25 10:02:37 UTC (rev 181941)
@@ -1,3 +1,28 @@
+2015-03-18  Simon Fraser  <[email protected]>
+
+        Avoid repaints when changing transform on an element with multiple background images
+        https://bugs.webkit.org/show_bug.cgi?id=142841
+
+        Reviewed by Zalan Bujtas.
+        
+        Replace the cheap test for changed images in RenderElement::updateFillImages()
+        with an exhaustive test that walks the entire list of background images,
+        since any ensuing repaint is way more expensive than a slightly more expensive check here.
+        
+        Test: fast/repaint/multiple-backgrounds-style-change.html
+
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::updateFillImages):
+        * rendering/style/FillLayer.cpp:
+        (WebCore::layerImagesIdentical): See if both images are the same (either none
+        or both mask images, and same image pointer).
+        (WebCore::FillLayer::imagesIdentical): Walk the two FillLayer lists, checking the images
+        on each one. Returns false if we reach the end of one list before the other, or the images
+        are different.
+        * rendering/style/FillLayer.h: New static function; static because
+        it compares two FillLayer lists, and I think that makes more sense than
+        a member function.
+
 2015-03-18  Anders Carlsson  <[email protected]>
 
         Pass cookies by reference in CookieHash functions

Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderElement.cpp (181940 => 181941)


--- releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderElement.cpp	2015-03-25 09:53:47 UTC (rev 181940)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/RenderElement.cpp	2015-03-25 10:02:37 UTC (rev 181941)
@@ -330,7 +330,7 @@
 void RenderElement::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
 {
     // Optimize the common case
-    if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && oldLayers->image() == newLayers->image() && oldLayers->maskImage() == newLayers->maskImage())
+    if (FillLayer::imagesIdentical(oldLayers, newLayers))
         return;
     
     // Go through the new layers and addClients first, to avoid removing all clients of an image.

Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/style/FillLayer.cpp (181940 => 181941)


--- releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/style/FillLayer.cpp	2015-03-25 09:53:47 UTC (rev 181940)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/style/FillLayer.cpp	2015-03-25 10:02:37 UTC (rev 181941)
@@ -392,4 +392,20 @@
     return false;
 }
 
+static inline bool layerImagesIdentical(const FillLayer& layer1, const FillLayer& layer2)
+{
+    // We just care about pointer equivalency.
+    return layer1.hasMaskImage() == layer2.hasMaskImage() && layer1.image() == layer2.image();
+}
+
+bool FillLayer::imagesIdentical(const FillLayer* layer1, const FillLayer* layer2)
+{
+    for (; layer1 && layer2; layer1 = layer1->next(), layer2 = layer2->next()) {
+        if (!layerImagesIdentical(*layer1, *layer2))
+            return false;
+    }
+
+    return !layer1 && !layer2;
+}
+
 } // namespace WebCore

Modified: releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/style/FillLayer.h (181940 => 181941)


--- releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/style/FillLayer.h	2015-03-25 09:53:47 UTC (rev 181940)
+++ releases/WebKitGTK/webkit-2.8/Source/WebCore/rendering/style/FillLayer.h	2015-03-25 10:02:37 UTC (rev 181941)
@@ -159,6 +159,8 @@
     void fillUnsetProperties();
     void cullEmptyLayers();
 
+    static bool imagesIdentical(const FillLayer*, const FillLayer*);
+
     static EFillAttachment initialFillAttachment(EFillLayerType) { return ScrollBackgroundAttachment; }
     static EFillBox initialFillClip(EFillLayerType) { return BorderFillBox; }
     static EFillBox initialFillOrigin(EFillLayerType type) { return type == BackgroundFillLayer ? PaddingFillBox : BorderFillBox; }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to