<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[195515] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/195515">195515</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2016-01-24 12:39:42 -0800 (Sun, 24 Jan 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Add testing for display list replay, and skip clipped-out items on replay
https://bugs.webkit.org/show_bug.cgi?id=153408
Reviewed by Zalan Bujtas.
Source/WebCore:
Make it possible to save and serialize a DisplayList of Items which were
actually applied on replay, so that replay-time optimizations can be tested.
This exposes internals.setElementTracksDisplayListReplay() and
internals.replayDisplayListForElement().
Do a trivial replay-time optimization, which is to skip items whose extents are
outside the replay clip.
Test: displaylists/replay-skip-clipped-rect.html
* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::GraphicsLayer):
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::setIsTrackingDisplayListReplay):
(WebCore::GraphicsLayer::isTrackingDisplayListReplay):
(WebCore::GraphicsLayer::replayDisplayListAsText):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::layerDisplayListMap): Use a singleton map to store the replay display lists
to avoid bloating GraphicsLayerCA for test-only code. The map stores a pair of the
replay list and a clip rect, which are both dumped. Dumping the clip rect ensures that
we're reporting the replay for the correct tile in a test (since there will be a replay
for each tile).
(WebCore::GraphicsLayerCA::~GraphicsLayerCA):
(WebCore::GraphicsLayerCA::platformCALayerPaintContents):
(WebCore::GraphicsLayerCA::setIsTrackingDisplayListReplay):
(WebCore::GraphicsLayerCA::replayDisplayListAsText):
* platform/graphics/ca/GraphicsLayerCA.h:
* platform/graphics/displaylists/DisplayList.h:
(WebCore::DisplayList::DisplayList::appendItem):
* platform/graphics/displaylists/DisplayListReplayer.cpp:
(WebCore::DisplayList::Replayer::replay): In the unlikely event of tracking replays,
allocate a new DisplayList and append to it items which actually get applied.
* platform/graphics/displaylists/DisplayListReplayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::setIsTrackingDisplayListReplay):
(WebCore::RenderLayerBacking::replayDisplayListAsText):
* rendering/RenderLayerBacking.h:
* testing/Internals.cpp:
(WebCore::Internals::setElementTracksDisplayListReplay):
(WebCore::Internals::replayDisplayListForElement):
* testing/Internals.h:
* testing/Internals.idl:
LayoutTests:
Test that a clipped-out rectangle is not painted.
In order to get the rect into the display list, we need to make the target
compositing layer be tiled, and to be clipped by an ancestor so that only the
second tile renders. (This complexity is required because in simpler scenarios,
the rect is clipped out at recording time.)
* displaylists/replay-skip-clipped-rect-expected.txt: Added.
* displaylists/replay-skip-clipped-rect.html: Added.
* displaylists/resources/dump-target-replay-list.js: Added.
(doTest):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsLayercpp">trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsLayerh">trunk/Source/WebCore/platform/graphics/GraphicsLayer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp">trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAh">trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListh">trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListReplayercpp">trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListReplayerh">trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingcpp">trunk/Source/WebCore/rendering/RenderLayerBacking.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingh">trunk/Source/WebCore/rendering/RenderLayerBacking.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsh">trunk/Source/WebCore/testing/Internals.h</a></li>
<li><a href="#trunkSourceWebCoretestingInternalsidl">trunk/Source/WebCore/testing/Internals.idl</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsdisplaylistsreplayskipclippedrectexpectedtxt">trunk/LayoutTests/displaylists/replay-skip-clipped-rect-expected.txt</a></li>
<li><a href="#trunkLayoutTestsdisplaylistsreplayskipclippedrecthtml">trunk/LayoutTests/displaylists/replay-skip-clipped-rect.html</a></li>
<li><a href="#trunkLayoutTestsdisplaylistsresourcesdumptargetreplaylistjs">trunk/LayoutTests/displaylists/resources/dump-target-replay-list.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/LayoutTests/ChangeLog        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2016-01-24 Simon Fraser <simon.fraser@apple.com>
+
+ Add testing for display list replay, and skip clipped-out items on replay
+ https://bugs.webkit.org/show_bug.cgi?id=153408
+
+ Reviewed by Zalan Bujtas.
+
+ Test that a clipped-out rectangle is not painted.
+
+ In order to get the rect into the display list, we need to make the target
+ compositing layer be tiled, and to be clipped by an ancestor so that only the
+ second tile renders. (This complexity is required because in simpler scenarios,
+ the rect is clipped out at recording time.)
+
+ * displaylists/replay-skip-clipped-rect-expected.txt: Added.
+ * displaylists/replay-skip-clipped-rect.html: Added.
+ * displaylists/resources/dump-target-replay-list.js: Added.
+ (doTest):
+
</ins><span class="cx"> 2016-01-23 Simon Fraser <simon.fraser@apple.com>
</span><span class="cx">
</span><span class="cx"> Layout Test displaylists/extent-includes-transforms.html is flaky on mac-wk1
</span></span></pre></div>
<a id="trunkLayoutTestsdisplaylistsreplayskipclippedrectexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/displaylists/replay-skip-clipped-rect-expected.txt (0 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/displaylists/replay-skip-clipped-rect-expected.txt         (rev 0)
+++ trunk/LayoutTests/displaylists/replay-skip-clipped-rect-expected.txt        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+recorded:
+(
+ (translate
+ (x 0.00)
+ (y 0.00)))
+(
+ (fill-rect-with-color
+ (extent at (412,0) size 100x100)
+ (rect at (412,0) size 100x100)
+ (color #0000FF)))
+
+replayed:
+(
+ (translate
+ (x 0.00)
+ (y 0.00)))
</ins></span></pre></div>
<a id="trunkLayoutTestsdisplaylistsreplayskipclippedrecthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/displaylists/replay-skip-clipped-rect.html (0 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/displaylists/replay-skip-clipped-rect.html         (rev 0)
+++ trunk/LayoutTests/displaylists/replay-skip-clipped-rect.html        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ #clipper {
+ height: 200px;
+ width: 200px;
+ overflow: hidden;
+ -webkit-transform: translateZ(0);
+ }
+ #target {
+ /* Tiled layer, shifted to show the second tile. */
+ height: 200px;
+ width: 3200px;
+ -webkit-transform: translate3d(-512px, 0, 0);
+ }
+
+ .shadowed {
+ /* Just outside the second tile. */
+ margin-left: 412px;
+ width: 100px;
+ height: 100px;
+ background-color: blue;
+ }
+
+ </style>
+ <script src="resources/dump-target-replay-list.js"></script>
+</head>
+<body>
+
+<div id="clipper">
+ <div id="target">
+ <div class="shadowed">
+ </div>
+ </div>
+</div>
+
+<pre id="output"></pre>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestsdisplaylistsresourcesdumptargetreplaylistjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/displaylists/resources/dump-target-replay-list.js (0 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/displaylists/resources/dump-target-replay-list.js         (rev 0)
+++ trunk/LayoutTests/displaylists/resources/dump-target-replay-list.js        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+if (window.testRunner)
+ testRunner.dumpAsText();
+
+var targetDiv;
+function doTest()
+{
+ document.body.offsetWidth;
+ targetDiv = document.getElementById('target');
+ if (window.internals) {
+ internals.setElementUsesDisplayListDrawing(targetDiv, true);
+ internals.setElementTracksDisplayListReplay(targetDiv, true);
+ }
+
+ if (window.testRunner)
+ testRunner.display();
+
+ if (window.internals) {
+ var displayList = internals.displayListForElement(targetDiv);
+ var replayList = internals.replayDisplayListForElement(targetDiv);
+ document.getElementById('output').textContent = 'recorded: ' + displayList + '\n\nreplayed: ' + replayList;
+ }
+}
+window.addEventListener('load', doTest, false);
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/ChangeLog        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -1,3 +1,54 @@
</span><ins>+2016-01-24 Simon Fraser <simon.fraser@apple.com>
+
+ Add testing for display list replay, and skip clipped-out items on replay
+ https://bugs.webkit.org/show_bug.cgi?id=153408
+
+ Reviewed by Zalan Bujtas.
+
+ Make it possible to save and serialize a DisplayList of Items which were
+ actually applied on replay, so that replay-time optimizations can be tested.
+
+ This exposes internals.setElementTracksDisplayListReplay() and
+ internals.replayDisplayListForElement().
+
+ Do a trivial replay-time optimization, which is to skip items whose extents are
+ outside the replay clip.
+
+ Test: displaylists/replay-skip-clipped-rect.html
+
+ * platform/graphics/GraphicsLayer.cpp:
+ (WebCore::GraphicsLayer::GraphicsLayer):
+ * platform/graphics/GraphicsLayer.h:
+ (WebCore::GraphicsLayer::setIsTrackingDisplayListReplay):
+ (WebCore::GraphicsLayer::isTrackingDisplayListReplay):
+ (WebCore::GraphicsLayer::replayDisplayListAsText):
+ * platform/graphics/ca/GraphicsLayerCA.cpp:
+ (WebCore::layerDisplayListMap): Use a singleton map to store the replay display lists
+ to avoid bloating GraphicsLayerCA for test-only code. The map stores a pair of the
+ replay list and a clip rect, which are both dumped. Dumping the clip rect ensures that
+ we're reporting the replay for the correct tile in a test (since there will be a replay
+ for each tile).
+ (WebCore::GraphicsLayerCA::~GraphicsLayerCA):
+ (WebCore::GraphicsLayerCA::platformCALayerPaintContents):
+ (WebCore::GraphicsLayerCA::setIsTrackingDisplayListReplay):
+ (WebCore::GraphicsLayerCA::replayDisplayListAsText):
+ * platform/graphics/ca/GraphicsLayerCA.h:
+ * platform/graphics/displaylists/DisplayList.h:
+ (WebCore::DisplayList::DisplayList::appendItem):
+ * platform/graphics/displaylists/DisplayListReplayer.cpp:
+ (WebCore::DisplayList::Replayer::replay): In the unlikely event of tracking replays,
+ allocate a new DisplayList and append to it items which actually get applied.
+ * platform/graphics/displaylists/DisplayListReplayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::setIsTrackingDisplayListReplay):
+ (WebCore::RenderLayerBacking::replayDisplayListAsText):
+ * rendering/RenderLayerBacking.h:
+ * testing/Internals.cpp:
+ (WebCore::Internals::setElementTracksDisplayListReplay):
+ (WebCore::Internals::replayDisplayListForElement):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
</ins><span class="cx"> 2016-01-23 Wonchul Lee <wonchul.lee@collabora.co.uk>
</span><span class="cx">
</span><span class="cx"> [GTK] Fix media controls displaying without controls attribute
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -127,6 +127,7 @@
</span><span class="cx"> , m_showDebugBorder(false)
</span><span class="cx"> , m_showRepaintCounter(false)
</span><span class="cx"> , m_isMaskLayer(false)
</span><ins>+ , m_isTrackingDisplayListReplay(false)
</ins><span class="cx"> , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
</span><span class="cx"> , m_contentsOrientation(CompositingCoordinatesTopDown)
</span><span class="cx"> , m_parent(nullptr)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsLayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -524,6 +524,10 @@
</span><span class="cx"> // For testing.
</span><span class="cx"> WEBCORE_EXPORT virtual String displayListAsText(DisplayList::AsTextFlags) const { return String(); }
</span><span class="cx">
</span><ins>+ WEBCORE_EXPORT virtual void setIsTrackingDisplayListReplay(bool isTracking) { m_isTrackingDisplayListReplay = isTracking; }
+ WEBCORE_EXPORT virtual bool isTrackingDisplayListReplay() const { return m_isTrackingDisplayListReplay; }
+ WEBCORE_EXPORT virtual String replayDisplayListAsText(DisplayList::AsTextFlags) const { return String(); }
+
</ins><span class="cx"> // Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers.
</span><span class="cx"> WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const;
</span><span class="cx">
</span><span class="lines">@@ -621,6 +625,7 @@
</span><span class="cx"> bool m_showDebugBorder : 1;
</span><span class="cx"> bool m_showRepaintCounter : 1;
</span><span class="cx"> bool m_isMaskLayer : 1;
</span><ins>+ bool m_isTrackingDisplayListReplay : 1;
</ins><span class="cx">
</span><span class="cx"> GraphicsLayerPaintingPhase m_paintingPhase;
</span><span class="cx"> CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> #include <limits.h>
</span><span class="cx"> #include <wtf/CurrentTime.h>
</span><span class="cx"> #include <wtf/MathExtras.h>
</span><ins>+#include <wtf/NeverDestroyed.h>
</ins><span class="cx"> #include <wtf/SystemTracing.h>
</span><span class="cx"> #include <wtf/TemporaryChange.h>
</span><span class="cx"> #include <wtf/text/WTFString.h>
</span><span class="lines">@@ -357,6 +358,14 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+typedef HashMap<const GraphicsLayerCA*, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>> LayerDisplayListHashMap;
+
+static LayerDisplayListHashMap& layerDisplayListMap()
+{
+ static NeverDestroyed<LayerDisplayListHashMap> sharedHashMap;
+ return sharedHashMap;
+}
+
</ins><span class="cx"> GraphicsLayerCA::GraphicsLayerCA(Type layerType, GraphicsLayerClient& client)
</span><span class="cx"> : GraphicsLayer(layerType, client)
</span><span class="cx"> , m_needsFullRepaint(false)
</span><span class="lines">@@ -390,6 +399,9 @@
</span><span class="cx">
</span><span class="cx"> GraphicsLayerCA::~GraphicsLayerCA()
</span><span class="cx"> {
</span><ins>+ if (UNLIKELY(isTrackingDisplayListReplay()))
+ layerDisplayListMap().remove(this);
+
</ins><span class="cx"> // Do cleanup while we can still safely call methods on the derived class.
</span><span class="cx"> willBeDestroyed();
</span><span class="cx"> }
</span><span class="lines">@@ -1445,7 +1457,13 @@
</span><span class="cx"> m_hasEverPainted = true;
</span><span class="cx"> if (m_displayList) {
</span><span class="cx"> DisplayList::Replayer replayer(context, *m_displayList);
</span><del>- replayer.replay(clip);
</del><ins>+
+ if (UNLIKELY(isTrackingDisplayListReplay())) {
+ auto replayList = replayer.replay(clip, isTrackingDisplayListReplay());
+ layerDisplayListMap().add(this, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>(clip, WTFMove(replayList)));
+ } else
+ replayer.replay(clip);
+
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -3279,6 +3297,32 @@
</span><span class="cx"> return m_displayList->asText(flags);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void GraphicsLayerCA::setIsTrackingDisplayListReplay(bool isTracking)
+{
+ if (isTracking == m_isTrackingDisplayListReplay)
+ return;
+
+ m_isTrackingDisplayListReplay = isTracking;
+ if (!m_isTrackingDisplayListReplay)
+ layerDisplayListMap().remove(this);
+}
+
+String GraphicsLayerCA::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
+{
+ auto it = layerDisplayListMap().find(this);
+ if (it != layerDisplayListMap().end()) {
+ TextStream stream;
+
+ TextStream::GroupScope scope(stream);
+ stream.dumpProperty("clip", it->value.first);
+ stream << it->value.second->asText(flags);
+ return stream.release();
+
+ }
+
+ return String();
+}
+
</ins><span class="cx"> void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
</span><span class="cx"> {
</span><span class="cx"> if (color.isValid())
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -210,6 +210,9 @@
</span><span class="cx">
</span><span class="cx"> WEBCORE_EXPORT virtual String displayListAsText(DisplayList::AsTextFlags) const override;
</span><span class="cx">
</span><ins>+ WEBCORE_EXPORT virtual void setIsTrackingDisplayListReplay(bool) override;
+ WEBCORE_EXPORT virtual String replayDisplayListAsText(DisplayList::AsTextFlags) const override;
+
</ins><span class="cx"> WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const override;
</span><span class="cx">
</span><span class="cx"> WEBCORE_EXPORT virtual bool shouldRepaintOnSizeChange() const override;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> class DisplayList {
</span><span class="cx"> WTF_MAKE_NONCOPYABLE(DisplayList);
</span><span class="cx"> friend class Recorder;
</span><ins>+ friend class Replayer;
</ins><span class="cx"> public:
</span><span class="cx"> DisplayList() = default;
</span><span class="cx"> DisplayList(DisplayList&&) = default;
</span><span class="lines">@@ -65,7 +66,7 @@
</span><span class="cx"> ASSERT(index < m_list.size());
</span><span class="cx"> return m_list[index].get();
</span><span class="cx"> }
</span><del>-
</del><ins>+
</ins><span class="cx"> void clear();
</span><span class="cx"> void removeItemsFromIndex(size_t);
</span><span class="cx">
</span><span class="lines">@@ -86,6 +87,12 @@
</span><span class="cx"> return m_list.last().get();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ // Less efficient append, only used for tracking replay.
+ void appendItem(Item& item)
+ {
+ m_list.append(item);
+ }
+
</ins><span class="cx"> static bool shouldDumpForFlags(AsTextFlags, const Item&);
</span><span class="cx">
</span><span class="cx"> Vector<Ref<Item>>& list() { return m_list; }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListReplayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -26,7 +26,6 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "DisplayListReplayer.h"
</span><span class="cx">
</span><del>-#include "DisplayList.h"
</del><span class="cx"> #include "DisplayListItems.h"
</span><span class="cx"> #include "GraphicsContext.h"
</span><span class="cx"> #include "Logging.h"
</span><span class="lines">@@ -45,17 +44,35 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void Replayer::replay(const FloatRect& initialClip)
</del><ins>+std::unique_ptr<DisplayList> Replayer::replay(const FloatRect& initialClip, bool trackReplayList)
</ins><span class="cx"> {
</span><span class="cx"> LOG_WITH_STREAM(DisplayLists, stream << "\nReplaying with clip " << initialClip);
</span><span class="cx"> UNUSED_PARAM(initialClip);
</span><span class="cx">
</span><ins>+ std::unique_ptr<DisplayList> replayList;
+ if (UNLIKELY(trackReplayList))
+ replayList = std::make_unique<DisplayList>();
+
</ins><span class="cx"> size_t numItems = m_displayList.itemCount();
</span><span class="cx"> for (size_t i = 0; i < numItems; ++i) {
</span><span class="cx"> auto& item = m_displayList.list()[i].get();
</span><del>- LOG_WITH_STREAM(DisplayLists, stream << "drawing " << i << " " << item);
</del><ins>+
+ if (is<DrawingItem>(item)) {
+ const DrawingItem& drawingItem = downcast<DrawingItem>(item);
+ if (drawingItem.extentKnown() && !drawingItem.extent().intersects(initialClip)) {
+ LOG_WITH_STREAM(DisplayLists, stream << "skipping " << i << " " << item);
+ continue;
+ }
+ }
+
+ LOG_WITH_STREAM(DisplayLists, stream << "applying " << i << " " << item);
</ins><span class="cx"> item.apply(m_context);
</span><ins>+
+ if (UNLIKELY(trackReplayList))
+ replayList->appendItem(const_cast<Item&>(item));
</ins><span class="cx"> }
</span><ins>+
+ return replayList;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace DisplayList
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListReplayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -26,7 +26,9 @@
</span><span class="cx"> #ifndef DisplayListReplayer_h
</span><span class="cx"> #define DisplayListReplayer_h
</span><span class="cx">
</span><ins>+#include "DisplayList.h"
</ins><span class="cx"> #include <wtf/Noncopyable.h>
</span><ins>+#include <wtf/text/WTFString.h>
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="lines">@@ -35,16 +37,14 @@
</span><span class="cx">
</span><span class="cx"> namespace DisplayList {
</span><span class="cx">
</span><del>-class DisplayList;
-
</del><span class="cx"> class Replayer {
</span><span class="cx"> WTF_MAKE_NONCOPYABLE(Replayer);
</span><span class="cx"> public:
</span><span class="cx"> Replayer(GraphicsContext&, const DisplayList&);
</span><span class="cx"> ~Replayer();
</span><span class="cx">
</span><del>- void replay(const FloatRect& initialClip);
-
</del><ins>+ std::unique_ptr<DisplayList> replay(const FloatRect& initialClip, bool trackReplayList = false);
+
</ins><span class="cx"> private:
</span><span class="cx"> const DisplayList& m_displayList;
</span><span class="cx"> GraphicsContext& m_context;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -198,6 +198,16 @@
</span><span class="cx"> return m_graphicsLayer->displayListAsText(flags);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void RenderLayerBacking::setIsTrackingDisplayListReplay(bool isTrackingReplay)
+{
+ m_graphicsLayer->setIsTrackingDisplayListReplay(isTrackingReplay);
+}
+
+String RenderLayerBacking::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
+{
+ return m_graphicsLayer->replayDisplayListAsText(flags);
+}
+
</ins><span class="cx"> void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
</span><span class="cx"> {
</span><span class="cx"> compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.h        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -245,6 +245,9 @@
</span><span class="cx"> WEBCORE_EXPORT void setUsesDisplayListDrawing(bool);
</span><span class="cx"> WEBCORE_EXPORT String displayListAsText(DisplayList::AsTextFlags) const;
</span><span class="cx">
</span><ins>+ WEBCORE_EXPORT void setIsTrackingDisplayListReplay(bool);
+ WEBCORE_EXPORT String replayDisplayListAsText(DisplayList::AsTextFlags) const;
+
</ins><span class="cx"> LayoutSize devicePixelFractionFromRenderer() const { return m_devicePixelFractionFromRenderer; }
</span><span class="cx">
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/testing/Internals.cpp        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -1996,6 +1996,28 @@
</span><span class="cx"> layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void Internals::setElementTracksDisplayListReplay(Element* element, bool isTrackingReplay, ExceptionCode& ec)
+{
+ Document* document = contextDocument();
+ if (!document || !document->renderView()) {
+ ec = INVALID_ACCESS_ERR;
+ return;
+ }
+
+ if (!element || !element->renderer() || !element->renderer()->hasLayer()) {
+ ec = INVALID_ACCESS_ERR;
+ return;
+ }
+
+ RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer();
+ if (!layer->isComposited()) {
+ ec = INVALID_ACCESS_ERR;
+ return;
+ }
+
+ layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay);
+}
+
</ins><span class="cx"> String Internals::displayListForElement(Element* element, ExceptionCode& ec)
</span><span class="cx"> {
</span><span class="cx"> return displayListForElement(element, 0, ec);
</span><span class="lines">@@ -2027,6 +2049,37 @@
</span><span class="cx"> return layer->backing()->displayListAsText(displayListFlags);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+String Internals::replayDisplayListForElement(Element* element, ExceptionCode& ec)
+{
+ return replayDisplayListForElement(element, 0, ec);
+}
+
+String Internals::replayDisplayListForElement(Element* element, unsigned flags, ExceptionCode& ec)
+{
+ Document* document = contextDocument();
+ if (!document || !document->renderView()) {
+ ec = INVALID_ACCESS_ERR;
+ return String();
+ }
+
+ if (!element || !element->renderer() || !element->renderer()->hasLayer()) {
+ ec = INVALID_ACCESS_ERR;
+ return String();
+ }
+
+ RenderLayer* layer = downcast<RenderLayerModelObject>(element->renderer())->layer();
+ if (!layer->isComposited()) {
+ ec = INVALID_ACCESS_ERR;
+ return String();
+ }
+
+ DisplayList::AsTextFlags displayListFlags = 0;
+ if (flags & DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS)
+ displayListFlags |= DisplayList::AsTextFlag::IncludesPlatformOperations;
+
+ return layer->backing()->replayDisplayListAsText(displayListFlags);
+}
+
</ins><span class="cx"> void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
</span><span class="cx"> {
</span><span class="cx"> Document* document = contextDocument();
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.h (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.h        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/testing/Internals.h        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -254,6 +254,7 @@
</span><span class="cx"> RefPtr<ClientRectList> nonFastScrollableRects(ExceptionCode&) const;
</span><span class="cx">
</span><span class="cx"> void setElementUsesDisplayListDrawing(Element*, bool usesDisplayListDrawing, ExceptionCode&);
</span><ins>+ void setElementTracksDisplayListReplay(Element*, bool isTrackingReplay, ExceptionCode&);
</ins><span class="cx">
</span><span class="cx"> enum {
</span><span class="cx"> // Values need to be kept in sync with Internals.idl.
</span><span class="lines">@@ -262,6 +263,9 @@
</span><span class="cx"> String displayListForElement(Element*, unsigned flags, ExceptionCode&);
</span><span class="cx"> String displayListForElement(Element*, ExceptionCode&);
</span><span class="cx">
</span><ins>+ String replayDisplayListForElement(Element*, unsigned flags, ExceptionCode&);
+ String replayDisplayListForElement(Element*, ExceptionCode&);
+
</ins><span class="cx"> void garbageCollectDocumentResources(ExceptionCode&) const;
</span><span class="cx">
</span><span class="cx"> void insertAuthorCSS(const String&, ExceptionCode&) const;
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalsidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.idl (195514 => 195515)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.idl        2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/Source/WebCore/testing/Internals.idl        2016-01-24 20:39:42 UTC (rev 195515)
</span><span class="lines">@@ -226,10 +226,14 @@
</span><span class="cx">
</span><span class="cx"> // These throw if the element does not have a compositing layer.
</span><span class="cx"> [RaisesException] void setElementUsesDisplayListDrawing(Element element, boolean usesDisplayListDrawing);
</span><ins>+ [RaisesException] void setElementTracksDisplayListReplay(Element element, boolean trackReplay);
</ins><span class="cx">
</span><span class="cx"> // Flags for displayListForElement.
</span><span class="cx"> const unsigned short DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS = 1;
</span><ins>+ // Returns the recorded display list.
</ins><span class="cx"> [RaisesException] DOMString displayListForElement(Element element, optional unsigned short flags);
</span><ins>+ // Returns the display list that was actually painted.
+ [RaisesException] DOMString replayDisplayListForElement(Element element, optional unsigned short flags);
</ins><span class="cx">
</span><span class="cx"> [RaisesException] void garbageCollectDocumentResources();
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>