<!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>[194708] trunk/Source/WebCore</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/194708">194708</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2016-01-07 11:53:31 -0800 (Thu, 07 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Initial implementation files for display-list recording and playback
https://bugs.webkit.org/show_bug.cgi?id=152816

Reviewed by Zalan Bujtas.

Add files for:
- DisplayList, a class that holds a vector of display items, and in the future will hold metadata
  on the list for optimizations etc.
- DisplayList::Recorder, the outward-facing recording API which GraphicsContext will
  call into.
- DisplayList::Replayer, which plays back a DisplayList, possibly applying optimizations.
- Various DisplayList::Items, one type for each display list operation. They cover most of the
  GraphicsContext functionality, other than clipping to an image buffer. Text drawing is stubbed
  out for now.

Added a &quot;DisplayLists&quot; log channel.

Added GraphicsContextState functions for tracking state deltas with change bits. It may
make sense to combine GraphicsContextStateChange and GraphicsContextState, and use the
dirty bits in non-display-list drawing as well.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/Logging.h:
* platform/graphics/GraphicsContext.h:
* platform/graphics/displaylists/DisplayList.cpp: Added.
(WebCore::DisplayList::DisplayList::description):
(WebCore::DisplayList::DisplayList::dump):
(WebCore::operator&lt;&lt;):
* platform/graphics/displaylists/DisplayListItems.cpp: Added.
* platform/graphics/displaylists/DisplayListItems.h: Added.
* platform/graphics/displaylists/DisplayListRecorder.cpp: Added.
* platform/graphics/displaylists/DisplayListRecorder.h: Added.
* platform/graphics/displaylists/DisplayListReplayer.cpp: Added.
(WebCore::DisplayList::Replayer::Replayer):
(WebCore::DisplayList::Replayer::~Replayer):
(WebCore::DisplayList::Replayer::replay):
* platform/graphics/displaylists/DisplayListReplayer.h: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformLoggingh">trunk/Source/WebCore/platform/Logging.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContextcpp">trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsContexth">trunk/Source/WebCore/platform/graphics/GraphicsContext.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/Source/WebCore/platform/graphics/displaylists/</li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListcpp">trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListh">trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListItemscpp">trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListItemsh">trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListRecordercpp">trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListRecorderh">trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (194707 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-01-07 19:42:49 UTC (rev 194707)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -70,6 +70,7 @@
</span><span class="cx">     &quot;${WEBCORE_DIR}/platform/graphics&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/platform/graphics/cpu/arm&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/platform/graphics/cpu/arm/filters&quot;
</span><ins>+    &quot;${WEBCORE_DIR}/platform/graphics/displaylists&quot;
</ins><span class="cx">     &quot;${WEBCORE_DIR}/platform/graphics/filters&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/platform/graphics/filters/texmap&quot;
</span><span class="cx">     &quot;${WEBCORE_DIR}/platform/graphics/harfbuzz&quot;
</span><span class="lines">@@ -2215,6 +2216,11 @@
</span><span class="cx"> 
</span><span class="cx">     platform/graphics/cpu/arm/filters/FELightingNEON.cpp
</span><span class="cx"> 
</span><ins>+    platform/graphics/displaylists/DisplayList.cpp
+    platform/graphics/displaylists/DisplayListItems.cpp
+    platform/graphics/displaylists/DisplayListRecorder.cpp
+    platform/graphics/displaylists/DisplayListReplayer.cpp
+
</ins><span class="cx">     platform/graphics/filters/DistantLightSource.cpp
</span><span class="cx">     platform/graphics/filters/FEBlend.cpp
</span><span class="cx">     platform/graphics/filters/FEColorMatrix.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (194707 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-07 19:42:49 UTC (rev 194707)
+++ trunk/Source/WebCore/ChangeLog        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2016-01-06  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Initial implementation files for display-list recording and playback
+        https://bugs.webkit.org/show_bug.cgi?id=152816
+
+        Reviewed by Zalan Bujtas.
+
+        Add files for:
+        - DisplayList, a class that holds a vector of display items, and in the future will hold metadata
+          on the list for optimizations etc.
+        - DisplayList::Recorder, the outward-facing recording API which GraphicsContext will
+          call into.
+        - DisplayList::Replayer, which plays back a DisplayList, possibly applying optimizations.
+        - Various DisplayList::Items, one type for each display list operation. They cover most of the
+          GraphicsContext functionality, other than clipping to an image buffer. Text drawing is stubbed
+          out for now.
+
+        Added a &quot;DisplayLists&quot; log channel.
+
+        Added GraphicsContextState functions for tracking state deltas with change bits. It may
+        make sense to combine GraphicsContextStateChange and GraphicsContextState, and use the
+        dirty bits in non-display-list drawing as well.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/Logging.h:
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/displaylists/DisplayList.cpp: Added.
+        (WebCore::DisplayList::DisplayList::description):
+        (WebCore::DisplayList::DisplayList::dump):
+        (WebCore::operator&lt;&lt;):
+        * platform/graphics/displaylists/DisplayListItems.cpp: Added.
+        * platform/graphics/displaylists/DisplayListItems.h: Added.
+        * platform/graphics/displaylists/DisplayListRecorder.cpp: Added.
+        * platform/graphics/displaylists/DisplayListRecorder.h: Added.
+        * platform/graphics/displaylists/DisplayListReplayer.cpp: Added.
+        (WebCore::DisplayList::Replayer::Replayer):
+        (WebCore::DisplayList::Replayer::~Replayer):
+        (WebCore::DisplayList::Replayer::replay):
+        * platform/graphics/displaylists/DisplayListReplayer.h: Added.
+
</ins><span class="cx"> 2016-01-07  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Directly-composited animated GIFs never resume once scrolled offscreen
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (194707 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-07 19:42:49 UTC (rev 194707)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -550,6 +550,14 @@
</span><span class="cx">                 0FDF45A91BD1C82500E4FA8C /* TimingFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF45A81BD1C82500E4FA8C /* TimingFunction.cpp */; };
</span><span class="cx">                 0FE5806319327A6200DE32EB /* ScrollingTreeMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5806119327A6200DE32EB /* ScrollingTreeMac.cpp */; };
</span><span class="cx">                 0FE5806419327A6200DE32EB /* ScrollingTreeMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5806219327A6200DE32EB /* ScrollingTreeMac.h */; };
</span><ins>+                0FE5FBD21C3DD51E0007A2CA /* DisplayList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */; };
+                0FE5FBD31C3DD51E0007A2CA /* DisplayList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */; };
+                0FE5FBD41C3DD51E0007A2CA /* DisplayListItems.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */; };
+                0FE5FBD51C3DD51E0007A2CA /* DisplayListItems.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */; };
+                0FE5FBD61C3DD51E0007A2CA /* DisplayListRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */; };
+                0FE5FBD71C3DD51E0007A2CA /* DisplayListRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */; };
+                0FE5FBD81C3DD51E0007A2CA /* DisplayListReplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */; };
+                0FE5FBD91C3DD51E0007A2CA /* DisplayListReplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */; };
</ins><span class="cx">                 0FE71405142170B800DB33BA /* ScrollbarThemeMock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */; };
</span><span class="cx">                 0FE71406142170B800DB33BA /* ScrollbarThemeMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */; };
</span><span class="cx">                 0FEA3E7B191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA3E79191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -7839,6 +7847,14 @@
</span><span class="cx">                 0FDF45A81BD1C82500E4FA8C /* TimingFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimingFunction.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE5806119327A6200DE32EB /* ScrollingTreeMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeMac.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE5806219327A6200DE32EB /* ScrollingTreeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeMac.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayList.cpp; path = displaylists/DisplayList.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayList.h; path = displaylists/DisplayList.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListItems.cpp; path = displaylists/DisplayListItems.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListItems.h; path = displaylists/DisplayListItems.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListRecorder.cpp; path = displaylists/DisplayListRecorder.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListRecorder.h; path = displaylists/DisplayListRecorder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListReplayer.cpp; path = displaylists/DisplayListReplayer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListReplayer.h; path = displaylists/DisplayListReplayer.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarThemeMock.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeMock.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE71415142189FC00DB33BA /* ScrollbarTheme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarTheme.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -15654,6 +15670,21 @@
</span><span class="cx">                         path = ios;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="cx">                 };
</span><ins>+                0FE5FBC91C3DD5060007A2CA /* displaylists */ = {
+                        isa = PBXGroup;
+                        children = (
+                                0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */,
+                                0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */,
+                                0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */,
+                                0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */,
+                                0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */,
+                                0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */,
+                                0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */,
+                                0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */,
+                        );
+                        name = displaylists;
+                        sourceTree = &quot;&lt;group&gt;&quot;;
+                };
</ins><span class="cx">                 14DFB33F0A7DF7630018F769 /* Derived Sources */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><span class="lines">@@ -21529,6 +21560,7 @@
</span><span class="cx">                                 B27535290B053814002CE64F /* cg */,
</span><span class="cx">                                 B5320D68122A24E9002D1440 /* cocoa */,
</span><span class="cx">                                 9332AB3B16515D7700D827EC /* cpu */,
</span><ins>+                                0FE5FBC91C3DD5060007A2CA /* displaylists */,
</ins><span class="cx">                                 A75E8B7F0E1DE2B0007F2481 /* filters */,
</span><span class="cx">                                 498770C11242C50D002226BA /* gpu */,
</span><span class="cx">                                 441AF0A70EBA7BBF0044ED4B /* ios */,
</span><span class="lines">@@ -25068,6 +25100,10 @@
</span><span class="cx">                                 2D5646B01B8F8493003C4994 /* DictionaryPopupInfo.h in Headers */,
</span><span class="cx">                                 FDAF19991513D131008DB0C3 /* DirectConvolver.h in Headers */,
</span><span class="cx">                                 7EDAAFC919A2CCDC0034DFD1 /* DiskCacheMonitorCocoa.h in Headers */,
</span><ins>+                                0FE5FBD31C3DD51E0007A2CA /* DisplayList.h in Headers */,
+                                0FE5FBD51C3DD51E0007A2CA /* DisplayListItems.h in Headers */,
+                                0FE5FBD71C3DD51E0007A2CA /* DisplayListRecorder.h in Headers */,
+                                0FE5FBD91C3DD51E0007A2CA /* DisplayListReplayer.h in Headers */,
</ins><span class="cx">                                 49AF2D6914435D050016A784 /* DisplayRefreshMonitor.h in Headers */,
</span><span class="cx">                                 2D29ECC6192ECC8300984B78 /* DisplayRefreshMonitorClient.h in Headers */,
</span><span class="cx">                                 2D29ECCA192F1F1D00984B78 /* DisplayRefreshMonitorIOS.h in Headers */,
</span><span class="lines">@@ -28902,6 +28938,10 @@
</span><span class="cx">                                 937FF3D71A10131B008EBA31 /* DictionaryLookup.mm in Sources */,
</span><span class="cx">                                 FDAF19981513D131008DB0C3 /* DirectConvolver.cpp in Sources */,
</span><span class="cx">                                 7E4DE10D198B10B60051CB02 /* DiskCacheMonitorCocoa.mm in Sources */,
</span><ins>+                                0FE5FBD21C3DD51E0007A2CA /* DisplayList.cpp in Sources */,
+                                0FE5FBD41C3DD51E0007A2CA /* DisplayListItems.cpp in Sources */,
+                                0FE5FBD61C3DD51E0007A2CA /* DisplayListRecorder.cpp in Sources */,
+                                0FE5FBD81C3DD51E0007A2CA /* DisplayListReplayer.cpp in Sources */,
</ins><span class="cx">                                 49FC7A501444AF5F00A5D864 /* DisplayRefreshMonitor.cpp in Sources */,
</span><span class="cx">                                 2D29ECC5192ECC8300984B78 /* DisplayRefreshMonitorClient.cpp in Sources */,
</span><span class="cx">                                 0F97A658155DA81E00FADD4C /* DisplayRefreshMonitorIOS.mm in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformLoggingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/Logging.h (194707 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/Logging.h        2016-01-07 19:42:49 UTC (rev 194707)
+++ trunk/Source/WebCore/platform/Logging.h        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx">     M(Archives) \
</span><span class="cx">     M(Compositing) \
</span><span class="cx">     M(ContentFiltering) \
</span><ins>+    M(DisplayLists) \
</ins><span class="cx">     M(DOMTimers) \
</span><span class="cx">     M(Editing) \
</span><span class="cx">     M(Events) \
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (194707 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp        2016-01-07 19:42:49 UTC (rev 194707)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;IntRect.h&quot;
</span><span class="cx"> #include &quot;RoundedRect.h&quot;
</span><span class="cx"> #include &quot;TextRun.h&quot;
</span><ins>+#include &quot;TextStream.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -98,6 +99,267 @@
</span><span class="cx">     bool m_interpolationQualityChanged;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+
+#define CHECK_FOR_CHANGED_PROPERTY(flag, property) \
+    if ((m_changeFlags &amp; GraphicsContextState::flag) &amp;&amp; (m_state.property != state.property)) \
+        changeFlags |= GraphicsContextState::flag;
+
+GraphicsContextState::StateChangeFlags GraphicsContextStateChange::changesFromState(const GraphicsContextState&amp; state) const
+{
+    GraphicsContextState::StateChangeFlags changeFlags = GraphicsContextState::NoChange;
+
+    CHECK_FOR_CHANGED_PROPERTY(StrokeGradientChange, strokeGradient);
+    CHECK_FOR_CHANGED_PROPERTY(StrokePatternChange, strokePattern);
+    CHECK_FOR_CHANGED_PROPERTY(FillGradientChange, fillGradient);
+    CHECK_FOR_CHANGED_PROPERTY(FillPatternChange, fillPattern);
+
+    if ((m_changeFlags &amp; GraphicsContextState::ShadowChange)
+        &amp;&amp; (m_state.shadowOffset != state.shadowOffset
+            || m_state.shadowBlur != state.shadowBlur
+            || m_state.shadowColor != state.shadowColor))
+        changeFlags |= GraphicsContextState::ShadowChange;
+
+    CHECK_FOR_CHANGED_PROPERTY(StrokeThicknessChange, strokeThickness);
+    CHECK_FOR_CHANGED_PROPERTY(TextDrawingModeChange, textDrawingMode);
+    CHECK_FOR_CHANGED_PROPERTY(StrokeColorChange, strokeColor);
+    CHECK_FOR_CHANGED_PROPERTY(FillColorChange, fillColor);
+    CHECK_FOR_CHANGED_PROPERTY(StrokeStyleChange, strokeStyle);
+    CHECK_FOR_CHANGED_PROPERTY(FillRuleChange, fillRule);
+    CHECK_FOR_CHANGED_PROPERTY(AlphaChange, alpha);
+
+    if ((m_changeFlags &amp; (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange))
+        &amp;&amp; (m_state.compositeOperator != state.compositeOperator || m_state.blendMode != state.blendMode))
+        changeFlags |= (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange);
+
+    CHECK_FOR_CHANGED_PROPERTY(ShouldAntialiasChange, shouldAntialias);
+    CHECK_FOR_CHANGED_PROPERTY(ShouldSmoothFontsChange, shouldSmoothFonts);
+    CHECK_FOR_CHANGED_PROPERTY(AntialiasedFontDilationEnabledChange, antialiasedFontDilationEnabled);
+    CHECK_FOR_CHANGED_PROPERTY(ShouldSubpixelQuantizeFontsChange, shouldSubpixelQuantizeFonts);
+    CHECK_FOR_CHANGED_PROPERTY(ShadowsIgnoreTransformsChange, shadowsIgnoreTransforms);
+    CHECK_FOR_CHANGED_PROPERTY(DrawLuminanceMaskChange, drawLuminanceMask);
+    CHECK_FOR_CHANGED_PROPERTY(ImageInterpolationQualityChange, imageInterpolationQuality);
+
+    return changeFlags;
+}
+
+void GraphicsContextStateChange::accumulate(const GraphicsContextState&amp; state, GraphicsContextState::StateChangeFlags flags)
+{
+    // FIXME: This code should move to GraphicsContextState.
+    if (flags &amp; GraphicsContextState::StrokeGradientChange)
+        m_state.strokeGradient = state.strokeGradient;
+
+    if (flags &amp; GraphicsContextState::StrokePatternChange)
+        m_state.strokePattern = state.strokePattern;
+
+    if (flags &amp; GraphicsContextState::FillGradientChange)
+        m_state.fillGradient = state.fillGradient;
+
+    if (flags &amp; GraphicsContextState::FillPatternChange)
+        m_state.fillPattern = state.fillPattern;
+
+    if (flags &amp; GraphicsContextState::ShadowChange) {
+        // FIXME: Deal with state.shadowsUseLegacyRadius.
+        m_state.shadowOffset = state.shadowOffset;
+        m_state.shadowBlur = state.shadowBlur;
+        m_state.shadowColor = state.shadowColor;
+    }
+
+    if (flags &amp; GraphicsContextState::StrokeThicknessChange)
+        m_state.strokeThickness = state.strokeThickness;
+
+    if (flags &amp; GraphicsContextState::TextDrawingModeChange)
+        m_state.textDrawingMode = state.textDrawingMode;
+
+    if (flags &amp; GraphicsContextState::StrokeColorChange)
+        m_state.strokeColor = state.strokeColor;
+
+    if (flags &amp; GraphicsContextState::FillColorChange)
+        m_state.fillColor = state.fillColor;
+
+    if (flags &amp; GraphicsContextState::StrokeStyleChange)
+        m_state.strokeStyle = state.strokeStyle;
+
+    if (flags &amp; GraphicsContextState::FillRuleChange)
+        m_state.fillRule = state.fillRule;
+
+    if (flags &amp; GraphicsContextState::AlphaChange)
+        m_state.alpha = state.alpha;
+
+    if (flags &amp; (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange)) {
+        m_state.compositeOperator = state.compositeOperator;
+        m_state.blendMode = state.blendMode;
+    }
+
+    if (flags &amp; GraphicsContextState::ShouldAntialiasChange)
+        m_state.shouldAntialias = state.shouldAntialias;
+
+    if (flags &amp; GraphicsContextState::ShouldSmoothFontsChange)
+        m_state.shouldSmoothFonts = state.shouldSmoothFonts;
+
+    if (flags &amp; GraphicsContextState::AntialiasedFontDilationEnabledChange)
+        m_state.antialiasedFontDilationEnabled = state.antialiasedFontDilationEnabled;
+
+    if (flags &amp; GraphicsContextState::ShouldSubpixelQuantizeFontsChange)
+        m_state.shouldSubpixelQuantizeFonts = state.shouldSubpixelQuantizeFonts;
+
+    if (flags &amp; GraphicsContextState::ShadowsIgnoreTransformsChange)
+        m_state.shadowsIgnoreTransforms = state.shadowsIgnoreTransforms;
+
+    if (flags &amp; GraphicsContextState::DrawLuminanceMaskChange)
+        m_state.drawLuminanceMask = state.drawLuminanceMask;
+
+    if (flags &amp; GraphicsContextState::ImageInterpolationQualityChange)
+        m_state.imageInterpolationQuality = state.imageInterpolationQuality;
+    
+    m_changeFlags |= flags;
+}
+
+void GraphicsContextStateChange::apply(GraphicsContext&amp; context) const
+{
+    if (m_changeFlags &amp; GraphicsContextState::StrokeGradientChange)
+        context.setStrokeGradient(*m_state.strokeGradient);
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokePatternChange)
+        context.setStrokePattern(*m_state.strokePattern);
+
+    if (m_changeFlags &amp; GraphicsContextState::FillGradientChange)
+        context.setFillGradient(*m_state.fillGradient);
+
+    if (m_changeFlags &amp; GraphicsContextState::FillPatternChange)
+        context.setFillPattern(*m_state.fillPattern);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShadowChange) {
+#if USE(CG)
+        if (m_state.shadowsUseLegacyRadius)
+            context.setLegacyShadow(m_state.shadowOffset, m_state.shadowBlur, m_state.shadowColor);
+        else
+#endif
+            context.setShadow(m_state.shadowOffset, m_state.shadowBlur, m_state.shadowColor);
+    }
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokeThicknessChange)
+        context.setStrokeThickness(m_state.strokeThickness);
+
+    if (m_changeFlags &amp; GraphicsContextState::TextDrawingModeChange)
+        context.setTextDrawingMode(m_state.textDrawingMode);
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokeColorChange)
+        context.setStrokeColor(m_state.strokeColor);
+
+    if (m_changeFlags &amp; GraphicsContextState::FillColorChange)
+        context.setFillColor(m_state.fillColor);
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokeStyleChange)
+        context.setStrokeStyle(m_state.strokeStyle);
+
+    if (m_changeFlags &amp; GraphicsContextState::FillRuleChange)
+        context.setFillRule(m_state.fillRule);
+
+    if (m_changeFlags &amp; GraphicsContextState::AlphaChange)
+        context.setAlpha(m_state.alpha);
+
+    if (m_changeFlags &amp; (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange))
+        context.setCompositeOperation(m_state.compositeOperator, m_state.blendMode);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShouldAntialiasChange)
+        context.setShouldAntialias(m_state.shouldAntialias);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShouldSmoothFontsChange)
+        context.setShouldSmoothFonts(m_state.shouldSmoothFonts);
+
+    if (m_changeFlags &amp; GraphicsContextState::AntialiasedFontDilationEnabledChange)
+        context.setAntialiasedFontDilationEnabled(m_state.antialiasedFontDilationEnabled);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShouldSubpixelQuantizeFontsChange)
+        context.setShouldSubpixelQuantizeFonts(m_state.shouldSubpixelQuantizeFonts);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShadowsIgnoreTransformsChange)
+        context.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms);
+
+    if (m_changeFlags &amp; GraphicsContextState::DrawLuminanceMaskChange)
+        context.setDrawLuminanceMask(m_state.drawLuminanceMask);
+
+    if (m_changeFlags &amp; GraphicsContextState::ImageInterpolationQualityChange)
+        context.setImageInterpolationQuality(m_state.imageInterpolationQuality);
+}
+
+void GraphicsContextStateChange::dump(TextStream&amp; ts) const
+{
+    ts.dumpProperty(&quot;change-flags&quot;, m_changeFlags);
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokeGradientChange)
+        ts.dumpProperty(&quot;stroke-gradient&quot;, m_state.strokeGradient.get());
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokePatternChange)
+        ts.dumpProperty(&quot;stroke-pattern&quot;, m_state.strokePattern.get());
+
+    if (m_changeFlags &amp; GraphicsContextState::FillGradientChange)
+        ts.dumpProperty(&quot;fill-gradient&quot;, m_state.fillGradient.get());
+
+    if (m_changeFlags &amp; GraphicsContextState::FillPatternChange)
+        ts.dumpProperty(&quot;fill-pattern&quot;, m_state.fillPattern.get());
+
+    if (m_changeFlags &amp; GraphicsContextState::ShadowChange) {
+        ts.dumpProperty(&quot;shadow-blur&quot;, m_state.shadowBlur);
+        ts.dumpProperty(&quot;shadow-offset&quot;, m_state.shadowOffset);
+#if USE(CG)
+        ts.dumpProperty(&quot;shadows-use-legacy-radius&quot;, m_state.shadowsUseLegacyRadius);
+#endif
+    }
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokeThicknessChange)
+        ts.dumpProperty(&quot;stroke-thickness&quot;, m_state.strokeThickness);
+
+    if (m_changeFlags &amp; GraphicsContextState::TextDrawingModeChange)
+        ts.dumpProperty(&quot;text-drawing-mode&quot;, m_state.textDrawingMode);
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokeColorChange)
+        ts.dumpProperty(&quot;stroke-color&quot;, m_state.strokeColor);
+
+    if (m_changeFlags &amp; GraphicsContextState::FillColorChange)
+        ts.dumpProperty(&quot;fill-color&quot;, m_state.fillColor);
+
+    if (m_changeFlags &amp; GraphicsContextState::StrokeStyleChange)
+        ts.dumpProperty(&quot;stroke-style&quot;, m_state.strokeStyle);
+
+    if (m_changeFlags &amp; GraphicsContextState::FillRuleChange)
+        ts.dumpProperty(&quot;fill-rule&quot;, m_state.fillRule);
+
+    if (m_changeFlags &amp; GraphicsContextState::AlphaChange)
+        ts.dumpProperty(&quot;alpha&quot;, m_state.alpha);
+
+    if (m_changeFlags &amp; GraphicsContextState::CompositeOperationChange)
+        ts.dumpProperty(&quot;composite-operator&quot;, m_state.compositeOperator);
+
+    if (m_changeFlags &amp; GraphicsContextState::BlendModeChange)
+        ts.dumpProperty(&quot;blend-mode&quot;, m_state.blendMode);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShouldAntialiasChange)
+        ts.dumpProperty(&quot;should-antialias&quot;, m_state.shouldAntialias);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShouldSmoothFontsChange)
+        ts.dumpProperty(&quot;should-smooth-fonts&quot;, m_state.shouldSmoothFonts);
+
+    if (m_changeFlags &amp; GraphicsContextState::AntialiasedFontDilationEnabledChange)
+        ts.dumpProperty(&quot;antialiased-font-dilation-enabled&quot;, m_state.antialiasedFontDilationEnabled);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShouldSubpixelQuantizeFontsChange)
+        ts.dumpProperty(&quot;should-subpixel-quantize-fonts&quot;, m_state.shouldSubpixelQuantizeFonts);
+
+    if (m_changeFlags &amp; GraphicsContextState::ShadowsIgnoreTransformsChange)
+        ts.dumpProperty(&quot;shadows-ignore-transforms&quot;, m_state.shadowsIgnoreTransforms);
+
+    if (m_changeFlags &amp; GraphicsContextState::DrawLuminanceMaskChange)
+        ts.dumpProperty(&quot;draw-luminance-mask&quot;, m_state.drawLuminanceMask);
+}
+
+TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const GraphicsContextStateChange&amp; stateChange)
+{
+    stateChange.dump(ts);
+    return ts;
+}
+
+
</ins><span class="cx"> GraphicsContext::GraphicsContext(PlatformGraphicsContext* platformGraphicsContext)
</span><span class="cx">     : m_updatingControlTints(false)
</span><span class="cx">     , m_transparencyCount(0)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (194707 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2016-01-07 19:42:49 UTC (rev 194707)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -127,6 +127,33 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    enum Change : uint32_t {
+        NoChange                                = 0,
+        StrokeGradientChange                    = 1 &lt;&lt; 1,
+        StrokePatternChange                     = 1 &lt;&lt; 2,
+        FillGradientChange                      = 1 &lt;&lt; 3,
+        FillPatternChange                       = 1 &lt;&lt; 4,
+        StrokeThicknessChange                   = 1 &lt;&lt; 5,
+        StrokeColorChange                       = 1 &lt;&lt; 6,
+        StrokeStyleChange                       = 1 &lt;&lt; 7,
+        FillColorChange                         = 1 &lt;&lt; 8,
+        FillRuleChange                          = 1 &lt;&lt; 9,
+        ShadowChange                            = 1 &lt;&lt; 10,
+        ShadowColorChange                       = 1 &lt;&lt; 11,
+        ShadowsIgnoreTransformsChange           = 1 &lt;&lt; 12,
+        AlphaChange                             = 1 &lt;&lt; 13,
+        CompositeOperationChange                = 1 &lt;&lt; 14,
+        BlendModeChange                         = 1 &lt;&lt; 15,
+        TextDrawingModeChange                   = 1 &lt;&lt; 16,
+        ShouldAntialiasChange                   = 1 &lt;&lt; 17,
+        ShouldSmoothFontsChange                 = 1 &lt;&lt; 18,
+        AntialiasedFontDilationEnabledChange    = 1 &lt;&lt; 19,
+        ShouldSubpixelQuantizeFontsChange       = 1 &lt;&lt; 20,
+        DrawLuminanceMaskChange                 = 1 &lt;&lt; 21,
+        ImageInterpolationQualityChange         = 1 &lt;&lt; 22,
+    };
+    typedef uint32_t StateChangeFlags;
+
</ins><span class="cx">     RefPtr&lt;Gradient&gt; strokeGradient;
</span><span class="cx">     RefPtr&lt;Pattern&gt; strokePattern;
</span><span class="cx">     
</span><span class="lines">@@ -195,6 +222,28 @@
</span><span class="cx">     bool m_useLowQualityScale;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct GraphicsContextStateChange {
+    GraphicsContextStateChange() = default;
+    GraphicsContextStateChange(const GraphicsContextState&amp; state, GraphicsContextState::StateChangeFlags flags)
+        : m_state(state)
+        , m_changeFlags(flags)
+    {
+    }
+
+    GraphicsContextState::StateChangeFlags changesFromState(const GraphicsContextState&amp;) const;
+
+    void accumulate(const GraphicsContextState&amp;, GraphicsContextState::StateChangeFlags);
+    void apply(GraphicsContext&amp;) const;
+    
+    void dump(TextStream&amp;) const;
+
+    GraphicsContextState m_state;
+    GraphicsContextState::StateChangeFlags m_changeFlags { GraphicsContextState::NoChange };
+};
+
+TextStream&amp; operator&lt;&lt;(TextStream&amp;, const GraphicsContextStateChange&amp;);
+
+
</ins><span class="cx"> class GraphicsContext {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,83 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DisplayList.h&quot;
+
+#include &quot;DisplayListItems.h&quot;
+#include &quot;Logging.h&quot;
+#include &quot;TextStream.h&quot;
+#include &lt;wtf/StdLibExtras.h&gt;
+
+namespace WebCore {
+namespace DisplayList {
+
+#if !defined(NDEBUG) || !LOG_DISABLED
+WTF::CString DisplayList::description() const
+{
+    TextStream ts;
+    ts &lt;&lt; *this;
+    return ts.release().utf8();
+}
+
+void DisplayList::dump() const
+{
+    fprintf(stderr, &quot;%s&quot;, description().data());
+}
+#endif
+
+void DisplayList::dump(TextStream&amp; ts) const
+{
+    TextStream::GroupScope group(ts);
+    ts &lt;&lt; &quot;display list&quot;;
+
+    size_t numItems = m_list.size();
+    for (size_t i = 0; i &lt; numItems; ++i) {
+        TextStream::GroupScope scope(ts);
+        ts &lt;&lt; i &lt;&lt; &quot; &quot; &lt;&lt; m_list[i].get();
+    }
+    ts.startGroup();
+    ts &lt;&lt; &quot;size in bytes: &quot; &lt;&lt; sizeInBytes();
+    ts.endGroup();
+}
+
+size_t DisplayList::sizeInBytes() const
+{
+    size_t result = 0;
+    for (auto&amp; ref : m_list)
+        result += Item::sizeInBytes(ref);
+
+    return result;
+}
+
+} // namespace DisplayList
+
+TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DisplayList::DisplayList&amp; displayList)
+{
+    displayList.dump(ts);
+    return ts;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayList.h        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,96 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DisplayList_h
+#define DisplayList_h
+
+#include &lt;wtf/FastMalloc.h&gt;
+#include &lt;wtf/Noncopyable.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+class FloatRect;
+class GraphicsContext;
+class TextStream;
+
+namespace DisplayList {
+
+class Item;
+
+class DisplayList {
+    WTF_MAKE_NONCOPYABLE(DisplayList);
+    friend class Recorder;
+public:
+    DisplayList() = default;
+    DisplayList(DisplayList&amp;&amp;) = default;
+
+    DisplayList&amp; operator=(DisplayList&amp;&amp;) = default;
+
+    void dump(TextStream&amp;) const;
+
+    const Vector&lt;Ref&lt;Item&gt;&gt;&amp; list() const { return m_list; }
+    Item&amp; itemAt(size_t index)
+    {
+        ASSERT(index &lt; m_list.size());
+        return m_list[index].get();
+    }
+    
+    void clear() { m_list.clear(); }
+    size_t size() const { return m_list.size(); }
+
+    void removeItemsFromIndex(size_t index)
+    {
+        m_list.resize(index);
+    }
+
+    size_t sizeInBytes() const;
+
+#if !defined(NDEBUG) || !LOG_DISABLED
+    WTF::CString description() const;
+    void dump() const;
+#endif
+
+private:
+    Item&amp; append(Ref&lt;Item&gt;&amp;&amp; item)
+    {
+        m_list.append(WTFMove(item));
+        return m_list.last().get();
+    }
+
+    Vector&lt;Ref&lt;Item&gt;&gt;&amp; list() { return m_list; }
+
+    Vector&lt;Ref&lt;Item&gt;&gt; m_list;
+};
+
+} // DisplayList
+
+TextStream&amp; operator&lt;&lt;(TextStream&amp;, const DisplayList::DisplayList&amp;);
+
+} // WebCore
+
+using WebCore::DisplayList::DisplayList;
+
+#endif /* DisplayList_h */
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListItemscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,1219 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DisplayListItems.h&quot;
+
+#include &quot;FontCascade.h&quot;
+#include &quot;TextStream.h&quot;
+
+namespace WebCore {
+namespace DisplayList {
+
+// Should match RenderTheme::platformFocusRingWidth()
+static const float platformFocusRingWidth = 3;
+
+#if !defined(NDEBUG) || !LOG_DISABLED
+WTF::CString Item::description() const
+{
+    TextStream ts;
+    ts &lt;&lt; *this;
+    return ts.release().utf8();
+}
+#endif
+
+size_t Item::sizeInBytes(const Item&amp; item)
+{
+    switch (item.type()) {
+    case ItemType::Save:
+        return sizeof(downcast&lt;Save&gt;(item));
+    case ItemType::Restore:
+        return sizeof(downcast&lt;Restore&gt;(item));
+    case ItemType::Translate:
+        return sizeof(downcast&lt;Translate&gt;(item));
+    case ItemType::Rotate:
+        return sizeof(downcast&lt;Rotate&gt;(item));
+    case ItemType::Scale:
+        return sizeof(downcast&lt;Scale&gt;(item));
+    case ItemType::ConcatenateCTM:
+        return sizeof(downcast&lt;ConcatenateCTM&gt;(item));
+    case ItemType::SetState:
+        return sizeof(downcast&lt;SetState&gt;(item));
+    case ItemType::SetLineCap:
+        return sizeof(downcast&lt;SetLineCap&gt;(item));
+    case ItemType::SetLineDash:
+        return sizeof(downcast&lt;SetLineDash&gt;(item));
+    case ItemType::SetLineJoin:
+        return sizeof(downcast&lt;SetLineJoin&gt;(item));
+    case ItemType::SetMiterLimit:
+        return sizeof(downcast&lt;SetMiterLimit&gt;(item));
+    case ItemType::ClearShadow:
+        return sizeof(downcast&lt;ClearShadow&gt;(item));
+    case ItemType::Clip:
+        return sizeof(downcast&lt;Clip&gt;(item));
+    case ItemType::ClipOut:
+        return sizeof(downcast&lt;ClipOut&gt;(item));
+    case ItemType::ClipOutToPath:
+        return sizeof(downcast&lt;ClipOutToPath&gt;(item));
+    case ItemType::ClipPath:
+        return sizeof(downcast&lt;ClipPath&gt;(item));
+    case ItemType::ClipConvexPolygon:
+        return sizeof(downcast&lt;ClipConvexPolygon&gt;(item));
+    case ItemType::DrawGlyphs:
+        return sizeof(downcast&lt;DrawGlyphs&gt;(item));
+    case ItemType::DrawImage:
+        return sizeof(downcast&lt;DrawImage&gt;(item));
+    case ItemType::DrawTiledImage:
+        return sizeof(downcast&lt;DrawTiledImage&gt;(item));
+    case ItemType::DrawTiledScaledImage:
+        return sizeof(downcast&lt;DrawTiledScaledImage&gt;(item));
+#if USE(CG) || USE(CAIRO)
+    case ItemType::DrawNativeImage:
+        return sizeof(downcast&lt;DrawNativeImage&gt;(item));
+#endif
+    case ItemType::DrawPattern:
+        return sizeof(downcast&lt;DrawPattern&gt;(item));
+    case ItemType::DrawRect:
+        return sizeof(downcast&lt;DrawRect&gt;(item));
+    case ItemType::DrawLine:
+        return sizeof(downcast&lt;DrawLine&gt;(item));
+    case ItemType::DrawLinesForText:
+        return sizeof(downcast&lt;DrawLinesForText&gt;(item));
+    case ItemType::DrawLineForDocumentMarker:
+        return sizeof(downcast&lt;DrawLineForDocumentMarker&gt;(item));
+    case ItemType::DrawEllipse:
+        return sizeof(downcast&lt;DrawEllipse&gt;(item));
+    case ItemType::DrawConvexPolygon:
+        return sizeof(downcast&lt;DrawConvexPolygon&gt;(item));
+    case ItemType::DrawPath:
+        return sizeof(downcast&lt;DrawPath&gt;(item));
+    case ItemType::DrawFocusRingPath:
+        return sizeof(downcast&lt;DrawFocusRingPath&gt;(item));
+    case ItemType::DrawFocusRingRects:
+        return sizeof(downcast&lt;DrawFocusRingRects&gt;(item));
+    case ItemType::FillRect:
+        return sizeof(downcast&lt;FillRect&gt;(item));
+    case ItemType::FillRectWithColor:
+        return sizeof(downcast&lt;FillRectWithColor&gt;(item));
+    case ItemType::FillRectWithGradient:
+        return sizeof(downcast&lt;FillRectWithGradient&gt;(item));
+    case ItemType::FillCompositedRect:
+        return sizeof(downcast&lt;FillCompositedRect&gt;(item));
+    case ItemType::FillRoundedRect:
+        return sizeof(downcast&lt;FillRoundedRect&gt;(item));
+    case ItemType::FillRectWithRoundedHole:
+        return sizeof(downcast&lt;FillRectWithRoundedHole&gt;(item));
+    case ItemType::FillPath:
+        return sizeof(downcast&lt;FillPath&gt;(item));
+    case ItemType::FillEllipse:
+        return sizeof(downcast&lt;FillEllipse&gt;(item));
+    case ItemType::StrokeRect:
+        return sizeof(downcast&lt;StrokeRect&gt;(item));
+    case ItemType::StrokePath:
+        return sizeof(downcast&lt;StrokePath&gt;(item));
+    case ItemType::StrokeEllipse:
+        return sizeof(downcast&lt;StrokeEllipse&gt;(item));
+    case ItemType::ClearRect:
+        return sizeof(downcast&lt;ClearRect&gt;(item));
+    case ItemType::BeginTransparencyLayer:
+        return sizeof(downcast&lt;BeginTransparencyLayer&gt;(item));
+    case ItemType::EndTransparencyLayer:
+        return sizeof(downcast&lt;EndTransparencyLayer&gt;(item));
+#if USE(CG)
+    case ItemType::ApplyStrokePattern:
+        return sizeof(downcast&lt;ApplyStrokePattern&gt;(item));
+    case ItemType::ApplyFillPattern:
+        return sizeof(downcast&lt;ApplyFillPattern&gt;(item));
+#endif
+    case ItemType::ApplyDeviceScaleFactor:
+        return sizeof(downcast&lt;ApplyDeviceScaleFactor&gt;(item));
+    }
+    return 0;
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawingItem&amp; item)
+{
+    ts.startGroup();
+    ts &lt;&lt; &quot;extent &quot;;
+    if (item.extentKnown())
+        ts &lt;&lt; item.extent();
+    else
+        ts &lt;&lt; &quot;unknown&quot;;
+    
+    ts.endGroup();
+    return ts;
+}
+
+void Save::apply(GraphicsContext&amp; context) const
+{
+    context.save();
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const Save&amp; item)
+{
+    ts.dumpProperty(&quot;restore-index&quot;, item.restoreIndex());
+    return ts;
+}
+
+void Restore::apply(GraphicsContext&amp; context) const
+{
+    context.restore();
+}
+
+void Translate::apply(GraphicsContext&amp; context) const
+{
+    context.translate(m_x, m_y);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const Translate&amp; item)
+{
+    ts.dumpProperty(&quot;x&quot;, item.x());
+    ts.dumpProperty(&quot;y&quot;, item.y());
+
+    return ts;
+}
+
+void Rotate::apply(GraphicsContext&amp; context) const
+{
+    context.rotate(m_angle);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const Rotate&amp; item)
+{
+    ts.dumpProperty(&quot;angle&quot;, item.angle());
+
+    return ts;
+}
+
+void Scale::apply(GraphicsContext&amp; context) const
+{
+    context.scale(m_size);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const Scale&amp; item)
+{
+    ts.dumpProperty(&quot;size&quot;, item.amount());
+
+    return ts;
+}
+
+ConcatenateCTM::ConcatenateCTM(const AffineTransform&amp; transform)
+    : Item(ItemType::ConcatenateCTM)
+    , m_transform(transform)
+{
+}
+
+void ConcatenateCTM::apply(GraphicsContext&amp; context) const
+{
+    context.concatCTM(m_transform);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ConcatenateCTM&amp; item)
+{
+    ts.dumpProperty(&quot;ctm&quot;, item.transform());
+
+    return ts;
+}
+
+void SetState::apply(GraphicsContext&amp; context) const
+{
+    m_state.apply(context);
+}
+
+void SetState::accumulate(const GraphicsContextState&amp; state, GraphicsContextState::StateChangeFlags flags)
+{
+    m_state.accumulate(state, flags);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const SetState&amp; state)
+{
+    ts &lt;&lt; state.state();
+    return ts;
+}
+
+void SetLineCap::apply(GraphicsContext&amp; context) const
+{
+    context.setLineCap(m_lineCap);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const SetLineCap&amp; lineCap)
+{
+    ts.dumpProperty(&quot;line-cap&quot;, lineCap.lineCap());
+    return ts;
+}
+
+void SetLineDash::apply(GraphicsContext&amp; context) const
+{
+    context.setLineDash(m_dashArray, m_dashOffset);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const SetLineDash&amp; lineDash)
+{
+    ts.dumpProperty(&quot;dash-array&quot;, lineDash.dashArray());
+    ts.dumpProperty(&quot;dash-offset&quot;, lineDash.dashOffset());
+    return ts;
+}
+
+void SetLineJoin::apply(GraphicsContext&amp; context) const
+{
+    context.setLineJoin(m_lineJoin);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const SetLineJoin&amp; lineJoin)
+{
+    ts.dumpProperty(&quot;line-join&quot;, lineJoin.lineJoin());
+    return ts;
+}
+
+void SetMiterLimit::apply(GraphicsContext&amp; context) const
+{
+    context.setMiterLimit(m_miterLimit);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const SetMiterLimit&amp; miterLimit)
+{
+    ts.dumpProperty(&quot;mitre-limit&quot;, miterLimit.miterLimit());
+    return ts;
+}
+
+void ClearShadow::apply(GraphicsContext&amp; context) const
+{
+    context.clearShadow();
+}
+
+void Clip::apply(GraphicsContext&amp; context) const
+{
+    context.clip(m_rect);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const Clip&amp; item)
+{
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+void ClipOut::apply(GraphicsContext&amp; context) const
+{
+    context.clipOut(m_rect);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ClipOut&amp; item)
+{
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+void ClipOutToPath::apply(GraphicsContext&amp; context) const
+{
+    context.clipOut(m_path);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ClipOutToPath&amp;)
+{
+//    ts.dumpProperty(&quot;path&quot;, item.path()); // FIXME: path logging.
+    return ts;
+}
+
+void ClipPath::apply(GraphicsContext&amp; context) const
+{
+    context.clipPath(m_path, m_windRule);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ClipPath&amp; item)
+{
+//    ts.dumpProperty(&quot;path&quot;, item.path()); // FIXME: path logging.
+    ts.dumpProperty(&quot;wind-rule&quot;, item.windRule());
+    return ts;
+}
+
+ClipConvexPolygon::ClipConvexPolygon(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+    : Item(ItemType::ClipConvexPolygon)
+    , m_antialias(antialiased)
+{
+    for (size_t i = 0; i &lt; numberOfPoints; ++i)
+        m_points.append(points[i]);
+}
+
+void ClipConvexPolygon::apply(GraphicsContext&amp; context) const
+{
+    context.clipConvexPolygon(m_points.size(), m_points.data(), m_antialias);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ClipConvexPolygon&amp; item)
+{
+    ts.dumpProperty(&quot;points&quot;, item.points());
+    ts.dumpProperty(&quot;antialias&quot;, item.antialias());
+    return ts;
+}
+
+DrawGlyphs::DrawGlyphs(const Font&amp; font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint&amp; blockLocation, const FloatSize&amp; localAnchor, FontSmoothingMode smoothingMode)
+    : DrawingItem(ItemType::DrawGlyphs)
+    , m_font(const_cast&lt;Font&amp;&gt;(font))
+    , m_blockLocation(blockLocation)
+    , m_localAnchor(localAnchor)
+    , m_smoothingMode(smoothingMode)
+{
+    m_glyphs.reserveInitialCapacity(count);
+    m_advances.reserveInitialCapacity(count);
+    for (unsigned i = 0; i &lt; count; ++i) {
+        m_glyphs.uncheckedAppend(glyphs[i]);
+        m_advances.uncheckedAppend(advances[i]);
+    }
+    computeBounds();
+}
+
+inline GlyphBuffer DrawGlyphs::generateGlyphBuffer() const
+{
+    GlyphBuffer result;
+    for (size_t i = 0; i &lt; m_glyphs.size(); ++i) {
+#if USE(CAIRO)
+        result.add(m_glyphs[i].index, &amp;m_font.get(), m_advances[i]);
+#else
+        result.add(m_glyphs[i], &amp;m_font.get(), m_advances[i]);
+#endif
+    }
+    return result;
+}
+
+void DrawGlyphs::apply(GraphicsContext&amp;) const
+{
+    // FIXME: implement.
+    UNUSED_PARAM(m_smoothingMode);
+}
+
+void DrawGlyphs::computeBounds()
+{
+    // FIXME: This code doesn't actually take the extents of the glyphs into consideration. It assumes that
+    // the glyph lies entirely within its [(ascent + descent), advance] rect.
+    float ascent = m_font-&gt;fontMetrics().floatAscent();
+    float descent = m_font-&gt;fontMetrics().floatDescent();
+    FloatPoint current = toFloatPoint(localAnchor());
+    size_t numGlyphs = m_glyphs.size();
+    for (size_t i = 0; i &lt; numGlyphs; ++i) {
+        GlyphBufferAdvance advance = m_advances[i];
+        FloatRect glyphRect = FloatRect(current.x(), current.y() - ascent, advance.width(), ascent + descent);
+        m_bounds.unite(glyphRect);
+
+        current += FloatSize(advance);
+    }
+}
+
+Optional&lt;FloatRect&gt; DrawGlyphs::localBounds(const GraphicsContext&amp;) const
+{
+    FloatRect localBounds = m_bounds;
+    localBounds.move(m_blockLocation.x(), m_blockLocation.y());
+    return localBounds;
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawGlyphs&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    // FIXME: dump more stuff.
+    ts.dumpProperty(&quot;block-location&quot;, item.blockLocation());
+    ts.dumpProperty(&quot;local-anchor&quot;, item.localAnchor());
+    ts.dumpProperty(&quot;anchor-point&quot;, item.anchorPoint());
+    ts.dumpProperty(&quot;length&quot;, item.glyphs().size());
+
+    return ts;
+}
+
+DrawImage::DrawImage(Image&amp; image, const FloatRect&amp; destination, const FloatRect&amp; source, const ImagePaintingOptions&amp; imagePaintingOptions)
+    : DrawingItem(ItemType::DrawImage)
+    , m_image(image)
+    , m_destination(destination)
+    , m_source(source)
+    , m_imagePaintingOptions(imagePaintingOptions)
+{
+}
+
+void DrawImage::apply(GraphicsContext&amp; context) const
+{
+    context.drawImage(m_image.get(), m_destination, m_source, m_imagePaintingOptions);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawImage&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;image&quot;, item.image());
+    ts.dumpProperty(&quot;source-rect&quot;, item.source());
+    ts.dumpProperty(&quot;dest-rect&quot;, item.destination());
+    return ts;
+}
+
+DrawTiledImage::DrawTiledImage(Image&amp; image, const FloatRect&amp; destination, const FloatPoint&amp; source, const FloatSize&amp; tileSize, const FloatSize&amp; spacing, const ImagePaintingOptions&amp; imagePaintingOptions)
+    : DrawingItem(ItemType::DrawTiledImage)
+    , m_image(image)
+    , m_destination(destination)
+    , m_source(source)
+    , m_tileSize(tileSize)
+    , m_spacing(spacing)
+    , m_imagePaintingOptions(imagePaintingOptions)
+{
+}
+
+void DrawTiledImage::apply(GraphicsContext&amp; context) const
+{
+    context.drawTiledImage(m_image.get(), m_destination, m_source, m_tileSize, m_spacing, m_imagePaintingOptions);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawTiledImage&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;image&quot;, item.image());
+    ts.dumpProperty(&quot;source-point&quot;, item.source());
+    ts.dumpProperty(&quot;dest-rect&quot;, item.destination());
+    ts.dumpProperty(&quot;tile-size&quot;, item.tileSize());
+    ts.dumpProperty(&quot;spacing&quot;, item.spacing());
+    return ts;
+}
+
+DrawTiledScaledImage::DrawTiledScaledImage(Image&amp; image, const FloatRect&amp; destination, const FloatRect&amp; source, const FloatSize&amp; tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&amp; imagePaintingOptions)
+    : DrawingItem(ItemType::DrawTiledScaledImage)
+    , m_image(image)
+    , m_destination(destination)
+    , m_source(source)
+    , m_tileScaleFactor(tileScaleFactor)
+    , m_hRule(hRule)
+    , m_vRule(vRule)
+    , m_imagePaintingOptions(imagePaintingOptions)
+{
+}
+
+void DrawTiledScaledImage::apply(GraphicsContext&amp; context) const
+{
+    context.drawTiledImage(m_image.get(), m_destination, m_source, m_tileScaleFactor, m_hRule, m_vRule, m_imagePaintingOptions);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawTiledScaledImage&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;image&quot;, item.image());
+    ts.dumpProperty(&quot;source-rect&quot;, item.source());
+    ts.dumpProperty(&quot;dest-rect&quot;, item.destination());
+    return ts;
+}
+
+#if USE(CG) || USE(CAIRO)
+DrawNativeImage::DrawNativeImage(PassNativeImagePtr imagePtr, const FloatSize&amp; imageSize, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation)
+    : DrawingItem(ItemType::DrawNativeImage)
+#if USE(CG)
+    // FIXME: Need to store an image for Cairo.
+    , m_imagePtr(imagePtr)
+#endif
+    , m_imageSize(imageSize)
+    , m_destination(destRect)
+    , m_srcRect(srcRect)
+    , m_op(op)
+    , m_blendMode(blendMode)
+    , m_orientation(orientation)
+{
+    UNUSED_PARAM(imagePtr);
+}
+
+void DrawNativeImage::apply(GraphicsContext&amp; context) const
+{
+#if USE(CG)
+    context.drawNativeImage(m_imagePtr.get(), m_imageSize, m_destination, m_srcRect, m_op, m_blendMode, m_orientation);
+#else
+    UNUSED_PARAM(context);
+#endif
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawNativeImage&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    // FIXME: dump more stuff.
+    ts.dumpProperty(&quot;source-rect&quot;, item.source());
+    ts.dumpProperty(&quot;dest-rect&quot;, item.destination());
+    return ts;
+}
+#endif
+
+DrawPattern::DrawPattern(Image&amp; image, const FloatRect&amp; tileRect, const AffineTransform&amp; patternTransform, const FloatPoint&amp; phase, const FloatSize&amp; spacing, CompositeOperator op, const FloatRect&amp; destRect, BlendMode blendMode)
+    : DrawingItem(ItemType::DrawPattern)
+    , m_image(image)
+    , m_patternTransform(patternTransform)
+    , m_tileRect(tileRect)
+    , m_destination(destRect)
+    , m_phase(phase)
+    , m_spacing(spacing)
+    , m_op(op)
+    , m_blendMode(blendMode)
+{
+}
+
+void DrawPattern::apply(GraphicsContext&amp; context) const
+{
+    context.drawPattern(m_image.get(), m_tileRect, m_patternTransform, m_phase, m_spacing, m_op, m_destination, m_blendMode);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawPattern&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;image&quot;, item.image());
+    ts.dumpProperty(&quot;pattern-transform&quot;, item.patternTransform());
+    ts.dumpProperty(&quot;tile-rect&quot;, item.tileRect());
+    ts.dumpProperty(&quot;dest-rect&quot;, item.destRect());
+    ts.dumpProperty(&quot;phase&quot;, item.phase());
+    ts.dumpProperty(&quot;spacing&quot;, item.spacing());
+    return ts;
+}
+
+void DrawRect::apply(GraphicsContext&amp; context) const
+{
+    context.drawRect(m_rect, m_borderThickness);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawRect&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    ts.dumpProperty(&quot;border-thickness&quot;, item.borderThickness());
+    return ts;
+}
+
+Optional&lt;FloatRect&gt; DrawLine::localBounds(const GraphicsContext&amp;) const
+{
+    FloatRect bounds;
+    bounds.fitToPoints(m_point1, m_point2);
+    return bounds;
+}
+
+void DrawLine::apply(GraphicsContext&amp; context) const
+{
+    context.drawLine(m_point1, m_point2);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawLine&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;point-1&quot;, item.point1());
+    ts.dumpProperty(&quot;point-2&quot;, item.point2());
+    return ts;
+}
+
+void DrawLinesForText::apply(GraphicsContext&amp; context) const
+{
+    context.drawLinesForText(point(), m_widths, m_printing, m_doubleLines);
+}
+
+Optional&lt;FloatRect&gt; DrawLinesForText::localBounds(const GraphicsContext&amp;) const
+{
+    // This function needs to return a value equal to or enclosing what GraphicsContext::computeLineBoundsAndAntialiasingModeForText() returns.
+
+    if (!m_widths.size())
+        return FloatRect();
+
+    FloatRect result(point(), FloatSize(m_widths.last(), m_strokeWidth));
+    result.inflate(1); // Account for pixel snapping. FIXME: This isn't perfect, as it doesn't take the CTM into account.
+    return result;
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawLinesForText&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;block-location&quot;, item.blockLocation());
+    ts.dumpProperty(&quot;local-anchor&quot;, item.localAnchor());
+    ts.dumpProperty(&quot;point&quot;, item.point());
+    ts.dumpProperty(&quot;double&quot;, item.doubleLines());
+    ts.dumpProperty(&quot;widths&quot;, item.widths());
+    ts.dumpProperty(&quot;is-printing&quot;, item.isPrinting());
+    ts.dumpProperty(&quot;double&quot;, item.doubleLines());
+    return ts;
+}
+
+void DrawLineForDocumentMarker::apply(GraphicsContext&amp; context) const
+{
+    context.drawLineForDocumentMarker(m_point, m_width, m_style);
+}
+
+Optional&lt;FloatRect&gt; DrawLineForDocumentMarker::localBounds(const GraphicsContext&amp;) const
+{
+    // This function needs to return a value equal to or enclosing what GraphicsContext::drawLineForDocumentMarker() returns.
+
+    FloatRect result(m_point, FloatSize(m_width, cMisspellingLineThickness));
+    result.inflate(cMisspellingLineThickness); // Account for &quot;misspelling dot&quot; snapping.
+    return result;
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawLineForDocumentMarker&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;point&quot;, item.point());
+    ts.dumpProperty(&quot;width&quot;, item.width());
+    return ts;
+}
+
+void DrawEllipse::apply(GraphicsContext&amp; context) const
+{
+    context.drawEllipse(m_rect);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawEllipse&amp; item)
+{
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+// FIXME: Share this code.
+void addConvexPolygonToPath(Path&amp; path, size_t numberOfPoints, const FloatPoint* points)
+{
+    ASSERT(numberOfPoints &gt; 0);
+
+    path.moveTo(points[0]);
+    for (size_t i = 1; i &lt; numberOfPoints; ++i)
+        path.addLineTo(points[i]);
+    path.closeSubpath();
+}
+
+DrawConvexPolygon::DrawConvexPolygon(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+    : DrawingItem(ItemType::DrawConvexPolygon)
+    , m_antialiased(antialiased)
+{
+    for (size_t i = 0; i &lt; numberOfPoints; ++i)
+        m_points.append(points[i]);
+}
+
+Optional&lt;FloatRect&gt; DrawConvexPolygon::localBounds(const GraphicsContext&amp;) const
+{
+    FloatRect result;
+    for (auto&amp; point : m_points)
+        result.extend(point);
+    result.inflate(m_antialiased ? 1 : 0); // Account for antialiasing
+    return result;
+}
+
+void DrawConvexPolygon::apply(GraphicsContext&amp; context) const
+{
+    context.drawConvexPolygon(m_points.size(), m_points.data(), m_antialiased);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawConvexPolygon&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;points&quot;, item.points());
+    ts.dumpProperty(&quot;antialiased&quot;, item.antialiased());
+    return ts;
+}
+
+void DrawPath::apply(GraphicsContext&amp; context) const
+{
+#if USE(CG)
+    context.drawPath(m_path);
+#else
+    UNUSED_PARAM(context);
+#endif
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawPath&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+//    ts.dumpProperty(&quot;path&quot;, item.path()); // FIXME: add logging for paths.
+    return ts;
+}
+
+void DrawFocusRingPath::apply(GraphicsContext&amp; context) const
+{
+    context.drawFocusRing(m_path, m_width, m_offset, m_color);
+}
+
+Optional&lt;FloatRect&gt; DrawFocusRingPath::localBounds(const GraphicsContext&amp;) const
+{
+    FloatRect result = m_path.fastBoundingRect();
+    result.inflate(platformFocusRingWidth);
+    return result;
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawFocusRingPath&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+//    ts.dumpProperty(&quot;path&quot;, item.path()); // FIXME: add logging for paths.
+    ts.dumpProperty(&quot;width&quot;, item.width());
+    ts.dumpProperty(&quot;offset&quot;, item.offset());
+    ts.dumpProperty(&quot;color&quot;, item.color());
+    return ts;
+}
+
+void DrawFocusRingRects::apply(GraphicsContext&amp; context) const
+{
+    context.drawFocusRing(m_rects, m_width, m_offset, m_color);
+}
+
+Optional&lt;FloatRect&gt; DrawFocusRingRects::localBounds(const GraphicsContext&amp;) const
+{
+    FloatRect result;
+    for (auto&amp; rect : m_rects)
+        result.unite(rect);
+    result.inflate(platformFocusRingWidth);
+    return result;
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const DrawFocusRingRects&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rects&quot;, item.rects());
+    ts.dumpProperty(&quot;width&quot;, item.width());
+    ts.dumpProperty(&quot;offset&quot;, item.offset());
+    ts.dumpProperty(&quot;color&quot;, item.color());
+    return ts;
+}
+
+void FillRect::apply(GraphicsContext&amp; context) const
+{
+    context.fillRect(m_rect);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillRect&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+void FillRectWithColor::apply(GraphicsContext&amp; context) const
+{
+    context.fillRect(m_rect, m_color);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillRectWithColor&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    ts.dumpProperty(&quot;color&quot;, item.color());
+    return ts;
+}
+
+void FillRectWithGradient::apply(GraphicsContext&amp; context) const
+{
+    context.fillRect(m_rect, m_gradient.get());
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillRectWithGradient&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    // FIXME: log gradient.
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+void FillCompositedRect::apply(GraphicsContext&amp; context) const
+{
+    context.fillRect(m_rect, m_color, m_op, m_blendMode);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillCompositedRect&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    ts.dumpProperty(&quot;color&quot;, item.color());
+    ts.dumpProperty(&quot;composite-operation&quot;, item.compositeOperator());
+    ts.dumpProperty(&quot;blend-mode&quot;, item.blendMode());
+    return ts;
+}
+
+void FillRoundedRect::apply(GraphicsContext&amp; context) const
+{
+    context.fillRoundedRect(m_rect, m_color, m_blendMode);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillRoundedRect&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.roundedRect());
+    ts.dumpProperty(&quot;color&quot;, item.color());
+    ts.dumpProperty(&quot;blend-mode&quot;, item.blendMode());
+    return ts;
+}
+
+void FillRectWithRoundedHole::apply(GraphicsContext&amp; context) const
+{
+    context.fillRectWithRoundedHole(m_rect, m_roundedHoleRect, m_color);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillRectWithRoundedHole&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    ts.dumpProperty(&quot;rounded-hole-rect&quot;, item.roundedHoleRect());
+    ts.dumpProperty(&quot;color&quot;, item.color());
+    return ts;
+}
+
+void FillPath::apply(GraphicsContext&amp; context) const
+{
+    context.fillPath(m_path);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillPath&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+//    ts.dumpProperty(&quot;path&quot;, item.path()); // FIXME: path logging.
+    return ts;
+}
+
+void FillEllipse::apply(GraphicsContext&amp; context) const
+{
+    context.fillEllipse(m_rect);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const FillEllipse&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+Optional&lt;FloatRect&gt; StrokeRect::localBounds(const GraphicsContext&amp;) const
+{
+    FloatRect bounds = m_rect;
+    bounds.expand(m_lineWidth, m_lineWidth);
+    return bounds;
+}
+
+void StrokeRect::apply(GraphicsContext&amp; context) const
+{
+    context.strokeRect(m_rect, m_lineWidth);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const StrokeRect&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    ts.dumpProperty(&quot;line-width&quot;, item.lineWidth());
+    return ts;
+}
+
+Optional&lt;FloatRect&gt; StrokePath::localBounds(const GraphicsContext&amp; context) const
+{
+    // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath().
+    float strokeThickness = context.strokeThickness();
+
+    FloatRect bounds = m_path.boundingRect();
+    bounds.expand(strokeThickness, strokeThickness);
+    return bounds;
+}
+
+void StrokePath::apply(GraphicsContext&amp; context) const
+{
+    context.strokePath(m_path);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const StrokePath&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+//    ts.dumpProperty(&quot;path&quot;, item.path()); // FIXME: path logging.
+    return ts;
+}
+
+Optional&lt;FloatRect&gt; StrokeEllipse::localBounds(const GraphicsContext&amp; context) const
+{
+    float strokeThickness = context.strokeThickness();
+
+    FloatRect bounds = m_rect;
+    bounds.expand(strokeThickness, strokeThickness);
+    return bounds;
+}
+
+void StrokeEllipse::apply(GraphicsContext&amp; context) const
+{
+    context.strokeEllipse(m_rect);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const StrokeEllipse&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+void ClearRect::apply(GraphicsContext&amp; context) const
+{
+    context.clearRect(m_rect);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ClearRect&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;rect&quot;, item.rect());
+    return ts;
+}
+
+void BeginTransparencyLayer::apply(GraphicsContext&amp; context) const
+{
+    context.beginTransparencyLayer(m_opacity);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const BeginTransparencyLayer&amp; item)
+{
+    ts &lt;&lt; static_cast&lt;const DrawingItem&amp;&gt;(item);
+    ts.dumpProperty(&quot;opacity&quot;, item.opacity());
+    return ts;
+}
+
+void EndTransparencyLayer::apply(GraphicsContext&amp; context) const
+{
+    context.endTransparencyLayer();
+}
+
+#if USE(CG)
+void ApplyStrokePattern::apply(GraphicsContext&amp; context) const
+{
+    context.applyStrokePattern();
+}
+
+void ApplyFillPattern::apply(GraphicsContext&amp; context) const
+{
+    context.applyFillPattern();
+}
+#endif
+
+void ApplyDeviceScaleFactor::apply(GraphicsContext&amp; context) const
+{
+    context.applyDeviceScaleFactor(m_scaleFactor);
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ApplyDeviceScaleFactor&amp; item)
+{
+    ts.dumpProperty(&quot;scale-factor&quot;, item.scaleFactor());
+    return ts;
+}
+
+static TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const ItemType&amp; type)
+{
+    switch (type) {
+    case ItemType::Save: ts &lt;&lt; &quot;save&quot;; break;
+    case ItemType::Restore: ts &lt;&lt; &quot;restore&quot;; break;
+    case ItemType::Translate: ts &lt;&lt; &quot;translate&quot;; break;
+    case ItemType::Rotate: ts &lt;&lt; &quot;rotate&quot;; break;
+    case ItemType::Scale: ts &lt;&lt; &quot;scale&quot;; break;
+    case ItemType::ConcatenateCTM: ts &lt;&lt; &quot;concatentate-ctm&quot;; break;
+    case ItemType::SetState: ts &lt;&lt; &quot;set-state&quot;; break;
+    case ItemType::SetLineCap: ts &lt;&lt; &quot;set-line-cap&quot;; break;
+    case ItemType::SetLineDash: ts &lt;&lt; &quot;set-line-dash&quot;; break;
+    case ItemType::SetLineJoin: ts &lt;&lt; &quot;set-line-join&quot;; break;
+    case ItemType::SetMiterLimit: ts &lt;&lt; &quot;set-miter-limit&quot;; break;
+    case ItemType::Clip: ts &lt;&lt; &quot;clip&quot;; break;
+    case ItemType::ClipOut: ts &lt;&lt; &quot;clip-out&quot;; break;
+    case ItemType::ClipOutToPath: ts &lt;&lt; &quot;clip-out-to-path&quot;; break;
+    case ItemType::ClipPath: ts &lt;&lt; &quot;clip-path&quot;; break;
+    case ItemType::ClipConvexPolygon: ts &lt;&lt; &quot;clip-convex-polygon&quot;; break;
+    case ItemType::DrawGlyphs: ts &lt;&lt; &quot;draw-glyphs&quot;; break;
+    case ItemType::DrawImage: ts &lt;&lt; &quot;draw-image&quot;; break;
+    case ItemType::DrawTiledImage: ts &lt;&lt; &quot;draw-tiled-image&quot;; break;
+    case ItemType::DrawTiledScaledImage: ts &lt;&lt; &quot;draw-tiled-scaled-image&quot;; break;
+#if USE(CG) || USE(CAIRO)
+    case ItemType::DrawNativeImage: ts &lt;&lt; &quot;draw-native-image&quot;; break;
+#endif
+    case ItemType::DrawPattern: ts &lt;&lt; &quot;draw-pattern&quot;; break;
+    case ItemType::DrawRect: ts &lt;&lt; &quot;draw-rect&quot;; break;
+    case ItemType::DrawLine: ts &lt;&lt; &quot;draw-line&quot;; break;
+    case ItemType::DrawLinesForText: ts &lt;&lt; &quot;draw-lines-for-text&quot;; break;
+    case ItemType::DrawLineForDocumentMarker: ts &lt;&lt; &quot;draw-lines-for-document-marker&quot;; break;
+    case ItemType::DrawEllipse: ts &lt;&lt; &quot;draw-ellipse&quot;; break;
+    case ItemType::DrawConvexPolygon: ts &lt;&lt; &quot;draw-convex-polgon&quot;; break;
+    case ItemType::DrawPath: ts &lt;&lt; &quot;draw-path&quot;; break;
+    case ItemType::DrawFocusRingPath: ts &lt;&lt; &quot;draw-focus-ring-path&quot;; break;
+    case ItemType::DrawFocusRingRects: ts &lt;&lt; &quot;draw-focus-ring-rects&quot;; break;
+    case ItemType::FillRect: ts &lt;&lt; &quot;fill-rect&quot;; break;
+    case ItemType::FillRectWithColor: ts &lt;&lt; &quot;fill-rect-with-color&quot;; break;
+    case ItemType::FillRectWithGradient: ts &lt;&lt; &quot;fill-rect-with-gradient&quot;; break;
+    case ItemType::FillCompositedRect: ts &lt;&lt; &quot;fill-composited-rect&quot;; break;
+    case ItemType::FillRoundedRect: ts &lt;&lt; &quot;fill-rounded-rect&quot;; break;
+    case ItemType::FillRectWithRoundedHole: ts &lt;&lt; &quot;fill-rect-with-rounded-hole&quot;; break;
+    case ItemType::FillPath: ts &lt;&lt; &quot;fill-path&quot;; break;
+    case ItemType::FillEllipse: ts &lt;&lt; &quot;fill-ellipse&quot;; break;
+    case ItemType::StrokeRect: ts &lt;&lt; &quot;stroke-rect&quot;; break;
+    case ItemType::StrokePath: ts &lt;&lt; &quot;stroke-path&quot;; break;
+    case ItemType::StrokeEllipse: ts &lt;&lt; &quot;stroke-ellipse&quot;; break;
+    case ItemType::ClearRect: ts &lt;&lt; &quot;clear-rect&quot;; break;
+    case ItemType::BeginTransparencyLayer: ts &lt;&lt; &quot;begin-transparency-layer&quot;; break;
+    case ItemType::EndTransparencyLayer: ts &lt;&lt; &quot;end-transparency-layer&quot;; break;
+#if USE(CG)
+    case ItemType::ApplyStrokePattern: ts &lt;&lt; &quot;apply-stroke-pattern&quot;; break;
+    case ItemType::ApplyFillPattern: ts &lt;&lt; &quot;apply-fill-pattern&quot;; break;
+#endif
+    case ItemType::ApplyDeviceScaleFactor: ts &lt;&lt; &quot;apply-device-scale-factor&quot;; break;
+    case ItemType::ClearShadow: ts &lt;&lt; &quot;clear-shadow&quot;; break;
+    }
+    return ts;
+}
+
+TextStream&amp; operator&lt;&lt;(TextStream&amp; ts, const Item&amp; item)
+{
+    TextStream::GroupScope group(ts);
+    ts &lt;&lt; item.type();
+
+    // FIXME: Make a macro which takes a macro for all these enumeration switches
+    switch (item.type()) {
+    case ItemType::Save:
+        ts &lt;&lt; downcast&lt;Save&gt;(item);
+        break;
+    case ItemType::Translate:
+        ts &lt;&lt; downcast&lt;Translate&gt;(item);
+        break;
+    case ItemType::Rotate:
+        ts &lt;&lt; downcast&lt;Rotate&gt;(item);
+        break;
+    case ItemType::Scale:
+        ts &lt;&lt; downcast&lt;Scale&gt;(item);
+        break;
+    case ItemType::ConcatenateCTM:
+        ts &lt;&lt; downcast&lt;ConcatenateCTM&gt;(item);
+        break;
+    case ItemType::SetState:
+        ts &lt;&lt; downcast&lt;SetState&gt;(item);
+        break;
+    case ItemType::SetLineCap:
+        ts &lt;&lt; downcast&lt;SetLineCap&gt;(item);
+        break;
+    case ItemType::SetLineDash:
+        ts &lt;&lt; downcast&lt;SetLineDash&gt;(item);
+        break;
+    case ItemType::SetLineJoin:
+        ts &lt;&lt; downcast&lt;SetLineJoin&gt;(item);
+        break;
+    case ItemType::SetMiterLimit:
+        ts &lt;&lt; downcast&lt;SetMiterLimit&gt;(item);
+        break;
+    case ItemType::Clip:
+        ts &lt;&lt; downcast&lt;Clip&gt;(item);
+        break;
+    case ItemType::ClipOut:
+        ts &lt;&lt; downcast&lt;ClipOut&gt;(item);
+        break;
+    case ItemType::ClipOutToPath:
+        ts &lt;&lt; downcast&lt;ClipOutToPath&gt;(item);
+        break;
+    case ItemType::ClipPath:
+        ts &lt;&lt; downcast&lt;ClipPath&gt;(item);
+        break;
+    case ItemType::ClipConvexPolygon:
+        ts &lt;&lt; downcast&lt;ClipConvexPolygon&gt;(item);
+        break;
+    case ItemType::DrawGlyphs:
+        ts &lt;&lt; downcast&lt;DrawGlyphs&gt;(item);
+        break;
+    case ItemType::DrawImage:
+        ts &lt;&lt; downcast&lt;DrawImage&gt;(item);
+        break;
+    case ItemType::DrawTiledImage:
+        ts &lt;&lt; downcast&lt;DrawTiledImage&gt;(item);
+        break;
+    case ItemType::DrawTiledScaledImage:
+        ts &lt;&lt; downcast&lt;DrawTiledScaledImage&gt;(item);
+        break;
+#if USE(CG) || USE(CAIRO)
+    case ItemType::DrawNativeImage:
+        ts &lt;&lt; downcast&lt;DrawNativeImage&gt;(item);
+        break;
+#endif
+    case ItemType::DrawPattern:
+        ts &lt;&lt; downcast&lt;DrawPattern&gt;(item);
+        break;
+    case ItemType::DrawRect:
+        ts &lt;&lt; downcast&lt;DrawRect&gt;(item);
+        break;
+    case ItemType::DrawLine:
+        ts &lt;&lt; downcast&lt;DrawLine&gt;(item);
+        break;
+    case ItemType::DrawLinesForText:
+        ts &lt;&lt; downcast&lt;DrawLinesForText&gt;(item);
+        break;
+    case ItemType::DrawLineForDocumentMarker:
+        ts &lt;&lt; downcast&lt;DrawLineForDocumentMarker&gt;(item);
+        break;
+    case ItemType::DrawEllipse:
+        ts &lt;&lt; downcast&lt;DrawEllipse&gt;(item);
+        break;
+    case ItemType::DrawConvexPolygon:
+        ts &lt;&lt; downcast&lt;DrawConvexPolygon&gt;(item);
+        break;
+    case ItemType::DrawPath:
+        ts &lt;&lt; downcast&lt;DrawPath&gt;(item);
+        break;
+    case ItemType::DrawFocusRingPath:
+        ts &lt;&lt; downcast&lt;DrawFocusRingPath&gt;(item);
+        break;
+    case ItemType::DrawFocusRingRects:
+        ts &lt;&lt; downcast&lt;DrawFocusRingRects&gt;(item);
+        break;
+    case ItemType::FillRect:
+        ts &lt;&lt; downcast&lt;FillRect&gt;(item);
+        break;
+    case ItemType::FillRectWithColor:
+        ts &lt;&lt; downcast&lt;FillRectWithColor&gt;(item);
+        break;
+    case ItemType::FillRectWithGradient:
+        ts &lt;&lt; downcast&lt;FillRectWithGradient&gt;(item);
+        break;
+    case ItemType::FillCompositedRect:
+        ts &lt;&lt; downcast&lt;FillCompositedRect&gt;(item);
+        break;
+    case ItemType::FillRoundedRect:
+        ts &lt;&lt; downcast&lt;FillRoundedRect&gt;(item);
+        break;
+    case ItemType::FillRectWithRoundedHole:
+        ts &lt;&lt; downcast&lt;FillRectWithRoundedHole&gt;(item);
+        break;
+    case ItemType::FillPath:
+        ts &lt;&lt; downcast&lt;FillPath&gt;(item);
+        break;
+    case ItemType::FillEllipse:
+        ts &lt;&lt; downcast&lt;FillEllipse&gt;(item);
+        break;
+    case ItemType::StrokeRect:
+        ts &lt;&lt; downcast&lt;StrokeRect&gt;(item);
+        break;
+    case ItemType::StrokePath:
+        ts &lt;&lt; downcast&lt;StrokePath&gt;(item);
+        break;
+    case ItemType::StrokeEllipse:
+        ts &lt;&lt; downcast&lt;StrokeEllipse&gt;(item);
+        break;
+    case ItemType::ClearRect:
+        ts &lt;&lt; downcast&lt;ClearRect&gt;(item);
+        break;
+    case ItemType::BeginTransparencyLayer:
+        ts &lt;&lt; downcast&lt;BeginTransparencyLayer&gt;(item);
+        break;
+    case ItemType::ApplyDeviceScaleFactor:
+        ts &lt;&lt; downcast&lt;ApplyDeviceScaleFactor&gt;(item);
+        break;
+
+    // Items with no additional data.
+    case ItemType::Restore:
+    case ItemType::EndTransparencyLayer:
+#if USE(CG)
+    case ItemType::ApplyStrokePattern:
+    case ItemType::ApplyFillPattern:
+#endif
+    case ItemType::ClearShadow:
+        break;
+    }
+    return ts;
+}
+
+}
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListItemsh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,1431 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DisplayListItems_h
+#define DisplayListItems_h
+
+#include &quot;FloatPoint.h&quot;
+#include &quot;FloatRect.h&quot;
+#include &quot;FloatRoundedRect.h&quot;
+#include &quot;Font.h&quot;
+#include &quot;GlyphBuffer.h&quot;
+#include &quot;GraphicsContext.h&quot;
+#include &quot;Image.h&quot;
+#include &lt;wtf/RefCounted.h&gt;
+#include &lt;wtf/TypeCasts.h&gt;
+
+#if USE(CG)
+#include &quot;GraphicsContextPlatformPrivateCG.h&quot;
+#endif
+
+namespace WebCore {
+
+class TextStream;
+struct ImagePaintingOptions;
+
+namespace DisplayList {
+
+enum class ItemType {
+    Save,
+    Restore,
+    Translate,
+    Rotate,
+    Scale,
+    ConcatenateCTM,
+    SetState,
+    SetLineCap,
+    SetLineDash,
+    SetLineJoin,
+    SetMiterLimit,
+    ClearShadow,
+    Clip,
+    ClipOut,
+    ClipOutToPath,
+    ClipPath,
+    ClipConvexPolygon,
+    DrawGlyphs,
+    DrawImage,
+    DrawTiledImage,
+    DrawTiledScaledImage,
+#if USE(CG) || USE(CAIRO)
+    DrawNativeImage,
+#endif
+    DrawPattern,
+    DrawRect,
+    DrawLine,
+    DrawLinesForText,
+    DrawLineForDocumentMarker,
+    DrawEllipse,
+    DrawConvexPolygon,
+    DrawPath,
+    DrawFocusRingPath,
+    DrawFocusRingRects,
+    FillRect,
+    FillRectWithColor,
+    FillRectWithGradient,
+    FillCompositedRect,
+    FillRoundedRect,
+    FillRectWithRoundedHole,
+    FillPath,
+    FillEllipse,
+    StrokeRect,
+    StrokePath,
+    StrokeEllipse,
+    ClearRect,
+    BeginTransparencyLayer,
+    EndTransparencyLayer,
+#if USE(CG)
+    ApplyStrokePattern, // FIXME: should not be a recorded item.
+    ApplyFillPattern, // FIXME: should not be a recorded item.
+#endif
+    ApplyDeviceScaleFactor,
+};
+
+class Item : public RefCounted&lt;Item&gt; {
+public:
+    Item() = delete;
+
+    Item(ItemType type)
+        : m_type(type)
+    {
+    }
+
+    virtual ~Item() { }
+
+    ItemType type() const
+    {
+        return m_type;
+    }
+
+    virtual void apply(GraphicsContext&amp;) const = 0;
+
+    static constexpr bool isDisplayListItem = true;
+
+    virtual bool isDrawingItem() const { return false; }
+    
+    // A state item is one preserved by Save/Restore.
+    bool isStateItem() const
+    {
+        return isStateItemType(m_type);
+    }
+
+    static bool isStateItemType(ItemType itemType)
+    {
+        switch (itemType) {
+        case ItemType:: Translate:
+        case ItemType:: Rotate:
+        case ItemType:: Scale:
+        case ItemType:: ConcatenateCTM:
+        case ItemType:: SetState:
+        case ItemType:: SetLineCap:
+        case ItemType:: SetLineDash:
+        case ItemType:: SetLineJoin:
+        case ItemType:: SetMiterLimit:
+        case ItemType:: ClearShadow:
+            return true;
+        default:
+            return false;
+        }
+        return false;
+    }
+
+#if !defined(NDEBUG) || !LOG_DISABLED
+    WTF::CString description() const;
+#endif
+    static size_t sizeInBytes(const Item&amp;);
+
+private:
+    ItemType m_type;
+};
+
+class DrawingItem : public Item {
+public:
+    DrawingItem(ItemType type)
+        : Item(type)
+    {
+    }
+
+    void setExtent(const FloatRect&amp; r) { m_extent = r; }
+    const FloatRect&amp; extent() const { return m_extent.value(); }
+
+    bool extentKnown() const { return static_cast&lt;bool&gt;(m_extent); }
+
+    // Return bounds of this drawing operation in local coordinates.
+    // Does not include effets of transform, shadow etc in the state.
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const { return Nullopt; }
+
+private:
+    virtual bool isDrawingItem() const { return true; }
+
+    Optional&lt;FloatRect&gt; m_extent; // In base coordinates, taking shadows and transforms into account.
+};
+
+class Save : public Item {
+public:
+    static Ref&lt;Save&gt; create()
+    {
+        return adoptRef(*new Save);
+    }
+
+    // Index in the display list of the corresponding Restore item. 0 if unmatched.
+    size_t restoreIndex() const { return m_restoreIndex; }
+    void setRestoreIndex(size_t index) { m_restoreIndex = index; }
+
+private:
+    Save()
+        : Item(ItemType::Save)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    
+    size_t m_restoreIndex { 0 };
+};
+
+class Restore : public Item {
+public:
+    static Ref&lt;Restore&gt; create()
+    {
+        return adoptRef(*new Restore);
+    }
+
+private:
+    Restore()
+        : Item(ItemType::Restore)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+};
+
+class Translate : public Item {
+public:
+    static Ref&lt;Translate&gt; create(float x, float y)
+    {
+        return adoptRef(*new Translate(x, y));
+    }
+
+    float x() const { return m_x; }
+    float y() const { return m_y; }
+
+private:
+    Translate(float x, float y)
+        : Item(ItemType::Translate)
+        , m_x(x)
+        , m_y(y)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    float m_x;
+    float m_y;
+};
+
+class Rotate : public Item {
+public:
+    static Ref&lt;Rotate&gt; create(float angleInRadians)
+    {
+        return adoptRef(*new Rotate(angleInRadians));
+    }
+
+    float angle() const { return m_angle; }
+
+private:
+    Rotate(float angle)
+        : Item(ItemType::Rotate)
+        , m_angle(angle)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    float m_angle; // In radians.
+};
+
+class Scale : public Item {
+public:
+    static Ref&lt;Scale&gt; create(const FloatSize&amp; size)
+    {
+        return adoptRef(*new Scale(size));
+    }
+
+    const FloatSize&amp; amount() const { return m_size; }
+
+private:
+    Scale(const FloatSize&amp; size)
+        : Item(ItemType::Scale)
+        , m_size(size)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    FloatSize m_size;
+};
+
+class ConcatenateCTM : public Item {
+public:
+    static Ref&lt;ConcatenateCTM&gt; create(const AffineTransform&amp; matrix)
+    {
+        return adoptRef(*new ConcatenateCTM(matrix));
+    }
+
+    const AffineTransform&amp; transform() const { return m_transform; }
+
+private:
+    ConcatenateCTM(const AffineTransform&amp;);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    AffineTransform m_transform;
+};
+
+class SetState : public Item {
+public:
+    static Ref&lt;SetState&gt; create(const GraphicsContextState&amp; state, GraphicsContextState::StateChangeFlags flags)
+    {
+        return adoptRef(*new SetState(state, flags));
+    }
+    
+    const GraphicsContextStateChange&amp; state() const { return m_state; }
+
+    void accumulate(const GraphicsContextState&amp;, GraphicsContextState::StateChangeFlags);
+
+    void accumulate(GraphicsContextState&amp;) const;
+
+    static void applyState(GraphicsContext&amp;, const GraphicsContextState&amp;, GraphicsContextState::StateChangeFlags);
+
+    static void dumpStateChanges(TextStream&amp;, const GraphicsContextState&amp;, GraphicsContextState::StateChangeFlags);
+private:
+    SetState(const GraphicsContextState&amp; state, GraphicsContextState::StateChangeFlags flags)
+        : Item(ItemType::SetState)
+        , m_state(state, flags)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    GraphicsContextStateChange m_state;
+};
+
+class SetLineCap : public Item {
+public:
+    static Ref&lt;SetLineCap&gt; create(LineCap lineCap)
+    {
+        return adoptRef(*new SetLineCap(lineCap));
+    }
+    
+    LineCap lineCap() const { return m_lineCap; }
+
+private:
+    SetLineCap(LineCap lineCap)
+        : Item(ItemType::SetLineCap)
+        , m_lineCap(lineCap)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    LineCap m_lineCap;
+};
+
+class SetLineDash : public Item {
+public:
+    static Ref&lt;SetLineDash&gt; create(const DashArray&amp; dashArray, float dashOffset)
+    {
+        return adoptRef(*new SetLineDash(dashArray, dashOffset));
+    }
+
+    const DashArray&amp; dashArray() const { return m_dashArray; }
+    float dashOffset() const { return m_dashOffset; }
+
+private:
+    SetLineDash(const DashArray&amp; dashArray, float dashOffset)
+        : Item(ItemType::SetLineDash)
+        , m_dashArray(dashArray)
+        , m_dashOffset(dashOffset)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    DashArray m_dashArray;
+    float m_dashOffset;
+};
+
+class SetLineJoin : public Item {
+public:
+    static Ref&lt;SetLineJoin&gt; create(LineJoin lineJoin)
+    {
+        return adoptRef(*new SetLineJoin(lineJoin));
+    }
+    
+    LineJoin lineJoin() const { return m_lineJoin; }
+
+private:
+    SetLineJoin(LineJoin lineJoin)
+        : Item(ItemType::SetLineJoin)
+        , m_lineJoin(lineJoin)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    LineJoin m_lineJoin;
+};
+
+class SetMiterLimit : public Item {
+public:
+    static Ref&lt;SetMiterLimit&gt; create(float limit)
+    {
+        return adoptRef(*new SetMiterLimit(limit));
+    }
+
+    float miterLimit() const { return m_miterLimit; }
+
+private:
+    SetMiterLimit(float miterLimit)
+        : Item(ItemType::SetMiterLimit)
+        , m_miterLimit(miterLimit)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    float m_miterLimit;
+};
+
+class ClearShadow : public Item {
+public:
+    static Ref&lt;ClearShadow&gt; create()
+    {
+        return adoptRef(*new ClearShadow);
+    }
+
+private:
+    ClearShadow()
+        : Item(ItemType::ClearShadow)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+};
+
+// FIXME: treat as DrawingItem?
+class Clip : public Item {
+public:
+    static Ref&lt;Clip&gt; create(const FloatRect&amp; rect)
+    {
+        return adoptRef(*new Clip(rect));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    Clip(const FloatRect&amp; rect)
+        : Item(ItemType::Clip)
+        , m_rect(rect)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    FloatRect m_rect;
+};
+
+class ClipOut : public Item {
+public:
+    static Ref&lt;ClipOut&gt; create(const FloatRect&amp; rect)
+    {
+        return adoptRef(*new ClipOut(rect));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    ClipOut(const FloatRect&amp; rect)
+        : Item(ItemType::ClipOut)
+        , m_rect(rect)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    FloatRect m_rect;
+};
+
+class ClipOutToPath : public Item {
+public:
+    static Ref&lt;ClipOutToPath&gt; create(const Path&amp; path)
+    {
+        return adoptRef(*new ClipOutToPath(path));
+    }
+
+    const Path&amp; path() const { return m_path; }
+
+private:
+    ClipOutToPath(const Path&amp; path)
+        : Item(ItemType::ClipOutToPath)
+        , m_path(path)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    const Path m_path;
+};
+
+class ClipPath : public Item {
+public:
+    static Ref&lt;ClipPath&gt; create(const Path&amp; path, WindRule windRule)
+    {
+        return adoptRef(*new ClipPath(path, windRule));
+    }
+
+    const Path&amp; path() const { return m_path; }
+    WindRule windRule() const { return m_windRule; }
+
+private:
+    ClipPath(const Path&amp; path, WindRule windRule)
+        : Item(ItemType::ClipPath)
+        , m_path(path)
+        , m_windRule(windRule)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    const Path m_path;
+    WindRule m_windRule;
+};
+
+class ClipConvexPolygon : public Item {
+public:
+    static Ref&lt;ClipConvexPolygon&gt; create(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+    {
+        return adoptRef(*new ClipConvexPolygon(numberOfPoints, points, antialiased));
+    }
+
+    const Vector&lt;FloatPoint&gt;&amp; points() const { return m_points; }
+    bool antialias() const { return m_antialias; }
+
+private:
+    ClipConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    Vector&lt;FloatPoint&gt; m_points;
+    bool m_antialias;
+};
+
+class DrawGlyphs : public DrawingItem {
+public:
+    static Ref&lt;DrawGlyphs&gt; create(const Font&amp; font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint&amp; blockLocation, const FloatSize&amp; localAnchor, FontSmoothingMode smoothingMode)
+    {
+        return adoptRef(*new DrawGlyphs(font, glyphs, advances, count, blockLocation, localAnchor, smoothingMode));
+    }
+
+    const FloatPoint&amp; blockLocation() const { return m_blockLocation; }
+    void setBlockLocation(const FloatPoint&amp; blockLocation) { m_blockLocation = blockLocation; }
+
+    const FloatSize&amp; localAnchor() const { return m_localAnchor; }
+
+    FloatPoint anchorPoint() const { return m_blockLocation + m_localAnchor; }
+
+    const Vector&lt;GlyphBufferGlyph, 128&gt;&amp; glyphs() const { return m_glyphs; }
+
+private:
+    DrawGlyphs(const Font&amp;, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned count, const FloatPoint&amp; blockLocation, const FloatSize&amp; localAnchor, FontSmoothingMode);
+
+    void computeBounds();
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    GlyphBuffer generateGlyphBuffer() const;
+
+    Ref&lt;Font&gt; m_font;
+    Vector&lt;GlyphBufferGlyph, 128&gt; m_glyphs;
+    Vector&lt;GlyphBufferAdvance, 128&gt; m_advances;
+    FloatRect m_bounds;
+    FloatPoint m_blockLocation;
+    FloatSize m_localAnchor;
+    FontSmoothingMode m_smoothingMode;
+};
+
+class DrawImage : public DrawingItem {
+public:
+    static Ref&lt;DrawImage&gt; create(Image&amp; image, const FloatRect&amp; destination, const FloatRect&amp; source, const ImagePaintingOptions&amp; imagePaintingOptions)
+    {
+        return adoptRef(*new DrawImage(image, destination, source, imagePaintingOptions));
+    }
+
+    const Image&amp; image() const { return m_image.get(); }
+    FloatRect source() const { return m_source; }
+    FloatRect destination() const { return m_destination; }
+
+private:
+    DrawImage(Image&amp;, const FloatRect&amp; destination, const FloatRect&amp; source, const ImagePaintingOptions&amp;);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_destination; }
+
+    mutable Ref&lt;Image&gt; m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
+    FloatRect m_destination;
+    FloatRect m_source;
+    ImagePaintingOptions m_imagePaintingOptions;
+};
+
+class DrawTiledImage : public DrawingItem {
+public:
+    static Ref&lt;DrawTiledImage&gt; create(Image&amp; image, const FloatRect&amp; destination, const FloatPoint&amp; source, const FloatSize&amp; tileSize, const FloatSize&amp; spacing, const ImagePaintingOptions&amp; imagePaintingOptions)
+    {
+        return adoptRef(*new DrawTiledImage(image, destination, source, tileSize, spacing, imagePaintingOptions));
+    }
+
+    const Image&amp; image() const { return m_image.get(); }
+    FloatPoint source() const { return m_source; }
+    FloatRect destination() const { return m_destination; }
+
+    FloatSize tileSize() const { return m_tileSize; }
+    FloatSize spacing() const { return m_spacing; }
+
+private:
+    DrawTiledImage(Image&amp;, const FloatRect&amp; destination, const FloatPoint&amp; source, const FloatSize&amp; tileSize, const FloatSize&amp; spacing, const ImagePaintingOptions&amp;);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_destination; }
+
+    mutable Ref&lt;Image&gt; m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
+    FloatRect m_destination;
+    FloatPoint m_source;
+    FloatSize m_tileSize;
+    FloatSize m_spacing;
+    ImagePaintingOptions m_imagePaintingOptions;
+};
+
+class DrawTiledScaledImage : public DrawingItem {
+public:
+    static Ref&lt;DrawTiledScaledImage&gt; create(Image&amp; image, const FloatRect&amp; destination, const FloatRect&amp; source, const FloatSize&amp; tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&amp; imagePaintingOptions)
+    {
+        return adoptRef(*new DrawTiledScaledImage(image, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions));
+    }
+
+    const Image&amp; image() const { return m_image.get(); }
+    FloatRect source() const { return m_source; }
+    FloatRect destination() const { return m_destination; }
+
+private:
+    DrawTiledScaledImage(Image&amp;, const FloatRect&amp; destination, const FloatRect&amp; source, const FloatSize&amp; tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&amp;);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_destination; }
+
+    mutable Ref&lt;Image&gt; m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
+    FloatRect m_destination;
+    FloatRect m_source;
+    FloatSize m_tileScaleFactor;
+    Image::TileRule m_hRule;
+    Image::TileRule m_vRule;
+    ImagePaintingOptions m_imagePaintingOptions;
+};
+
+#if USE(CG) || USE(CAIRO)
+class DrawNativeImage : public DrawingItem {
+public:
+    static Ref&lt;DrawNativeImage&gt; create(PassNativeImagePtr imagePtr, const FloatSize&amp; imageSize, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation)
+    {
+        return adoptRef(*new DrawNativeImage(imagePtr, imageSize, destRect, srcRect, op, blendMode, orientation));
+    }
+
+    FloatRect source() const { return m_srcRect; }
+    FloatRect destination() const { return m_destination; }
+
+private:
+    DrawNativeImage(PassNativeImagePtr, const FloatSize&amp; selfSize, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, CompositeOperator, BlendMode, ImageOrientation);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_destination; }
+
+#if USE(CG)
+    RetainPtr&lt;CGImageRef&gt; m_imagePtr;
+#endif
+    FloatSize m_imageSize;
+    FloatRect m_destination;
+    FloatRect m_srcRect;
+    CompositeOperator m_op;
+    BlendMode m_blendMode;
+    ImageOrientation m_orientation;
+};
+#endif
+
+class DrawPattern : public DrawingItem {
+public:
+    static Ref&lt;DrawPattern&gt; create(Image&amp; image, const FloatRect&amp; tileRect, const AffineTransform&amp; patternTransform, const FloatPoint&amp; phase, const FloatSize&amp; spacing, CompositeOperator op, const FloatRect&amp; destRect, BlendMode blendMode)
+    {
+        return adoptRef(*new DrawPattern(image, tileRect, patternTransform, phase, spacing, op, destRect, blendMode));
+    }
+
+    const Image&amp; image() const { return m_image.get(); }
+    const AffineTransform&amp; patternTransform() const { return m_patternTransform; }
+    FloatRect tileRect() const { return m_tileRect; }
+    FloatRect destRect() const { return m_destination; }
+    FloatPoint phase() const { return m_phase; }
+    FloatSize spacing() const { return m_spacing; }
+
+private:
+    DrawPattern(Image&amp;, const FloatRect&amp; srcRect, const AffineTransform&amp;, const FloatPoint&amp; phase, const FloatSize&amp; spacing, CompositeOperator, const FloatRect&amp; destRect, BlendMode = BlendModeNormal);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_destination; }
+
+    mutable Ref&lt;Image&gt; m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable.
+    AffineTransform m_patternTransform;
+    FloatRect m_tileRect;
+    FloatRect m_destination;
+    FloatPoint m_phase;
+    FloatSize m_spacing;
+    CompositeOperator m_op;
+    BlendMode m_blendMode;
+};
+
+// Is DrawingItem because the size of the transparency layer is implicitly the clip bounds.
+class BeginTransparencyLayer : public DrawingItem {
+public:
+    static Ref&lt;BeginTransparencyLayer&gt; create(float opacity)
+    {
+        return adoptRef(*new BeginTransparencyLayer(opacity));
+    }
+
+    float opacity() const { return m_opacity; }
+
+private:
+    BeginTransparencyLayer(float opacity)
+        : DrawingItem(ItemType::BeginTransparencyLayer)
+        , m_opacity(opacity)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    float m_opacity;
+};
+
+class EndTransparencyLayer : public DrawingItem {
+public:
+    static Ref&lt;EndTransparencyLayer&gt; create()
+    {
+        return adoptRef(*new EndTransparencyLayer);
+    }
+
+private:
+    EndTransparencyLayer()
+        : DrawingItem(ItemType::EndTransparencyLayer)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+};
+
+class DrawRect : public DrawingItem {
+public:
+    static Ref&lt;DrawRect&gt; create(const FloatRect&amp; rect, float borderThickness)
+    {
+        return adoptRef(*new DrawRect(rect, borderThickness));
+    }
+
+    FloatRect rect() const { return m_rect; }
+    float borderThickness() const { return m_borderThickness; }
+
+private:
+    DrawRect(const FloatRect&amp; rect, float borderThickness)
+        : DrawingItem(ItemType::DrawRect)
+        , m_rect(rect)
+        , m_borderThickness(borderThickness)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+    float m_borderThickness;
+};
+
+class DrawLine : public DrawingItem {
+public:
+    static Ref&lt;DrawLine&gt; create(const FloatPoint&amp; point1, const FloatPoint&amp; point2)
+    {
+        return adoptRef(*new DrawLine(point1, point2));
+    }
+
+    FloatPoint point1() const { return m_point1; }
+    FloatPoint point2() const { return m_point2; }
+
+private:
+    DrawLine(const FloatPoint&amp; point1, const FloatPoint&amp; point2)
+        : DrawingItem(ItemType::DrawLine)
+        , m_point1(point1)
+        , m_point2(point2)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    FloatPoint m_point1;
+    FloatPoint m_point2;
+};
+
+class DrawLinesForText : public DrawingItem {
+public:
+    static Ref&lt;DrawLinesForText&gt; create(const FloatPoint&amp; blockLocation, const FloatSize&amp; localAnchor, const DashArray&amp; widths, bool printing, bool doubleLines, float strokeWidth)
+    {
+        return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, widths, printing, doubleLines, strokeWidth));
+    }
+
+    void setBlockLocation(const FloatPoint&amp; blockLocation) { m_blockLocation = blockLocation; }
+    const FloatPoint&amp; blockLocation() const { return m_blockLocation; }
+    const FloatSize&amp; localAnchor() const { return m_localAnchor; }
+    FloatPoint point() const { return m_blockLocation + m_localAnchor; }
+    const DashArray&amp; widths() const { return m_widths; }
+    bool isPrinting() const { return m_printing; }
+    bool doubleLines() const { return m_doubleLines; }
+
+private:
+    DrawLinesForText(const FloatPoint&amp; blockLocation, const FloatSize&amp; localAnchor, const DashArray&amp; widths, bool printing, bool doubleLines, float strokeWidth)
+        : DrawingItem(ItemType::DrawLinesForText)
+        , m_blockLocation(blockLocation)
+        , m_localAnchor(localAnchor)
+        , m_widths(widths)
+        , m_strokeWidth(strokeWidth)
+        , m_printing(printing)
+        , m_doubleLines(doubleLines)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    FloatPoint m_blockLocation;
+    FloatSize m_localAnchor;
+    DashArray m_widths;
+    float m_strokeWidth;
+    bool m_printing;
+    bool m_doubleLines;
+};
+
+class DrawLineForDocumentMarker : public DrawingItem {
+public:
+    static Ref&lt;DrawLineForDocumentMarker&gt; create(const FloatPoint&amp; point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+    {
+        return adoptRef(*new DrawLineForDocumentMarker(point, width, style));
+    }
+
+    FloatPoint point() const { return m_point; }
+    float width() const { return m_width; }
+
+private:
+    DrawLineForDocumentMarker(const FloatPoint&amp; point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+        : DrawingItem(ItemType::DrawLineForDocumentMarker)
+        , m_point(point)
+        , m_width(width)
+        , m_style(style)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    FloatPoint m_point;
+    float m_width;
+    GraphicsContext::DocumentMarkerLineStyle m_style;
+};
+
+class DrawEllipse : public DrawingItem {
+public:
+    static Ref&lt;DrawEllipse&gt; create(const FloatRect&amp; rect)
+    {
+        return adoptRef(*new DrawEllipse(rect));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    DrawEllipse(const FloatRect&amp; rect)
+        : DrawingItem(ItemType::DrawEllipse)
+        , m_rect(rect)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+};
+
+class DrawConvexPolygon : public DrawingItem {
+public:
+    static Ref&lt;DrawConvexPolygon&gt; create(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+    {
+        return adoptRef(*new DrawConvexPolygon(numberOfPoints, points, antialiased));
+    }
+
+    const Vector&lt;FloatPoint&gt;&amp; points() const { return m_points; }
+    bool antialiased() const { return m_antialiased; }
+
+private:
+    DrawConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased);
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    Vector&lt;FloatPoint&gt; m_points;
+    bool m_antialiased;
+};
+
+class DrawPath : public DrawingItem {
+public:
+    static Ref&lt;DrawPath&gt; create(const Path&amp; path)
+    {
+        return adoptRef(*new DrawPath(path));
+    }
+
+    const Path&amp; path() const { return m_path; }
+
+private:
+    DrawPath(const Path&amp; path)
+        : DrawingItem(ItemType::DrawPath)
+        , m_path(path)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_path.fastBoundingRect(); }
+
+    const Path m_path;
+};
+
+class DrawFocusRingPath : public DrawingItem {
+public:
+    static Ref&lt;DrawFocusRingPath&gt; create(const Path&amp; path, int width, int offset, const Color&amp; color)
+    {
+        return adoptRef(*new DrawFocusRingPath(path, width, offset, color));
+    }
+
+    const Path&amp; path() const { return m_path; }
+    int width() const { return m_width; }
+    int offset() const { return m_offset; }
+    Color color() const { return m_color; }
+
+private:
+    DrawFocusRingPath(const Path&amp; path, int width, int offset, const Color&amp; color)
+        : DrawingItem(ItemType::DrawFocusRingPath)
+        , m_path(path)
+        , m_width(width)
+        , m_offset(offset)
+        , m_color(color)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    const Path m_path;
+    int m_width;
+    int m_offset;
+    Color m_color;
+};
+
+class DrawFocusRingRects : public DrawingItem {
+public:
+    static Ref&lt;DrawFocusRingRects&gt; create(const Vector&lt;IntRect&gt;&amp; rects, int width, int offset, const Color&amp; color)
+    {
+        return adoptRef(*new DrawFocusRingRects(rects, width, offset, color));
+    }
+
+    const Vector&lt;IntRect&gt; rects() const { return m_rects; }
+    int width() const { return m_width; }
+    int offset() const { return m_offset; }
+    Color color() const { return m_color; }
+
+private:
+    DrawFocusRingRects(const Vector&lt;IntRect&gt;&amp; rects, int width, int offset, const Color&amp; color)
+        : DrawingItem(ItemType::DrawFocusRingRects)
+        , m_rects(rects)
+        , m_width(width)
+        , m_offset(offset)
+        , m_color(color)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    Vector&lt;IntRect&gt; m_rects;
+    int m_width;
+    int m_offset;
+    Color m_color;
+};
+
+class FillRect : public DrawingItem {
+public:
+    static Ref&lt;FillRect&gt; create(const FloatRect&amp; rect)
+    {
+        return adoptRef(*new FillRect(rect));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    FillRect(const FloatRect&amp; rect)
+        : DrawingItem(ItemType::FillRect)
+        , m_rect(rect)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+};
+
+// FIXME: Make these inherit from FillRect proper.
+class FillRectWithColor : public DrawingItem {
+public:
+    static Ref&lt;FillRectWithColor&gt; create(const FloatRect&amp; rect, const Color&amp; color)
+    {
+        return adoptRef(*new FillRectWithColor(rect, color));
+    }
+
+    FloatRect rect() const { return m_rect; }
+    Color color() const { return m_color; }
+
+private:
+    FillRectWithColor(const FloatRect&amp; rect, const Color&amp; color)
+        : DrawingItem(ItemType::FillRectWithColor)
+        , m_rect(rect)
+        , m_color(color)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+    Color m_color;
+};
+
+class FillRectWithGradient : public DrawingItem {
+public:
+    static Ref&lt;FillRectWithGradient&gt; create(const FloatRect&amp; rect, Gradient&amp; gradient)
+    {
+        return adoptRef(*new FillRectWithGradient(rect, gradient));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    FillRectWithGradient(const FloatRect&amp; rect, Gradient&amp; gradient)
+        : DrawingItem(ItemType::FillRectWithGradient)
+        , m_rect(rect)
+        , m_gradient(gradient)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+    mutable Ref&lt;Gradient&gt; m_gradient; // FIXME: Make this not mutable
+};
+
+class FillCompositedRect : public DrawingItem {
+public:
+    static Ref&lt;FillCompositedRect&gt; create(const FloatRect&amp; rect, const Color&amp; color, CompositeOperator op, BlendMode blendMode)
+    {
+        return adoptRef(*new FillCompositedRect(rect, color, op, blendMode));
+    }
+
+    FloatRect rect() const { return m_rect; }
+    Color color() const { return m_color; }
+    CompositeOperator compositeOperator() const { return m_op; }
+    BlendMode blendMode() const { return m_blendMode; }
+
+private:
+    FillCompositedRect(const FloatRect&amp; rect, const Color&amp; color, CompositeOperator op, BlendMode blendMode)
+        : DrawingItem(ItemType::FillCompositedRect)
+        , m_rect(rect)
+        , m_color(color)
+        , m_op(op)
+        , m_blendMode(blendMode)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+    Color m_color;
+    CompositeOperator m_op;
+    BlendMode m_blendMode;
+};
+
+class FillRoundedRect : public DrawingItem {
+public:
+    static Ref&lt;FillRoundedRect&gt; create(const FloatRoundedRect&amp; rect, const Color&amp; color, BlendMode blendMode)
+    {
+        return adoptRef(*new FillRoundedRect(rect, color, blendMode));
+    }
+
+    const FloatRoundedRect&amp; roundedRect() const { return m_rect; }
+    Color color() const { return m_color; }
+    BlendMode blendMode() const { return m_blendMode; }
+
+private:
+    FillRoundedRect(const FloatRoundedRect&amp; rect, const Color&amp; color, BlendMode blendMode)
+        : DrawingItem(ItemType::FillRoundedRect)
+        , m_rect(rect)
+        , m_color(color)
+        , m_blendMode(blendMode)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect.rect(); }
+
+    FloatRoundedRect m_rect;
+    Color m_color;
+    BlendMode m_blendMode;
+};
+
+class FillRectWithRoundedHole : public DrawingItem {
+public:
+    static Ref&lt;FillRectWithRoundedHole&gt; create(const FloatRect&amp; rect, const FloatRoundedRect&amp; roundedHoleRect, const Color&amp; color)
+    {
+        return adoptRef(*new FillRectWithRoundedHole(rect, roundedHoleRect, color));
+    }
+
+    const FloatRect&amp; rect() const { return m_rect; }
+    const FloatRoundedRect&amp; roundedHoleRect() const { return m_roundedHoleRect; }
+    Color color() const { return m_color; }
+
+private:
+    FillRectWithRoundedHole(const FloatRect&amp; rect, const FloatRoundedRect&amp; roundedHoleRect, const Color&amp; color)
+        : DrawingItem(ItemType::FillRectWithRoundedHole)
+        , m_rect(rect)
+        , m_roundedHoleRect(roundedHoleRect)
+        , m_color(color)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+    FloatRoundedRect m_roundedHoleRect;
+    Color m_color;
+};
+
+class FillPath : public DrawingItem {
+public:
+    static Ref&lt;FillPath&gt; create(const Path&amp; path)
+    {
+        return adoptRef(*new FillPath(path));
+    }
+
+    const Path&amp; path() const { return m_path; }
+
+private:
+    FillPath(const Path&amp; path)
+        : DrawingItem(ItemType::FillPath)
+        , m_path(path)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_path.fastBoundingRect(); }
+
+    const Path m_path;
+};
+
+class FillEllipse : public DrawingItem {
+public:
+    static Ref&lt;FillEllipse&gt; create(const FloatRect&amp; rect)
+    {
+        return adoptRef(*new FillEllipse(rect));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    FillEllipse(const FloatRect&amp; rect)
+        : DrawingItem(ItemType::FillEllipse)
+        , m_rect(rect)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+};
+
+class StrokeRect : public DrawingItem {
+public:
+    static Ref&lt;StrokeRect&gt; create(const FloatRect&amp; rect, float lineWidth)
+    {
+        return adoptRef(*new StrokeRect(rect, lineWidth));
+    }
+
+    FloatRect rect() const { return m_rect; }
+    float lineWidth() const { return m_lineWidth; }
+
+private:
+    StrokeRect(const FloatRect&amp; rect, float lineWidth)
+        : DrawingItem(ItemType::StrokeRect)
+        , m_rect(rect)
+        , m_lineWidth(lineWidth)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    FloatRect m_rect;
+    float m_lineWidth;
+};
+
+class StrokePath : public DrawingItem {
+public:
+    static Ref&lt;StrokePath&gt; create(const Path&amp; path)
+    {
+        return adoptRef(*new StrokePath(path));
+    }
+
+    const Path&amp; path() const { return m_path; }
+
+private:
+    StrokePath(const Path&amp; path)
+        : DrawingItem(ItemType::StrokePath)
+        , m_path(path)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    const Path m_path;
+    FloatPoint m_blockLocation;
+};
+
+class StrokeEllipse : public DrawingItem {
+public:
+    static Ref&lt;StrokeEllipse&gt; create(const FloatRect&amp; rect)
+    {
+        return adoptRef(*new StrokeEllipse(rect));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    StrokeEllipse(const FloatRect&amp; rect)
+        : DrawingItem(ItemType::StrokeEllipse)
+        , m_rect(rect)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override;
+
+    FloatRect m_rect;
+};
+
+class ClearRect : public DrawingItem {
+public:
+    static Ref&lt;ClearRect&gt; create(const FloatRect&amp; rect)
+    {
+        return adoptRef(*new ClearRect(rect));
+    }
+
+    FloatRect rect() const { return m_rect; }
+
+private:
+    ClearRect(const FloatRect&amp; rect)
+        : DrawingItem(ItemType::ClearRect)
+        , m_rect(rect)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+    virtual Optional&lt;FloatRect&gt; localBounds(const GraphicsContext&amp;) const override { return m_rect; }
+
+    FloatRect m_rect;
+};
+
+#if USE(CG)
+class ApplyStrokePattern : public Item {
+public:
+    static Ref&lt;ApplyStrokePattern&gt; create()
+    {
+        return adoptRef(*new ApplyStrokePattern);
+    }
+
+private:
+    ApplyStrokePattern()
+        : Item(ItemType::ApplyStrokePattern)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+};
+
+class ApplyFillPattern : public Item {
+public:
+    static Ref&lt;ApplyFillPattern&gt; create()
+    {
+        return adoptRef(*new ApplyFillPattern);
+    }
+
+private:
+    ApplyFillPattern()
+        : Item(ItemType::ApplyFillPattern)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+};
+#endif
+
+class ApplyDeviceScaleFactor : public Item {
+public:
+    static Ref&lt;ApplyDeviceScaleFactor&gt; create(float scaleFactor)
+    {
+        return adoptRef(*new ApplyDeviceScaleFactor(scaleFactor));
+    }
+
+    float scaleFactor() const { return m_scaleFactor; }
+
+private:
+    ApplyDeviceScaleFactor(float scaleFactor)
+        : Item(ItemType::ApplyDeviceScaleFactor)
+        , m_scaleFactor(scaleFactor)
+    {
+    }
+
+    virtual void apply(GraphicsContext&amp;) const override;
+
+    float m_scaleFactor;
+};
+
+// FIXME: this needs to move.
+void addConvexPolygonToPath(Path&amp;, size_t numPoints, const FloatPoint*);
+
+TextStream&amp; operator&lt;&lt;(TextStream&amp;, const Item&amp;);
+
+} // namespace DisplayList
+} // namespace WebCore
+
+
+#define SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_DRAWINGITEM(ToValueTypeName, predicate) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DisplayList::ToValueTypeName) \
+    static bool isType(const WebCore::DisplayList::Item&amp; object) { return object.predicate; } \
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_DRAWINGITEM(DrawingItem, isDrawingItem())
+
+#define SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ToValueTypeName) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DisplayList::ToValueTypeName) \
+    static bool isType(const WebCore::DisplayList::Item&amp; item) { return item.type() == WebCore::DisplayList::ItemType::ToValueTypeName; } \
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Save)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Restore)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Translate)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Rotate)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Scale)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ConcatenateCTM)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetState)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineCap)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineDash)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineJoin)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetMiterLimit)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Clip)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipOut)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipOutToPath)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipPath)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipConvexPolygon)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawGlyphs)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawImage)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawTiledImage)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawTiledScaledImage)
+#if USE(CG) || USE(CAIRO)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawNativeImage)
+#endif
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawPattern)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawRect)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLine)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLinesForText)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLineForDocumentMarker)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawEllipse)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawConvexPolygon)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawPath)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawFocusRingPath)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawFocusRingRects)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRect)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithColor)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithGradient)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillCompositedRect)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRoundedRect)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithRoundedHole)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillPath)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillEllipse)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeRect)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokePath)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeEllipse)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClearRect)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(BeginTransparencyLayer)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(EndTransparencyLayer)
+#if USE(CG)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyStrokePattern)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyFillPattern)
+#endif
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyDeviceScaleFactor)
+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClearShadow)
+
+#endif // DisplayListItems_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListRecordercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,482 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DisplayListRecorder.h&quot;
+
+#include &quot;DisplayList.h&quot;
+#include &quot;DisplayListItems.h&quot;
+#include &quot;GraphicsContext.h&quot;
+#include &quot;Logging.h&quot;
+#include &quot;TextStream.h&quot;
+#include &lt;wtf/MathExtras.h&gt;
+
+namespace WebCore {
+namespace DisplayList {
+
+Recorder::Recorder(GraphicsContext&amp; context, DisplayList&amp; displayList, const FloatRect&amp; initialClip, const AffineTransform&amp; baseCTM)
+    : m_graphicsContext(context)
+    , m_displayList(displayList)
+{
+    LOG_WITH_STREAM(DisplayLists, stream &lt;&lt; &quot;\nRecording with clip &quot; &lt;&lt; initialClip);
+
+    // FIXME: Hook up recorder in the GraphicsContext.
+    // m_graphicsContext.setDisplayListRecorder(this);
+    m_stateStack.append(ContextState(baseCTM, initialClip));
+}
+
+Recorder::~Recorder()
+{
+    ASSERT(m_stateStack.size() == 1); // If this fires, it indicates mismatched save/restore.
+    LOG(DisplayLists, &quot;Recorded display list:\n%s&quot;, m_displayList.description().data());
+}
+
+void Recorder::willAppendItem(const Item&amp; item)
+{
+    if (item.isDrawingItem()
+#if USE(CG)
+        || item.type() == ItemType::ApplyStrokePattern || item.type() == ItemType::ApplyStrokePattern
+#endif
+    ) {
+        GraphicsContextStateChange&amp; stateChanges = currentState().stateChange;
+        GraphicsContextState::StateChangeFlags changesFromLastState = stateChanges.changesFromState(currentState().lastDrawingState);
+        if (changesFromLastState) {
+            LOG_WITH_STREAM(DisplayLists, stream &lt;&lt; &quot;pre-drawing, saving state &quot; &lt;&lt; GraphicsContextStateChange(stateChanges.m_state, changesFromLastState));
+            m_displayList.append(SetState::create(stateChanges.m_state, changesFromLastState));
+            stateChanges.m_changeFlags = 0;
+            currentState().lastDrawingState = stateChanges.m_state;
+        }
+        currentState().wasUsedForDrawing = true;
+    }
+}
+
+void Recorder::updateState(const GraphicsContextState&amp; state, GraphicsContextState::StateChangeFlags flags)
+{
+    currentState().stateChange.accumulate(state, flags);
+}
+
+void Recorder::clearShadow()
+{
+    appendItem(ClearShadow::create());
+}
+
+void Recorder::setLineCap(LineCap lineCap)
+{
+    appendItem(SetLineCap::create(lineCap));
+}
+
+void Recorder::setLineDash(const DashArray&amp; dashArray, float dashOffset)
+{
+    appendItem(SetLineDash::create(dashArray, dashOffset));
+}
+
+void Recorder::setLineJoin(LineJoin lineJoin)
+{
+    appendItem(SetLineJoin::create(lineJoin));
+}
+
+void Recorder::setMiterLimit(float miterLimit)
+{
+    appendItem(SetMiterLimit::create(miterLimit));
+}
+
+void Recorder::drawGlyphs(const Font&amp; font, const GlyphBuffer&amp; glyphBuffer, int from, int numGlyphs, const FloatPoint&amp; startPoint, FontSmoothingMode smoothingMode)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawGlyphs::create(font, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs, FloatPoint(), toFloatSize(startPoint), smoothingMode)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawImage(Image&amp; image, const FloatRect&amp; destination, const FloatRect&amp; source, const ImagePaintingOptions&amp; imagePaintingOptions)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawImage::create(image, destination, source, imagePaintingOptions)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawTiledImage(Image&amp; image, const FloatRect&amp; destination, const FloatPoint&amp; source, const FloatSize&amp; tileSize, const FloatSize&amp; spacing, const ImagePaintingOptions&amp; imagePaintingOptions)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawTiledImage::create(image, destination, source, tileSize, spacing, imagePaintingOptions)));
+    updateItemExtent(newItem);
+}
+
+#if USE(CG) || USE(CAIRO)
+void Recorder::drawNativeImage(PassNativeImagePtr imagePtr, const FloatSize&amp; imageSize, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawNativeImage::create(imagePtr, imageSize, destRect, srcRect, op, blendMode, orientation)));
+    updateItemExtent(newItem);
+}
+#endif
+
+void Recorder::drawTiledImage(Image&amp; image, const FloatRect&amp; destination, const FloatRect&amp; source, const FloatSize&amp; tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&amp; imagePaintingOptions)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawTiledScaledImage::create(image, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawPattern(Image&amp; image, const FloatRect&amp; tileRect, const AffineTransform&amp; patternTransform, const FloatPoint&amp; phase, const FloatSize&amp; spacing, CompositeOperator op, const FloatRect&amp; destRect, BlendMode blendMode)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawPattern::create(image, tileRect, patternTransform, phase, spacing, op, destRect, blendMode)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::save()
+{
+    appendItem(Save::create());
+    m_stateStack.append(m_stateStack.last().cloneForSave(m_displayList.size() - 1));
+}
+
+void Recorder::restore()
+{
+    if (!m_stateStack.size())
+        return;
+    
+    bool stateUsedForDrawing = currentState().wasUsedForDrawing;
+    size_t saveIndex = currentState().saveItemIndex;
+    
+    m_stateStack.removeLast();
+    // Have to avoid eliding nested Save/Restore when a descendant state contains drawing items.
+    currentState().wasUsedForDrawing |= stateUsedForDrawing;
+
+    if (!stateUsedForDrawing &amp;&amp; saveIndex) {
+        // This Save/Restore didn't contain any drawing items. Roll back to just before the last save.
+        m_displayList.removeItemsFromIndex(saveIndex);
+        return;
+    }
+
+    appendItem(Restore::create());
+    
+    if (saveIndex) {
+        Save&amp; saveItem = downcast&lt;Save&gt;(m_displayList.itemAt(saveIndex));
+        saveItem.setRestoreIndex(m_displayList.size() - 1);
+    }
+}
+
+void Recorder::translate(float x, float y)
+{
+    currentState().translate(x, y);
+    appendItem(Translate::create(x, y));
+}
+
+void Recorder::rotate(float angleInRadians)
+{
+    currentState().rotate(angleInRadians);
+    appendItem(Rotate::create(angleInRadians));
+}
+
+void Recorder::scale(const FloatSize&amp; size)
+{
+    currentState().scale(size);
+    appendItem(Scale::create(size));
+}
+
+void Recorder::concatCTM(const AffineTransform&amp; transform)
+{
+    currentState().concatCTM(transform);
+    appendItem(ConcatenateCTM::create(transform));
+}
+
+void Recorder::beginTransparencyLayer(float opacity)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(BeginTransparencyLayer::create(opacity)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::endTransparencyLayer()
+{
+    appendItem(EndTransparencyLayer::create());
+}
+
+void Recorder::drawRect(const FloatRect&amp; rect, float borderThickness)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawRect::create(rect, borderThickness)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawLine(const FloatPoint&amp; point1, const FloatPoint&amp; point2)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawLine::create(point1, point2)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawLinesForText(const FloatPoint&amp; point, const DashArray&amp; widths, bool printing, bool doubleLines, float strokeThickness)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawLinesForText::create(FloatPoint(), toFloatSize(point), widths, printing, doubleLines, strokeThickness)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawLineForDocumentMarker(const FloatPoint&amp; point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawLineForDocumentMarker::create(point, width, style)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawEllipse(const FloatRect&amp; rect)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawEllipse::create(rect)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawConvexPolygon(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawConvexPolygon::create(numberOfPoints, points, antialiased)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawPath(const Path&amp; path)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawPath::create(path)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawFocusRing(const Path&amp; path, int width, int offset, const Color&amp; color)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawFocusRingPath::create(path, width, offset, color)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::drawFocusRing(const Vector&lt;IntRect&gt;&amp; rects, int width, int offset, const Color&amp; color)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(DrawFocusRingRects::create(rects, width, offset, color)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect&amp; rect)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillRect::create(rect)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect&amp; rect, const Color&amp; color)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillRectWithColor::create(rect, color)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect&amp; rect, Gradient&amp; gradient)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillRectWithGradient::create(rect, gradient)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect&amp; rect, const Color&amp; color, CompositeOperator op, BlendMode blendMode)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillCompositedRect::create(rect, color, op, blendMode)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillRoundedRect(const FloatRoundedRect&amp; rect, const Color&amp; color, BlendMode blendMode)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillRoundedRect::create(rect, color, blendMode)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillRectWithRoundedHole(const FloatRect&amp; rect, const FloatRoundedRect&amp; roundedHoleRect, const Color&amp; color)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillRectWithRoundedHole::create(rect, roundedHoleRect, color)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillPath(const Path&amp; path)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillPath::create(path)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::fillEllipse(const FloatRect&amp; rect)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(FillEllipse::create(rect)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::strokeRect(const FloatRect&amp; rect, float lineWidth)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(StrokeRect::create(rect, lineWidth)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::strokePath(const Path&amp; path)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(StrokePath::create(path)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::strokeEllipse(const FloatRect&amp; rect)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(StrokeEllipse::create(rect)));
+    updateItemExtent(newItem);
+}
+
+void Recorder::clearRect(const FloatRect&amp; rect)
+{
+    DrawingItem&amp; newItem = downcast&lt;DrawingItem&gt;(appendItem(ClearRect::create(rect)));
+    updateItemExtent(newItem);
+}
+
+#if USE(CG)
+void Recorder::applyStrokePattern()
+{
+    appendItem(ApplyStrokePattern::create());
+}
+
+void Recorder::applyFillPattern()
+{
+    appendItem(ApplyFillPattern::create());
+}
+#endif
+
+void Recorder::clip(const FloatRect&amp; rect)
+{
+    currentState().clipBounds.intersect(rect);
+    appendItem(Clip::create(rect));
+}
+
+void Recorder::clipOut(const FloatRect&amp; rect)
+{
+    appendItem(ClipOut::create(rect));
+}
+
+void Recorder::clipOut(const Path&amp; path)
+{
+    appendItem(ClipOutToPath::create(path));
+}
+
+void Recorder::clipPath(const Path&amp; path, WindRule windRule)
+{
+    currentState().clipBounds.intersect(path.fastBoundingRect());
+    appendItem(ClipPath::create(path, windRule));
+}
+
+void Recorder::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialias)
+{
+    Path polygonPath;
+    addConvexPolygonToPath(polygonPath, numPoints, points);
+    currentState().clipBounds.intersect(polygonPath.fastBoundingRect());
+
+    appendItem(ClipConvexPolygon::create(numPoints, points, antialias));
+}
+
+void Recorder::applyDeviceScaleFactor(float deviceScaleFactor)
+{
+    // FIXME: this changes the baseCTM, which will invalidate all of our cached extents.
+    // Assert that it's only called early on?
+    appendItem(ApplyDeviceScaleFactor::create(deviceScaleFactor));
+}
+
+Item&amp; Recorder::appendItem(Ref&lt;Item&gt;&amp;&amp; item)
+{
+    willAppendItem(item.get());
+    return m_displayList.append(WTFMove(item));
+}
+
+void Recorder::updateItemExtent(DrawingItem&amp; item) const
+{
+    if (Optional&lt;FloatRect&gt; rect = item.localBounds(m_graphicsContext))
+        item.setExtent(extentFromLocalBounds(rect.value()));
+}
+
+// FIXME: share with ShadowData
+static inline float shadowPaintingExtent(float blurRadius)
+{
+    // Blurring uses a Gaussian function whose std. deviation is m_radius/2, and which in theory
+    // extends to infinity. In 8-bit contexts, however, rounding causes the effect to become
+    // undetectable at around 1.4x the radius.
+    const float radiusExtentMultiplier = 1.4;
+    return ceilf(blurRadius * radiusExtentMultiplier);
+}
+
+FloatRect Recorder::extentFromLocalBounds(const FloatRect&amp; rect) const
+{
+    FloatRect bounds = rect;
+    const ContextState&amp; state = currentState();
+
+    FloatSize shadowOffset;
+    float shadowRadius;
+    Color shadowColor;
+    if (m_graphicsContext.getShadow(shadowOffset, shadowRadius, shadowColor)) {
+        FloatRect shadowExtent= bounds;
+        shadowExtent.move(shadowOffset);
+        shadowExtent.inflate(shadowPaintingExtent(shadowRadius));
+        bounds.unite(shadowExtent);
+    }
+    
+    FloatRect clippedExtent = intersection(state.clipBounds, bounds);
+    return state.ctm.mapRect(clippedExtent);
+}
+
+const Recorder::ContextState&amp; Recorder::currentState() const
+{
+    ASSERT(m_stateStack.size());
+    return m_stateStack.last();
+}
+
+Recorder::ContextState&amp; Recorder::currentState()
+{
+    ASSERT(m_stateStack.size());
+    return m_stateStack.last();
+}
+
+const AffineTransform&amp; Recorder::ctm() const
+{
+    return currentState().ctm;
+}
+
+const FloatRect&amp; Recorder::clipBounds() const
+{
+    return currentState().clipBounds;
+}
+
+void Recorder::ContextState::translate(float x, float y)
+{
+    ctm.translate(x, y);
+    clipBounds.move(-x, -y);
+}
+
+void Recorder::ContextState::rotate(float angleInRadians)
+{
+    double angleInDegrees = rad2deg(static_cast&lt;double&gt;(angleInRadians));
+    ctm.rotate(angleInDegrees);
+    
+    AffineTransform rotation;
+    rotation.rotate(angleInDegrees);
+
+    if (Optional&lt;AffineTransform&gt; inverse = rotation.inverse())
+        clipBounds = inverse.value().mapRect(clipBounds);
+}
+
+void Recorder::ContextState::scale(const FloatSize&amp; size)
+{
+    ctm.scale(size);
+    clipBounds.scale(1 / size.width(), 1 / size.height());
+}
+
+void Recorder::ContextState::concatCTM(const AffineTransform&amp; matrix)
+{
+    ctm *= matrix;
+
+    if (Optional&lt;AffineTransform&gt; inverse = matrix.inverse())
+        clipBounds = inverse.value().mapRect(clipBounds);
+}
+
+} // namespace DisplayList
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListRecorderh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,176 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DisplayListRecorder_h
+#define DisplayListRecorder_h
+
+#include &quot;DisplayList.h&quot;
+#include &quot;GraphicsContext.h&quot; // For InterpolationQuality.
+#include &quot;Image.h&quot; // For Image::TileRule.
+#include &quot;TextFlags.h&quot;
+#include &lt;wtf/Noncopyable.h&gt;
+
+namespace WebCore {
+
+class FloatPoint;
+class FloatRect;
+class GlyphBuffer;
+class FloatPoint;
+class Font;
+class Image;
+
+struct GraphicsContextState;
+struct ImagePaintingOptions;
+
+namespace DisplayList {
+
+class DrawingItem;
+
+class Recorder {
+    WTF_MAKE_NONCOPYABLE(Recorder);
+public:
+    Recorder(GraphicsContext&amp;, DisplayList&amp;, const FloatRect&amp; initialClip, const AffineTransform&amp;);
+    ~Recorder();
+
+    void updateState(const GraphicsContextState&amp;, GraphicsContextState::StateChangeFlags);
+    void clearShadow();
+
+    void setLineCap(LineCap);
+    void setLineDash(const DashArray&amp;, float dashOffset);
+    void setLineJoin(LineJoin);
+    void setMiterLimit(float);
+
+    void fillRect(const FloatRect&amp;);
+    void fillRect(const FloatRect&amp;, const Color&amp;);
+    void fillRect(const FloatRect&amp;, Gradient&amp;);
+    void fillRect(const FloatRect&amp;, const Color&amp;, CompositeOperator, BlendMode);
+    void fillRoundedRect(const FloatRoundedRect&amp;, const Color&amp;, BlendMode);
+    void fillRectWithRoundedHole(const FloatRect&amp;, const FloatRoundedRect&amp; roundedHoleRect, const Color&amp;);
+    void fillPath(const Path&amp;);
+    void fillEllipse(const FloatRect&amp;);
+    void strokeRect(const FloatRect&amp;, float lineWidth);
+    void strokePath(const Path&amp;);
+    void strokeEllipse(const FloatRect&amp;);
+    void clearRect(const FloatRect&amp;);
+
+#if USE(CG)
+    void applyStrokePattern();
+    void applyFillPattern();
+#endif
+
+    void drawGlyphs(const Font&amp;, const GlyphBuffer&amp;, int from, int numGlyphs, const FloatPoint&amp; anchorPoint, FontSmoothingMode);
+
+    void drawImage(Image&amp;, const FloatRect&amp; destination, const FloatRect&amp; source, const ImagePaintingOptions&amp;);
+    void drawTiledImage(Image&amp;, const FloatRect&amp; destination, const FloatPoint&amp; source, const FloatSize&amp; tileSize, const FloatSize&amp; spacing, const ImagePaintingOptions&amp;);
+    void drawTiledImage(Image&amp;, const FloatRect&amp; destination, const FloatRect&amp; source, const FloatSize&amp; tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&amp;);
+#if USE(CG) || USE(CAIRO)
+    void drawNativeImage(PassNativeImagePtr, const FloatSize&amp; selfSize, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, CompositeOperator, BlendMode, ImageOrientation);
+#endif
+    void drawPattern(Image&amp;, const FloatRect&amp; srcRect, const AffineTransform&amp;, const FloatPoint&amp; phase, const FloatSize&amp; spacing, CompositeOperator, const FloatRect&amp; destRect, BlendMode = BlendModeNormal);
+
+    void drawRect(const FloatRect&amp;, float borderThickness);
+    void drawLine(const FloatPoint&amp;, const FloatPoint&amp;);
+    void drawLinesForText(const FloatPoint&amp;, const DashArray&amp; widths, bool printing, bool doubleLines, float strokeThickness);
+    void drawLineForDocumentMarker(const FloatPoint&amp;, float width, GraphicsContext::DocumentMarkerLineStyle);
+    void drawEllipse(const FloatRect&amp;);
+    void drawConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased);
+    void drawPath(const Path&amp;);
+
+    void drawFocusRing(const Path&amp;, int width, int offset, const Color&amp;);
+    void drawFocusRing(const Vector&lt;IntRect&gt;&amp;, int width, int offset, const Color&amp;);
+
+    void save();
+    void restore();
+
+    void translate(float x, float y);
+    void rotate(float angleInRadians);
+    void scale(const FloatSize&amp;);
+    void concatCTM(const AffineTransform&amp;);
+
+    void beginTransparencyLayer(float opacity);
+    void endTransparencyLayer();
+
+    void clip(const FloatRect&amp;);
+    void clipOut(const FloatRect&amp;);
+    void clipOut(const Path&amp;);
+    void clipPath(const Path&amp;, WindRule);
+    void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
+    
+    void applyDeviceScaleFactor(float);
+
+    size_t size() const { return m_displayList.size(); }
+
+private:
+    Item&amp; appendItem(Ref&lt;Item&gt;&amp;&amp;);
+    void willAppendItem(const Item&amp;);
+
+    FloatRect extentFromLocalBounds(const FloatRect&amp;) const;
+    void updateItemExtent(DrawingItem&amp;) const;
+    
+    const AffineTransform&amp; ctm() const;
+    const FloatRect&amp; clipBounds() const;
+
+    struct ContextState {
+        AffineTransform ctm;
+        FloatRect clipBounds;
+        GraphicsContextStateChange stateChange;
+        GraphicsContextState lastDrawingState;
+        bool wasUsedForDrawing { false };
+        size_t saveItemIndex { 0 };
+        
+        ContextState(const AffineTransform&amp; transform, const FloatRect&amp; clip)
+            : ctm(transform)
+            , clipBounds(clip)
+        {
+        }
+        
+        ContextState cloneForSave(size_t saveIndex) const
+        {
+            ContextState state(ctm, clipBounds);
+            state.stateChange = stateChange;
+            state.lastDrawingState = lastDrawingState;
+            state.saveItemIndex = saveIndex;
+            return state;
+        }
+
+        void translate(float x, float y);
+        void rotate(float angleInRadians);
+        void scale(const FloatSize&amp;);
+        void concatCTM(const AffineTransform&amp;);
+    };
+    
+    const ContextState&amp; currentState() const;
+    ContextState&amp; currentState();
+
+    GraphicsContext&amp; m_graphicsContext;
+    DisplayList&amp; m_displayList;
+
+    Vector&lt;ContextState, 32&gt; m_stateStack;
+};
+
+}
+}
+
+#endif // DisplayListRecorder_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListReplayercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;DisplayListReplayer.h&quot;
+
+#include &quot;DisplayList.h&quot;
+#include &quot;DisplayListItems.h&quot;
+#include &quot;GraphicsContext.h&quot;
+#include &quot;Logging.h&quot;
+#include &quot;TextStream.h&quot;
+
+namespace WebCore {
+namespace DisplayList {
+
+Replayer::Replayer(GraphicsContext&amp; context, const DisplayList&amp; displayList)
+    : m_displayList(displayList)
+    , m_context(context)
+{
+}
+
+Replayer::~Replayer()
+{
+}
+
+void Replayer::replay(const FloatRect&amp; initialClip)
+{
+    LOG_WITH_STREAM(DisplayLists, stream &lt;&lt; &quot;\nReplaying with clip &quot; &lt;&lt; initialClip);
+    UNUSED_PARAM(initialClip);
+
+    size_t numItems = m_displayList.size();
+    for (size_t i = 0; i &lt; numItems; ++i) {
+        auto&amp; item = m_displayList.list()[i].get();
+        LOG_WITH_STREAM(DisplayLists, stream &lt;&lt; &quot;drawing  &quot; &lt;&lt; i &lt;&lt; &quot; &quot; &lt;&lt; item);
+        item.apply(m_context);
+    }
+}
+
+} // namespace DisplayList
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsdisplaylistsDisplayListReplayerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h (0 => 194708)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h        2016-01-07 19:53:31 UTC (rev 194708)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DisplayListReplayer_h
+#define DisplayListReplayer_h
+
+#include &lt;wtf/Noncopyable.h&gt;
+
+namespace WebCore {
+
+class FloatRect;
+class GraphicsContext;
+
+namespace DisplayList {
+
+class DisplayList;
+
+class Replayer {
+    WTF_MAKE_NONCOPYABLE(Replayer);
+public:
+    Replayer(GraphicsContext&amp;, const DisplayList&amp;);
+    ~Replayer();
+
+    void replay(const FloatRect&amp; initialClip);
+
+private:
+    const DisplayList&amp; m_displayList;
+    GraphicsContext&amp; m_context;
+};
+
+}
+}
+
+#endif // DisplayListReplayer_h
</ins></span></pre>
</div>
</div>

</body>
</html>