Diff
Modified: trunk/LayoutTests/ChangeLog (195514 => 195515)
--- trunk/LayoutTests/ChangeLog 2016-01-24 20:39:27 UTC (rev 195514)
+++ trunk/LayoutTests/ChangeLog 2016-01-24 20:39:42 UTC (rev 195515)
@@ -1,3 +1,22 @@
+2016-01-24 Simon Fraser <[email protected]>
+
+ 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):
+
2016-01-23 Simon Fraser <[email protected]>
Layout Test displaylists/extent-includes-transforms.html is flaky on mac-wk1
Added: trunk/LayoutTests/displaylists/replay-skip-clipped-rect-expected.txt (0 => 195515)
--- 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)
@@ -0,0 +1,16 @@
+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)))
Added: trunk/LayoutTests/displaylists/replay-skip-clipped-rect.html (0 => 195515)
--- 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)
@@ -0,0 +1,41 @@
+<!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=""
+</head>
+<body>
+
+<div id="clipper">
+ <div id="target">
+ <div class="shadowed">
+ </div>
+ </div>
+</div>
+
+<pre id="output"></pre>
+</body>
+</html>
Added: trunk/LayoutTests/displaylists/resources/dump-target-replay-list.js (0 => 195515)
--- 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)
@@ -0,0 +1,23 @@
+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);
Modified: trunk/Source/WebCore/ChangeLog (195514 => 195515)
--- 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)
@@ -1,3 +1,54 @@
+2016-01-24 Simon Fraser <[email protected]>
+
+ 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:
+
2016-01-23 Wonchul Lee <[email protected]>
[GTK] Fix media controls displaying without controls attribute
Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.cpp (195514 => 195515)
--- 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)
@@ -127,6 +127,7 @@
, m_showDebugBorder(false)
, m_showRepaintCounter(false)
, m_isMaskLayer(false)
+ , m_isTrackingDisplayListReplay(false)
, m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip)
, m_contentsOrientation(CompositingCoordinatesTopDown)
, m_parent(nullptr)
Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (195514 => 195515)
--- 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)
@@ -524,6 +524,10 @@
// For testing.
WEBCORE_EXPORT virtual String displayListAsText(DisplayList::AsTextFlags) const { return String(); }
+ 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(); }
+
// Return an estimate of the backing store memory cost (in bytes). May be incorrect for tiled layers.
WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const;
@@ -621,6 +625,7 @@
bool m_showDebugBorder : 1;
bool m_showRepaintCounter : 1;
bool m_isMaskLayer : 1;
+ bool m_isTrackingDisplayListReplay : 1;
GraphicsLayerPaintingPhase m_paintingPhase;
CompositingCoordinatesOrientation m_contentsOrientation; // affects orientation of layer contents
Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (195514 => 195515)
--- 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)
@@ -47,6 +47,7 @@
#include <limits.h>
#include <wtf/CurrentTime.h>
#include <wtf/MathExtras.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/SystemTracing.h>
#include <wtf/TemporaryChange.h>
#include <wtf/text/WTFString.h>
@@ -357,6 +358,14 @@
#endif
}
+typedef HashMap<const GraphicsLayerCA*, std::pair<FloatRect, std::unique_ptr<DisplayList::DisplayList>>> LayerDisplayListHashMap;
+
+static LayerDisplayListHashMap& layerDisplayListMap()
+{
+ static NeverDestroyed<LayerDisplayListHashMap> sharedHashMap;
+ return sharedHashMap;
+}
+
GraphicsLayerCA::GraphicsLayerCA(Type layerType, GraphicsLayerClient& client)
: GraphicsLayer(layerType, client)
, m_needsFullRepaint(false)
@@ -390,6 +399,9 @@
GraphicsLayerCA::~GraphicsLayerCA()
{
+ if (UNLIKELY(isTrackingDisplayListReplay()))
+ layerDisplayListMap().remove(this);
+
// Do cleanup while we can still safely call methods on the derived class.
willBeDestroyed();
}
@@ -1445,7 +1457,13 @@
m_hasEverPainted = true;
if (m_displayList) {
DisplayList::Replayer replayer(context, *m_displayList);
- replayer.replay(clip);
+
+ 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);
+
return;
}
@@ -3279,6 +3297,32 @@
return m_displayList->asText(flags);
}
+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();
+}
+
void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
{
if (color.isValid())
Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (195514 => 195515)
--- 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)
@@ -210,6 +210,9 @@
WEBCORE_EXPORT virtual String displayListAsText(DisplayList::AsTextFlags) const override;
+ WEBCORE_EXPORT virtual void setIsTrackingDisplayListReplay(bool) override;
+ WEBCORE_EXPORT virtual String replayDisplayListAsText(DisplayList::AsTextFlags) const override;
+
WEBCORE_EXPORT virtual double backingStoreMemoryEstimate() const override;
WEBCORE_EXPORT virtual bool shouldRepaintOnSizeChange() const override;
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h (195514 => 195515)
--- 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)
@@ -51,6 +51,7 @@
class DisplayList {
WTF_MAKE_NONCOPYABLE(DisplayList);
friend class Recorder;
+ friend class Replayer;
public:
DisplayList() = default;
DisplayList(DisplayList&&) = default;
@@ -65,7 +66,7 @@
ASSERT(index < m_list.size());
return m_list[index].get();
}
-
+
void clear();
void removeItemsFromIndex(size_t);
@@ -86,6 +87,12 @@
return m_list.last().get();
}
+ // Less efficient append, only used for tracking replay.
+ void appendItem(Item& item)
+ {
+ m_list.append(item);
+ }
+
static bool shouldDumpForFlags(AsTextFlags, const Item&);
Vector<Ref<Item>>& list() { return m_list; }
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp (195514 => 195515)
--- 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)
@@ -26,7 +26,6 @@
#include "config.h"
#include "DisplayListReplayer.h"
-#include "DisplayList.h"
#include "DisplayListItems.h"
#include "GraphicsContext.h"
#include "Logging.h"
@@ -45,17 +44,35 @@
{
}
-void Replayer::replay(const FloatRect& initialClip)
+std::unique_ptr<DisplayList> Replayer::replay(const FloatRect& initialClip, bool trackReplayList)
{
LOG_WITH_STREAM(DisplayLists, stream << "\nReplaying with clip " << initialClip);
UNUSED_PARAM(initialClip);
+ std::unique_ptr<DisplayList> replayList;
+ if (UNLIKELY(trackReplayList))
+ replayList = std::make_unique<DisplayList>();
+
size_t numItems = m_displayList.itemCount();
for (size_t i = 0; i < numItems; ++i) {
auto& item = m_displayList.list()[i].get();
- LOG_WITH_STREAM(DisplayLists, stream << "drawing " << i << " " << item);
+
+ 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);
item.apply(m_context);
+
+ if (UNLIKELY(trackReplayList))
+ replayList->appendItem(const_cast<Item&>(item));
}
+
+ return replayList;
}
} // namespace DisplayList
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h (195514 => 195515)
--- 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)
@@ -26,7 +26,9 @@
#ifndef DisplayListReplayer_h
#define DisplayListReplayer_h
+#include "DisplayList.h"
#include <wtf/Noncopyable.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -35,16 +37,14 @@
namespace DisplayList {
-class DisplayList;
-
class Replayer {
WTF_MAKE_NONCOPYABLE(Replayer);
public:
Replayer(GraphicsContext&, const DisplayList&);
~Replayer();
- void replay(const FloatRect& initialClip);
-
+ std::unique_ptr<DisplayList> replay(const FloatRect& initialClip, bool trackReplayList = false);
+
private:
const DisplayList& m_displayList;
GraphicsContext& m_context;
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (195514 => 195515)
--- 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)
@@ -198,6 +198,16 @@
return m_graphicsLayer->displayListAsText(flags);
}
+void RenderLayerBacking::setIsTrackingDisplayListReplay(bool isTrackingReplay)
+{
+ m_graphicsLayer->setIsTrackingDisplayListReplay(isTrackingReplay);
+}
+
+String RenderLayerBacking::replayDisplayListAsText(DisplayList::AsTextFlags flags) const
+{
+ return m_graphicsLayer->replayDisplayListAsText(flags);
+}
+
void RenderLayerBacking::tiledBackingUsageChanged(const GraphicsLayer* layer, bool usingTiledBacking)
{
compositor().layerTiledBackingUsageChanged(layer, usingTiledBacking);
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (195514 => 195515)
--- 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)
@@ -245,6 +245,9 @@
WEBCORE_EXPORT void setUsesDisplayListDrawing(bool);
WEBCORE_EXPORT String displayListAsText(DisplayList::AsTextFlags) const;
+ WEBCORE_EXPORT void setIsTrackingDisplayListReplay(bool);
+ WEBCORE_EXPORT String replayDisplayListAsText(DisplayList::AsTextFlags) const;
+
LayoutSize devicePixelFractionFromRenderer() const { return m_devicePixelFractionFromRenderer; }
private:
Modified: trunk/Source/WebCore/testing/Internals.cpp (195514 => 195515)
--- 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)
@@ -1996,6 +1996,28 @@
layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
}
+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);
+}
+
String Internals::displayListForElement(Element* element, ExceptionCode& ec)
{
return displayListForElement(element, 0, ec);
@@ -2027,6 +2049,37 @@
return layer->backing()->displayListAsText(displayListFlags);
}
+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);
+}
+
void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
{
Document* document = contextDocument();
Modified: trunk/Source/WebCore/testing/Internals.h (195514 => 195515)
--- 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)
@@ -254,6 +254,7 @@
RefPtr<ClientRectList> nonFastScrollableRects(ExceptionCode&) const;
void setElementUsesDisplayListDrawing(Element*, bool usesDisplayListDrawing, ExceptionCode&);
+ void setElementTracksDisplayListReplay(Element*, bool isTrackingReplay, ExceptionCode&);
enum {
// Values need to be kept in sync with Internals.idl.
@@ -262,6 +263,9 @@
String displayListForElement(Element*, unsigned flags, ExceptionCode&);
String displayListForElement(Element*, ExceptionCode&);
+ String replayDisplayListForElement(Element*, unsigned flags, ExceptionCode&);
+ String replayDisplayListForElement(Element*, ExceptionCode&);
+
void garbageCollectDocumentResources(ExceptionCode&) const;
void insertAuthorCSS(const String&, ExceptionCode&) const;
Modified: trunk/Source/WebCore/testing/Internals.idl (195514 => 195515)
--- 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)
@@ -226,10 +226,14 @@
// These throw if the element does not have a compositing layer.
[RaisesException] void setElementUsesDisplayListDrawing(Element element, boolean usesDisplayListDrawing);
+ [RaisesException] void setElementTracksDisplayListReplay(Element element, boolean trackReplay);
// Flags for displayListForElement.
const unsigned short DISPLAY_LIST_INCLUDES_PLATFORM_OPERATIONS = 1;
+ // Returns the recorded display list.
[RaisesException] DOMString displayListForElement(Element element, optional unsigned short flags);
+ // Returns the display list that was actually painted.
+ [RaisesException] DOMString replayDisplayListForElement(Element element, optional unsigned short flags);
[RaisesException] void garbageCollectDocumentResources();