<!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 "DisplayLists" 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<<):
* 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"> "${WEBCORE_DIR}/platform/graphics"
</span><span class="cx"> "${WEBCORE_DIR}/platform/graphics/cpu/arm"
</span><span class="cx"> "${WEBCORE_DIR}/platform/graphics/cpu/arm/filters"
</span><ins>+ "${WEBCORE_DIR}/platform/graphics/displaylists"
</ins><span class="cx"> "${WEBCORE_DIR}/platform/graphics/filters"
</span><span class="cx"> "${WEBCORE_DIR}/platform/graphics/filters/texmap"
</span><span class="cx"> "${WEBCORE_DIR}/platform/graphics/harfbuzz"
</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 <simon.fraser@apple.com>
+
+ 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 "DisplayLists" 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<<):
+ * 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 <cdumez@apple.com>
</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 = "<group>"; };
</span><span class="cx">                 0FE5806119327A6200DE32EB /* ScrollingTreeMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeMac.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0FE5806219327A6200DE32EB /* ScrollingTreeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeMac.h; sourceTree = "<group>"; };
</span><ins>+                0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayList.cpp; path = displaylists/DisplayList.cpp; sourceTree = "<group>"; };
+                0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayList.h; path = displaylists/DisplayList.h; sourceTree = "<group>"; };
+                0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListItems.cpp; path = displaylists/DisplayListItems.cpp; sourceTree = "<group>"; };
+                0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListItems.h; path = displaylists/DisplayListItems.h; sourceTree = "<group>"; };
+                0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListRecorder.cpp; path = displaylists/DisplayListRecorder.cpp; sourceTree = "<group>"; };
+                0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListRecorder.h; path = displaylists/DisplayListRecorder.h; sourceTree = "<group>"; };
+                0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListReplayer.cpp; path = displaylists/DisplayListReplayer.cpp; sourceTree = "<group>"; };
+                0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListReplayer.h; path = displaylists/DisplayListReplayer.h; sourceTree = "<group>"; };
</ins><span class="cx">                 0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarThemeMock.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeMock.h; sourceTree = "<group>"; };
</span><span class="cx">                 0FE71415142189FC00DB33BA /* ScrollbarTheme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarTheme.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -15654,6 +15670,21 @@
</span><span class="cx">                         path = ios;
</span><span class="cx">                         sourceTree = "<group>";
</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 = "<group>";
+                };
</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 "IntRect.h"
</span><span class="cx"> #include "RoundedRect.h"
</span><span class="cx"> #include "TextRun.h"
</span><ins>+#include "TextStream.h"
</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 & GraphicsContextState::flag) && (m_state.property != state.property)) \
+ changeFlags |= GraphicsContextState::flag;
+
+GraphicsContextState::StateChangeFlags GraphicsContextStateChange::changesFromState(const GraphicsContextState& 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 & GraphicsContextState::ShadowChange)
+ && (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 & (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange))
+ && (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& state, GraphicsContextState::StateChangeFlags flags)
+{
+ // FIXME: This code should move to GraphicsContextState.
+ if (flags & GraphicsContextState::StrokeGradientChange)
+ m_state.strokeGradient = state.strokeGradient;
+
+ if (flags & GraphicsContextState::StrokePatternChange)
+ m_state.strokePattern = state.strokePattern;
+
+ if (flags & GraphicsContextState::FillGradientChange)
+ m_state.fillGradient = state.fillGradient;
+
+ if (flags & GraphicsContextState::FillPatternChange)
+ m_state.fillPattern = state.fillPattern;
+
+ if (flags & GraphicsContextState::ShadowChange) {
+ // FIXME: Deal with state.shadowsUseLegacyRadius.
+ m_state.shadowOffset = state.shadowOffset;
+ m_state.shadowBlur = state.shadowBlur;
+ m_state.shadowColor = state.shadowColor;
+ }
+
+ if (flags & GraphicsContextState::StrokeThicknessChange)
+ m_state.strokeThickness = state.strokeThickness;
+
+ if (flags & GraphicsContextState::TextDrawingModeChange)
+ m_state.textDrawingMode = state.textDrawingMode;
+
+ if (flags & GraphicsContextState::StrokeColorChange)
+ m_state.strokeColor = state.strokeColor;
+
+ if (flags & GraphicsContextState::FillColorChange)
+ m_state.fillColor = state.fillColor;
+
+ if (flags & GraphicsContextState::StrokeStyleChange)
+ m_state.strokeStyle = state.strokeStyle;
+
+ if (flags & GraphicsContextState::FillRuleChange)
+ m_state.fillRule = state.fillRule;
+
+ if (flags & GraphicsContextState::AlphaChange)
+ m_state.alpha = state.alpha;
+
+ if (flags & (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange)) {
+ m_state.compositeOperator = state.compositeOperator;
+ m_state.blendMode = state.blendMode;
+ }
+
+ if (flags & GraphicsContextState::ShouldAntialiasChange)
+ m_state.shouldAntialias = state.shouldAntialias;
+
+ if (flags & GraphicsContextState::ShouldSmoothFontsChange)
+ m_state.shouldSmoothFonts = state.shouldSmoothFonts;
+
+ if (flags & GraphicsContextState::AntialiasedFontDilationEnabledChange)
+ m_state.antialiasedFontDilationEnabled = state.antialiasedFontDilationEnabled;
+
+ if (flags & GraphicsContextState::ShouldSubpixelQuantizeFontsChange)
+ m_state.shouldSubpixelQuantizeFonts = state.shouldSubpixelQuantizeFonts;
+
+ if (flags & GraphicsContextState::ShadowsIgnoreTransformsChange)
+ m_state.shadowsIgnoreTransforms = state.shadowsIgnoreTransforms;
+
+ if (flags & GraphicsContextState::DrawLuminanceMaskChange)
+ m_state.drawLuminanceMask = state.drawLuminanceMask;
+
+ if (flags & GraphicsContextState::ImageInterpolationQualityChange)
+ m_state.imageInterpolationQuality = state.imageInterpolationQuality;
+
+ m_changeFlags |= flags;
+}
+
+void GraphicsContextStateChange::apply(GraphicsContext& context) const
+{
+ if (m_changeFlags & GraphicsContextState::StrokeGradientChange)
+ context.setStrokeGradient(*m_state.strokeGradient);
+
+ if (m_changeFlags & GraphicsContextState::StrokePatternChange)
+ context.setStrokePattern(*m_state.strokePattern);
+
+ if (m_changeFlags & GraphicsContextState::FillGradientChange)
+ context.setFillGradient(*m_state.fillGradient);
+
+ if (m_changeFlags & GraphicsContextState::FillPatternChange)
+ context.setFillPattern(*m_state.fillPattern);
+
+ if (m_changeFlags & 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 & GraphicsContextState::StrokeThicknessChange)
+ context.setStrokeThickness(m_state.strokeThickness);
+
+ if (m_changeFlags & GraphicsContextState::TextDrawingModeChange)
+ context.setTextDrawingMode(m_state.textDrawingMode);
+
+ if (m_changeFlags & GraphicsContextState::StrokeColorChange)
+ context.setStrokeColor(m_state.strokeColor);
+
+ if (m_changeFlags & GraphicsContextState::FillColorChange)
+ context.setFillColor(m_state.fillColor);
+
+ if (m_changeFlags & GraphicsContextState::StrokeStyleChange)
+ context.setStrokeStyle(m_state.strokeStyle);
+
+ if (m_changeFlags & GraphicsContextState::FillRuleChange)
+ context.setFillRule(m_state.fillRule);
+
+ if (m_changeFlags & GraphicsContextState::AlphaChange)
+ context.setAlpha(m_state.alpha);
+
+ if (m_changeFlags & (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange))
+ context.setCompositeOperation(m_state.compositeOperator, m_state.blendMode);
+
+ if (m_changeFlags & GraphicsContextState::ShouldAntialiasChange)
+ context.setShouldAntialias(m_state.shouldAntialias);
+
+ if (m_changeFlags & GraphicsContextState::ShouldSmoothFontsChange)
+ context.setShouldSmoothFonts(m_state.shouldSmoothFonts);
+
+ if (m_changeFlags & GraphicsContextState::AntialiasedFontDilationEnabledChange)
+ context.setAntialiasedFontDilationEnabled(m_state.antialiasedFontDilationEnabled);
+
+ if (m_changeFlags & GraphicsContextState::ShouldSubpixelQuantizeFontsChange)
+ context.setShouldSubpixelQuantizeFonts(m_state.shouldSubpixelQuantizeFonts);
+
+ if (m_changeFlags & GraphicsContextState::ShadowsIgnoreTransformsChange)
+ context.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms);
+
+ if (m_changeFlags & GraphicsContextState::DrawLuminanceMaskChange)
+ context.setDrawLuminanceMask(m_state.drawLuminanceMask);
+
+ if (m_changeFlags & GraphicsContextState::ImageInterpolationQualityChange)
+ context.setImageInterpolationQuality(m_state.imageInterpolationQuality);
+}
+
+void GraphicsContextStateChange::dump(TextStream& ts) const
+{
+ ts.dumpProperty("change-flags", m_changeFlags);
+
+ if (m_changeFlags & GraphicsContextState::StrokeGradientChange)
+ ts.dumpProperty("stroke-gradient", m_state.strokeGradient.get());
+
+ if (m_changeFlags & GraphicsContextState::StrokePatternChange)
+ ts.dumpProperty("stroke-pattern", m_state.strokePattern.get());
+
+ if (m_changeFlags & GraphicsContextState::FillGradientChange)
+ ts.dumpProperty("fill-gradient", m_state.fillGradient.get());
+
+ if (m_changeFlags & GraphicsContextState::FillPatternChange)
+ ts.dumpProperty("fill-pattern", m_state.fillPattern.get());
+
+ if (m_changeFlags & GraphicsContextState::ShadowChange) {
+ ts.dumpProperty("shadow-blur", m_state.shadowBlur);
+ ts.dumpProperty("shadow-offset", m_state.shadowOffset);
+#if USE(CG)
+ ts.dumpProperty("shadows-use-legacy-radius", m_state.shadowsUseLegacyRadius);
+#endif
+ }
+
+ if (m_changeFlags & GraphicsContextState::StrokeThicknessChange)
+ ts.dumpProperty("stroke-thickness", m_state.strokeThickness);
+
+ if (m_changeFlags & GraphicsContextState::TextDrawingModeChange)
+ ts.dumpProperty("text-drawing-mode", m_state.textDrawingMode);
+
+ if (m_changeFlags & GraphicsContextState::StrokeColorChange)
+ ts.dumpProperty("stroke-color", m_state.strokeColor);
+
+ if (m_changeFlags & GraphicsContextState::FillColorChange)
+ ts.dumpProperty("fill-color", m_state.fillColor);
+
+ if (m_changeFlags & GraphicsContextState::StrokeStyleChange)
+ ts.dumpProperty("stroke-style", m_state.strokeStyle);
+
+ if (m_changeFlags & GraphicsContextState::FillRuleChange)
+ ts.dumpProperty("fill-rule", m_state.fillRule);
+
+ if (m_changeFlags & GraphicsContextState::AlphaChange)
+ ts.dumpProperty("alpha", m_state.alpha);
+
+ if (m_changeFlags & GraphicsContextState::CompositeOperationChange)
+ ts.dumpProperty("composite-operator", m_state.compositeOperator);
+
+ if (m_changeFlags & GraphicsContextState::BlendModeChange)
+ ts.dumpProperty("blend-mode", m_state.blendMode);
+
+ if (m_changeFlags & GraphicsContextState::ShouldAntialiasChange)
+ ts.dumpProperty("should-antialias", m_state.shouldAntialias);
+
+ if (m_changeFlags & GraphicsContextState::ShouldSmoothFontsChange)
+ ts.dumpProperty("should-smooth-fonts", m_state.shouldSmoothFonts);
+
+ if (m_changeFlags & GraphicsContextState::AntialiasedFontDilationEnabledChange)
+ ts.dumpProperty("antialiased-font-dilation-enabled", m_state.antialiasedFontDilationEnabled);
+
+ if (m_changeFlags & GraphicsContextState::ShouldSubpixelQuantizeFontsChange)
+ ts.dumpProperty("should-subpixel-quantize-fonts", m_state.shouldSubpixelQuantizeFonts);
+
+ if (m_changeFlags & GraphicsContextState::ShadowsIgnoreTransformsChange)
+ ts.dumpProperty("shadows-ignore-transforms", m_state.shadowsIgnoreTransforms);
+
+ if (m_changeFlags & GraphicsContextState::DrawLuminanceMaskChange)
+ ts.dumpProperty("draw-luminance-mask", m_state.drawLuminanceMask);
+}
+
+TextStream& operator<<(TextStream& ts, const GraphicsContextStateChange& 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 << 1,
+ StrokePatternChange = 1 << 2,
+ FillGradientChange = 1 << 3,
+ FillPatternChange = 1 << 4,
+ StrokeThicknessChange = 1 << 5,
+ StrokeColorChange = 1 << 6,
+ StrokeStyleChange = 1 << 7,
+ FillColorChange = 1 << 8,
+ FillRuleChange = 1 << 9,
+ ShadowChange = 1 << 10,
+ ShadowColorChange = 1 << 11,
+ ShadowsIgnoreTransformsChange = 1 << 12,
+ AlphaChange = 1 << 13,
+ CompositeOperationChange = 1 << 14,
+ BlendModeChange = 1 << 15,
+ TextDrawingModeChange = 1 << 16,
+ ShouldAntialiasChange = 1 << 17,
+ ShouldSmoothFontsChange = 1 << 18,
+ AntialiasedFontDilationEnabledChange = 1 << 19,
+ ShouldSubpixelQuantizeFontsChange = 1 << 20,
+ DrawLuminanceMaskChange = 1 << 21,
+ ImageInterpolationQualityChange = 1 << 22,
+ };
+ typedef uint32_t StateChangeFlags;
+
</ins><span class="cx"> RefPtr<Gradient> strokeGradient;
</span><span class="cx"> RefPtr<Pattern> 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& state, GraphicsContextState::StateChangeFlags flags)
+ : m_state(state)
+ , m_changeFlags(flags)
+ {
+ }
+
+ GraphicsContextState::StateChangeFlags changesFromState(const GraphicsContextState&) const;
+
+ void accumulate(const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
+ void apply(GraphicsContext&) const;
+
+ void dump(TextStream&) const;
+
+ GraphicsContextState m_state;
+ GraphicsContextState::StateChangeFlags m_changeFlags { GraphicsContextState::NoChange };
+};
+
+TextStream& operator<<(TextStream&, const GraphicsContextStateChange&);
+
+
</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 "config.h"
+#include "DisplayList.h"
+
+#include "DisplayListItems.h"
+#include "Logging.h"
+#include "TextStream.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+namespace DisplayList {
+
+#if !defined(NDEBUG) || !LOG_DISABLED
+WTF::CString DisplayList::description() const
+{
+ TextStream ts;
+ ts << *this;
+ return ts.release().utf8();
+}
+
+void DisplayList::dump() const
+{
+ fprintf(stderr, "%s", description().data());
+}
+#endif
+
+void DisplayList::dump(TextStream& ts) const
+{
+ TextStream::GroupScope group(ts);
+ ts << "display list";
+
+ size_t numItems = m_list.size();
+ for (size_t i = 0; i < numItems; ++i) {
+ TextStream::GroupScope scope(ts);
+ ts << i << " " << m_list[i].get();
+ }
+ ts.startGroup();
+ ts << "size in bytes: " << sizeInBytes();
+ ts.endGroup();
+}
+
+size_t DisplayList::sizeInBytes() const
+{
+ size_t result = 0;
+ for (auto& ref : m_list)
+ result += Item::sizeInBytes(ref);
+
+ return result;
+}
+
+} // namespace DisplayList
+
+TextStream& operator<<(TextStream& ts, const DisplayList::DisplayList& 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 <wtf/FastMalloc.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/text/WTFString.h>
+
+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&&) = default;
+
+ DisplayList& operator=(DisplayList&&) = default;
+
+ void dump(TextStream&) const;
+
+ const Vector<Ref<Item>>& list() const { return m_list; }
+ Item& itemAt(size_t index)
+ {
+ ASSERT(index < 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& append(Ref<Item>&& item)
+ {
+ m_list.append(WTFMove(item));
+ return m_list.last().get();
+ }
+
+ Vector<Ref<Item>>& list() { return m_list; }
+
+ Vector<Ref<Item>> m_list;
+};
+
+} // DisplayList
+
+TextStream& operator<<(TextStream&, const DisplayList::DisplayList&);
+
+} // 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 "config.h"
+#include "DisplayListItems.h"
+
+#include "FontCascade.h"
+#include "TextStream.h"
+
+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 << *this;
+ return ts.release().utf8();
+}
+#endif
+
+size_t Item::sizeInBytes(const Item& item)
+{
+ switch (item.type()) {
+ case ItemType::Save:
+ return sizeof(downcast<Save>(item));
+ case ItemType::Restore:
+ return sizeof(downcast<Restore>(item));
+ case ItemType::Translate:
+ return sizeof(downcast<Translate>(item));
+ case ItemType::Rotate:
+ return sizeof(downcast<Rotate>(item));
+ case ItemType::Scale:
+ return sizeof(downcast<Scale>(item));
+ case ItemType::ConcatenateCTM:
+ return sizeof(downcast<ConcatenateCTM>(item));
+ case ItemType::SetState:
+ return sizeof(downcast<SetState>(item));
+ case ItemType::SetLineCap:
+ return sizeof(downcast<SetLineCap>(item));
+ case ItemType::SetLineDash:
+ return sizeof(downcast<SetLineDash>(item));
+ case ItemType::SetLineJoin:
+ return sizeof(downcast<SetLineJoin>(item));
+ case ItemType::SetMiterLimit:
+ return sizeof(downcast<SetMiterLimit>(item));
+ case ItemType::ClearShadow:
+ return sizeof(downcast<ClearShadow>(item));
+ case ItemType::Clip:
+ return sizeof(downcast<Clip>(item));
+ case ItemType::ClipOut:
+ return sizeof(downcast<ClipOut>(item));
+ case ItemType::ClipOutToPath:
+ return sizeof(downcast<ClipOutToPath>(item));
+ case ItemType::ClipPath:
+ return sizeof(downcast<ClipPath>(item));
+ case ItemType::ClipConvexPolygon:
+ return sizeof(downcast<ClipConvexPolygon>(item));
+ case ItemType::DrawGlyphs:
+ return sizeof(downcast<DrawGlyphs>(item));
+ case ItemType::DrawImage:
+ return sizeof(downcast<DrawImage>(item));
+ case ItemType::DrawTiledImage:
+ return sizeof(downcast<DrawTiledImage>(item));
+ case ItemType::DrawTiledScaledImage:
+ return sizeof(downcast<DrawTiledScaledImage>(item));
+#if USE(CG) || USE(CAIRO)
+ case ItemType::DrawNativeImage:
+ return sizeof(downcast<DrawNativeImage>(item));
+#endif
+ case ItemType::DrawPattern:
+ return sizeof(downcast<DrawPattern>(item));
+ case ItemType::DrawRect:
+ return sizeof(downcast<DrawRect>(item));
+ case ItemType::DrawLine:
+ return sizeof(downcast<DrawLine>(item));
+ case ItemType::DrawLinesForText:
+ return sizeof(downcast<DrawLinesForText>(item));
+ case ItemType::DrawLineForDocumentMarker:
+ return sizeof(downcast<DrawLineForDocumentMarker>(item));
+ case ItemType::DrawEllipse:
+ return sizeof(downcast<DrawEllipse>(item));
+ case ItemType::DrawConvexPolygon:
+ return sizeof(downcast<DrawConvexPolygon>(item));
+ case ItemType::DrawPath:
+ return sizeof(downcast<DrawPath>(item));
+ case ItemType::DrawFocusRingPath:
+ return sizeof(downcast<DrawFocusRingPath>(item));
+ case ItemType::DrawFocusRingRects:
+ return sizeof(downcast<DrawFocusRingRects>(item));
+ case ItemType::FillRect:
+ return sizeof(downcast<FillRect>(item));
+ case ItemType::FillRectWithColor:
+ return sizeof(downcast<FillRectWithColor>(item));
+ case ItemType::FillRectWithGradient:
+ return sizeof(downcast<FillRectWithGradient>(item));
+ case ItemType::FillCompositedRect:
+ return sizeof(downcast<FillCompositedRect>(item));
+ case ItemType::FillRoundedRect:
+ return sizeof(downcast<FillRoundedRect>(item));
+ case ItemType::FillRectWithRoundedHole:
+ return sizeof(downcast<FillRectWithRoundedHole>(item));
+ case ItemType::FillPath:
+ return sizeof(downcast<FillPath>(item));
+ case ItemType::FillEllipse:
+ return sizeof(downcast<FillEllipse>(item));
+ case ItemType::StrokeRect:
+ return sizeof(downcast<StrokeRect>(item));
+ case ItemType::StrokePath:
+ return sizeof(downcast<StrokePath>(item));
+ case ItemType::StrokeEllipse:
+ return sizeof(downcast<StrokeEllipse>(item));
+ case ItemType::ClearRect:
+ return sizeof(downcast<ClearRect>(item));
+ case ItemType::BeginTransparencyLayer:
+ return sizeof(downcast<BeginTransparencyLayer>(item));
+ case ItemType::EndTransparencyLayer:
+ return sizeof(downcast<EndTransparencyLayer>(item));
+#if USE(CG)
+ case ItemType::ApplyStrokePattern:
+ return sizeof(downcast<ApplyStrokePattern>(item));
+ case ItemType::ApplyFillPattern:
+ return sizeof(downcast<ApplyFillPattern>(item));
+#endif
+ case ItemType::ApplyDeviceScaleFactor:
+ return sizeof(downcast<ApplyDeviceScaleFactor>(item));
+ }
+ return 0;
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawingItem& item)
+{
+ ts.startGroup();
+ ts << "extent ";
+ if (item.extentKnown())
+ ts << item.extent();
+ else
+ ts << "unknown";
+
+ ts.endGroup();
+ return ts;
+}
+
+void Save::apply(GraphicsContext& context) const
+{
+ context.save();
+}
+
+static TextStream& operator<<(TextStream& ts, const Save& item)
+{
+ ts.dumpProperty("restore-index", item.restoreIndex());
+ return ts;
+}
+
+void Restore::apply(GraphicsContext& context) const
+{
+ context.restore();
+}
+
+void Translate::apply(GraphicsContext& context) const
+{
+ context.translate(m_x, m_y);
+}
+
+static TextStream& operator<<(TextStream& ts, const Translate& item)
+{
+ ts.dumpProperty("x", item.x());
+ ts.dumpProperty("y", item.y());
+
+ return ts;
+}
+
+void Rotate::apply(GraphicsContext& context) const
+{
+ context.rotate(m_angle);
+}
+
+static TextStream& operator<<(TextStream& ts, const Rotate& item)
+{
+ ts.dumpProperty("angle", item.angle());
+
+ return ts;
+}
+
+void Scale::apply(GraphicsContext& context) const
+{
+ context.scale(m_size);
+}
+
+static TextStream& operator<<(TextStream& ts, const Scale& item)
+{
+ ts.dumpProperty("size", item.amount());
+
+ return ts;
+}
+
+ConcatenateCTM::ConcatenateCTM(const AffineTransform& transform)
+ : Item(ItemType::ConcatenateCTM)
+ , m_transform(transform)
+{
+}
+
+void ConcatenateCTM::apply(GraphicsContext& context) const
+{
+ context.concatCTM(m_transform);
+}
+
+static TextStream& operator<<(TextStream& ts, const ConcatenateCTM& item)
+{
+ ts.dumpProperty("ctm", item.transform());
+
+ return ts;
+}
+
+void SetState::apply(GraphicsContext& context) const
+{
+ m_state.apply(context);
+}
+
+void SetState::accumulate(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
+{
+ m_state.accumulate(state, flags);
+}
+
+static TextStream& operator<<(TextStream& ts, const SetState& state)
+{
+ ts << state.state();
+ return ts;
+}
+
+void SetLineCap::apply(GraphicsContext& context) const
+{
+ context.setLineCap(m_lineCap);
+}
+
+static TextStream& operator<<(TextStream& ts, const SetLineCap& lineCap)
+{
+ ts.dumpProperty("line-cap", lineCap.lineCap());
+ return ts;
+}
+
+void SetLineDash::apply(GraphicsContext& context) const
+{
+ context.setLineDash(m_dashArray, m_dashOffset);
+}
+
+static TextStream& operator<<(TextStream& ts, const SetLineDash& lineDash)
+{
+ ts.dumpProperty("dash-array", lineDash.dashArray());
+ ts.dumpProperty("dash-offset", lineDash.dashOffset());
+ return ts;
+}
+
+void SetLineJoin::apply(GraphicsContext& context) const
+{
+ context.setLineJoin(m_lineJoin);
+}
+
+static TextStream& operator<<(TextStream& ts, const SetLineJoin& lineJoin)
+{
+ ts.dumpProperty("line-join", lineJoin.lineJoin());
+ return ts;
+}
+
+void SetMiterLimit::apply(GraphicsContext& context) const
+{
+ context.setMiterLimit(m_miterLimit);
+}
+
+static TextStream& operator<<(TextStream& ts, const SetMiterLimit& miterLimit)
+{
+ ts.dumpProperty("mitre-limit", miterLimit.miterLimit());
+ return ts;
+}
+
+void ClearShadow::apply(GraphicsContext& context) const
+{
+ context.clearShadow();
+}
+
+void Clip::apply(GraphicsContext& context) const
+{
+ context.clip(m_rect);
+}
+
+static TextStream& operator<<(TextStream& ts, const Clip& item)
+{
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+void ClipOut::apply(GraphicsContext& context) const
+{
+ context.clipOut(m_rect);
+}
+
+static TextStream& operator<<(TextStream& ts, const ClipOut& item)
+{
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+void ClipOutToPath::apply(GraphicsContext& context) const
+{
+ context.clipOut(m_path);
+}
+
+static TextStream& operator<<(TextStream& ts, const ClipOutToPath&)
+{
+// ts.dumpProperty("path", item.path()); // FIXME: path logging.
+ return ts;
+}
+
+void ClipPath::apply(GraphicsContext& context) const
+{
+ context.clipPath(m_path, m_windRule);
+}
+
+static TextStream& operator<<(TextStream& ts, const ClipPath& item)
+{
+// ts.dumpProperty("path", item.path()); // FIXME: path logging.
+ ts.dumpProperty("wind-rule", 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 < numberOfPoints; ++i)
+ m_points.append(points[i]);
+}
+
+void ClipConvexPolygon::apply(GraphicsContext& context) const
+{
+ context.clipConvexPolygon(m_points.size(), m_points.data(), m_antialias);
+}
+
+static TextStream& operator<<(TextStream& ts, const ClipConvexPolygon& item)
+{
+ ts.dumpProperty("points", item.points());
+ ts.dumpProperty("antialias", item.antialias());
+ return ts;
+}
+
+DrawGlyphs::DrawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode smoothingMode)
+ : DrawingItem(ItemType::DrawGlyphs)
+ , m_font(const_cast<Font&>(font))
+ , m_blockLocation(blockLocation)
+ , m_localAnchor(localAnchor)
+ , m_smoothingMode(smoothingMode)
+{
+ m_glyphs.reserveInitialCapacity(count);
+ m_advances.reserveInitialCapacity(count);
+ for (unsigned i = 0; i < 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 < m_glyphs.size(); ++i) {
+#if USE(CAIRO)
+ result.add(m_glyphs[i].index, &m_font.get(), m_advances[i]);
+#else
+ result.add(m_glyphs[i], &m_font.get(), m_advances[i]);
+#endif
+ }
+ return result;
+}
+
+void DrawGlyphs::apply(GraphicsContext&) 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->fontMetrics().floatAscent();
+ float descent = m_font->fontMetrics().floatDescent();
+ FloatPoint current = toFloatPoint(localAnchor());
+ size_t numGlyphs = m_glyphs.size();
+ for (size_t i = 0; i < 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<FloatRect> DrawGlyphs::localBounds(const GraphicsContext&) const
+{
+ FloatRect localBounds = m_bounds;
+ localBounds.move(m_blockLocation.x(), m_blockLocation.y());
+ return localBounds;
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawGlyphs& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ // FIXME: dump more stuff.
+ ts.dumpProperty("block-location", item.blockLocation());
+ ts.dumpProperty("local-anchor", item.localAnchor());
+ ts.dumpProperty("anchor-point", item.anchorPoint());
+ ts.dumpProperty("length", item.glyphs().size());
+
+ return ts;
+}
+
+DrawImage::DrawImage(Image& image, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& imagePaintingOptions)
+ : DrawingItem(ItemType::DrawImage)
+ , m_image(image)
+ , m_destination(destination)
+ , m_source(source)
+ , m_imagePaintingOptions(imagePaintingOptions)
+{
+}
+
+void DrawImage::apply(GraphicsContext& context) const
+{
+ context.drawImage(m_image.get(), m_destination, m_source, m_imagePaintingOptions);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawImage& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("image", item.image());
+ ts.dumpProperty("source-rect", item.source());
+ ts.dumpProperty("dest-rect", item.destination());
+ return ts;
+}
+
+DrawTiledImage::DrawTiledImage(Image& image, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& 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& context) const
+{
+ context.drawTiledImage(m_image.get(), m_destination, m_source, m_tileSize, m_spacing, m_imagePaintingOptions);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawTiledImage& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("image", item.image());
+ ts.dumpProperty("source-point", item.source());
+ ts.dumpProperty("dest-rect", item.destination());
+ ts.dumpProperty("tile-size", item.tileSize());
+ ts.dumpProperty("spacing", item.spacing());
+ return ts;
+}
+
+DrawTiledScaledImage::DrawTiledScaledImage(Image& image, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions& 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& context) const
+{
+ context.drawTiledImage(m_image.get(), m_destination, m_source, m_tileScaleFactor, m_hRule, m_vRule, m_imagePaintingOptions);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawTiledScaledImage& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("image", item.image());
+ ts.dumpProperty("source-rect", item.source());
+ ts.dumpProperty("dest-rect", item.destination());
+ return ts;
+}
+
+#if USE(CG) || USE(CAIRO)
+DrawNativeImage::DrawNativeImage(PassNativeImagePtr imagePtr, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& 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& 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& operator<<(TextStream& ts, const DrawNativeImage& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ // FIXME: dump more stuff.
+ ts.dumpProperty("source-rect", item.source());
+ ts.dumpProperty("dest-rect", item.destination());
+ return ts;
+}
+#endif
+
+DrawPattern::DrawPattern(Image& image, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& 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& context) const
+{
+ context.drawPattern(m_image.get(), m_tileRect, m_patternTransform, m_phase, m_spacing, m_op, m_destination, m_blendMode);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawPattern& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("image", item.image());
+ ts.dumpProperty("pattern-transform", item.patternTransform());
+ ts.dumpProperty("tile-rect", item.tileRect());
+ ts.dumpProperty("dest-rect", item.destRect());
+ ts.dumpProperty("phase", item.phase());
+ ts.dumpProperty("spacing", item.spacing());
+ return ts;
+}
+
+void DrawRect::apply(GraphicsContext& context) const
+{
+ context.drawRect(m_rect, m_borderThickness);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawRect& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ ts.dumpProperty("border-thickness", item.borderThickness());
+ return ts;
+}
+
+Optional<FloatRect> DrawLine::localBounds(const GraphicsContext&) const
+{
+ FloatRect bounds;
+ bounds.fitToPoints(m_point1, m_point2);
+ return bounds;
+}
+
+void DrawLine::apply(GraphicsContext& context) const
+{
+ context.drawLine(m_point1, m_point2);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawLine& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("point-1", item.point1());
+ ts.dumpProperty("point-2", item.point2());
+ return ts;
+}
+
+void DrawLinesForText::apply(GraphicsContext& context) const
+{
+ context.drawLinesForText(point(), m_widths, m_printing, m_doubleLines);
+}
+
+Optional<FloatRect> DrawLinesForText::localBounds(const GraphicsContext&) 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& operator<<(TextStream& ts, const DrawLinesForText& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("block-location", item.blockLocation());
+ ts.dumpProperty("local-anchor", item.localAnchor());
+ ts.dumpProperty("point", item.point());
+ ts.dumpProperty("double", item.doubleLines());
+ ts.dumpProperty("widths", item.widths());
+ ts.dumpProperty("is-printing", item.isPrinting());
+ ts.dumpProperty("double", item.doubleLines());
+ return ts;
+}
+
+void DrawLineForDocumentMarker::apply(GraphicsContext& context) const
+{
+ context.drawLineForDocumentMarker(m_point, m_width, m_style);
+}
+
+Optional<FloatRect> DrawLineForDocumentMarker::localBounds(const GraphicsContext&) 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 "misspelling dot" snapping.
+ return result;
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawLineForDocumentMarker& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("point", item.point());
+ ts.dumpProperty("width", item.width());
+ return ts;
+}
+
+void DrawEllipse::apply(GraphicsContext& context) const
+{
+ context.drawEllipse(m_rect);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawEllipse& item)
+{
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+// FIXME: Share this code.
+void addConvexPolygonToPath(Path& path, size_t numberOfPoints, const FloatPoint* points)
+{
+ ASSERT(numberOfPoints > 0);
+
+ path.moveTo(points[0]);
+ for (size_t i = 1; i < 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 < numberOfPoints; ++i)
+ m_points.append(points[i]);
+}
+
+Optional<FloatRect> DrawConvexPolygon::localBounds(const GraphicsContext&) const
+{
+ FloatRect result;
+ for (auto& point : m_points)
+ result.extend(point);
+ result.inflate(m_antialiased ? 1 : 0); // Account for antialiasing
+ return result;
+}
+
+void DrawConvexPolygon::apply(GraphicsContext& context) const
+{
+ context.drawConvexPolygon(m_points.size(), m_points.data(), m_antialiased);
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawConvexPolygon& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("points", item.points());
+ ts.dumpProperty("antialiased", item.antialiased());
+ return ts;
+}
+
+void DrawPath::apply(GraphicsContext& context) const
+{
+#if USE(CG)
+ context.drawPath(m_path);
+#else
+ UNUSED_PARAM(context);
+#endif
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawPath& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+// ts.dumpProperty("path", item.path()); // FIXME: add logging for paths.
+ return ts;
+}
+
+void DrawFocusRingPath::apply(GraphicsContext& context) const
+{
+ context.drawFocusRing(m_path, m_width, m_offset, m_color);
+}
+
+Optional<FloatRect> DrawFocusRingPath::localBounds(const GraphicsContext&) const
+{
+ FloatRect result = m_path.fastBoundingRect();
+ result.inflate(platformFocusRingWidth);
+ return result;
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawFocusRingPath& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+// ts.dumpProperty("path", item.path()); // FIXME: add logging for paths.
+ ts.dumpProperty("width", item.width());
+ ts.dumpProperty("offset", item.offset());
+ ts.dumpProperty("color", item.color());
+ return ts;
+}
+
+void DrawFocusRingRects::apply(GraphicsContext& context) const
+{
+ context.drawFocusRing(m_rects, m_width, m_offset, m_color);
+}
+
+Optional<FloatRect> DrawFocusRingRects::localBounds(const GraphicsContext&) const
+{
+ FloatRect result;
+ for (auto& rect : m_rects)
+ result.unite(rect);
+ result.inflate(platformFocusRingWidth);
+ return result;
+}
+
+static TextStream& operator<<(TextStream& ts, const DrawFocusRingRects& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rects", item.rects());
+ ts.dumpProperty("width", item.width());
+ ts.dumpProperty("offset", item.offset());
+ ts.dumpProperty("color", item.color());
+ return ts;
+}
+
+void FillRect::apply(GraphicsContext& context) const
+{
+ context.fillRect(m_rect);
+}
+
+static TextStream& operator<<(TextStream& ts, const FillRect& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+void FillRectWithColor::apply(GraphicsContext& context) const
+{
+ context.fillRect(m_rect, m_color);
+}
+
+static TextStream& operator<<(TextStream& ts, const FillRectWithColor& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ ts.dumpProperty("color", item.color());
+ return ts;
+}
+
+void FillRectWithGradient::apply(GraphicsContext& context) const
+{
+ context.fillRect(m_rect, m_gradient.get());
+}
+
+static TextStream& operator<<(TextStream& ts, const FillRectWithGradient& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ // FIXME: log gradient.
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+void FillCompositedRect::apply(GraphicsContext& context) const
+{
+ context.fillRect(m_rect, m_color, m_op, m_blendMode);
+}
+
+static TextStream& operator<<(TextStream& ts, const FillCompositedRect& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ ts.dumpProperty("color", item.color());
+ ts.dumpProperty("composite-operation", item.compositeOperator());
+ ts.dumpProperty("blend-mode", item.blendMode());
+ return ts;
+}
+
+void FillRoundedRect::apply(GraphicsContext& context) const
+{
+ context.fillRoundedRect(m_rect, m_color, m_blendMode);
+}
+
+static TextStream& operator<<(TextStream& ts, const FillRoundedRect& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.roundedRect());
+ ts.dumpProperty("color", item.color());
+ ts.dumpProperty("blend-mode", item.blendMode());
+ return ts;
+}
+
+void FillRectWithRoundedHole::apply(GraphicsContext& context) const
+{
+ context.fillRectWithRoundedHole(m_rect, m_roundedHoleRect, m_color);
+}
+
+static TextStream& operator<<(TextStream& ts, const FillRectWithRoundedHole& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ ts.dumpProperty("rounded-hole-rect", item.roundedHoleRect());
+ ts.dumpProperty("color", item.color());
+ return ts;
+}
+
+void FillPath::apply(GraphicsContext& context) const
+{
+ context.fillPath(m_path);
+}
+
+static TextStream& operator<<(TextStream& ts, const FillPath& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+// ts.dumpProperty("path", item.path()); // FIXME: path logging.
+ return ts;
+}
+
+void FillEllipse::apply(GraphicsContext& context) const
+{
+ context.fillEllipse(m_rect);
+}
+
+static TextStream& operator<<(TextStream& ts, const FillEllipse& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+Optional<FloatRect> StrokeRect::localBounds(const GraphicsContext&) const
+{
+ FloatRect bounds = m_rect;
+ bounds.expand(m_lineWidth, m_lineWidth);
+ return bounds;
+}
+
+void StrokeRect::apply(GraphicsContext& context) const
+{
+ context.strokeRect(m_rect, m_lineWidth);
+}
+
+static TextStream& operator<<(TextStream& ts, const StrokeRect& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ ts.dumpProperty("line-width", item.lineWidth());
+ return ts;
+}
+
+Optional<FloatRect> StrokePath::localBounds(const GraphicsContext& 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& context) const
+{
+ context.strokePath(m_path);
+}
+
+static TextStream& operator<<(TextStream& ts, const StrokePath& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+// ts.dumpProperty("path", item.path()); // FIXME: path logging.
+ return ts;
+}
+
+Optional<FloatRect> StrokeEllipse::localBounds(const GraphicsContext& context) const
+{
+ float strokeThickness = context.strokeThickness();
+
+ FloatRect bounds = m_rect;
+ bounds.expand(strokeThickness, strokeThickness);
+ return bounds;
+}
+
+void StrokeEllipse::apply(GraphicsContext& context) const
+{
+ context.strokeEllipse(m_rect);
+}
+
+static TextStream& operator<<(TextStream& ts, const StrokeEllipse& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+void ClearRect::apply(GraphicsContext& context) const
+{
+ context.clearRect(m_rect);
+}
+
+static TextStream& operator<<(TextStream& ts, const ClearRect& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("rect", item.rect());
+ return ts;
+}
+
+void BeginTransparencyLayer::apply(GraphicsContext& context) const
+{
+ context.beginTransparencyLayer(m_opacity);
+}
+
+static TextStream& operator<<(TextStream& ts, const BeginTransparencyLayer& item)
+{
+ ts << static_cast<const DrawingItem&>(item);
+ ts.dumpProperty("opacity", item.opacity());
+ return ts;
+}
+
+void EndTransparencyLayer::apply(GraphicsContext& context) const
+{
+ context.endTransparencyLayer();
+}
+
+#if USE(CG)
+void ApplyStrokePattern::apply(GraphicsContext& context) const
+{
+ context.applyStrokePattern();
+}
+
+void ApplyFillPattern::apply(GraphicsContext& context) const
+{
+ context.applyFillPattern();
+}
+#endif
+
+void ApplyDeviceScaleFactor::apply(GraphicsContext& context) const
+{
+ context.applyDeviceScaleFactor(m_scaleFactor);
+}
+
+static TextStream& operator<<(TextStream& ts, const ApplyDeviceScaleFactor& item)
+{
+ ts.dumpProperty("scale-factor", item.scaleFactor());
+ return ts;
+}
+
+static TextStream& operator<<(TextStream& ts, const ItemType& type)
+{
+ switch (type) {
+ case ItemType::Save: ts << "save"; break;
+ case ItemType::Restore: ts << "restore"; break;
+ case ItemType::Translate: ts << "translate"; break;
+ case ItemType::Rotate: ts << "rotate"; break;
+ case ItemType::Scale: ts << "scale"; break;
+ case ItemType::ConcatenateCTM: ts << "concatentate-ctm"; break;
+ case ItemType::SetState: ts << "set-state"; break;
+ case ItemType::SetLineCap: ts << "set-line-cap"; break;
+ case ItemType::SetLineDash: ts << "set-line-dash"; break;
+ case ItemType::SetLineJoin: ts << "set-line-join"; break;
+ case ItemType::SetMiterLimit: ts << "set-miter-limit"; break;
+ case ItemType::Clip: ts << "clip"; break;
+ case ItemType::ClipOut: ts << "clip-out"; break;
+ case ItemType::ClipOutToPath: ts << "clip-out-to-path"; break;
+ case ItemType::ClipPath: ts << "clip-path"; break;
+ case ItemType::ClipConvexPolygon: ts << "clip-convex-polygon"; break;
+ case ItemType::DrawGlyphs: ts << "draw-glyphs"; break;
+ case ItemType::DrawImage: ts << "draw-image"; break;
+ case ItemType::DrawTiledImage: ts << "draw-tiled-image"; break;
+ case ItemType::DrawTiledScaledImage: ts << "draw-tiled-scaled-image"; break;
+#if USE(CG) || USE(CAIRO)
+ case ItemType::DrawNativeImage: ts << "draw-native-image"; break;
+#endif
+ case ItemType::DrawPattern: ts << "draw-pattern"; break;
+ case ItemType::DrawRect: ts << "draw-rect"; break;
+ case ItemType::DrawLine: ts << "draw-line"; break;
+ case ItemType::DrawLinesForText: ts << "draw-lines-for-text"; break;
+ case ItemType::DrawLineForDocumentMarker: ts << "draw-lines-for-document-marker"; break;
+ case ItemType::DrawEllipse: ts << "draw-ellipse"; break;
+ case ItemType::DrawConvexPolygon: ts << "draw-convex-polgon"; break;
+ case ItemType::DrawPath: ts << "draw-path"; break;
+ case ItemType::DrawFocusRingPath: ts << "draw-focus-ring-path"; break;
+ case ItemType::DrawFocusRingRects: ts << "draw-focus-ring-rects"; break;
+ case ItemType::FillRect: ts << "fill-rect"; break;
+ case ItemType::FillRectWithColor: ts << "fill-rect-with-color"; break;
+ case ItemType::FillRectWithGradient: ts << "fill-rect-with-gradient"; break;
+ case ItemType::FillCompositedRect: ts << "fill-composited-rect"; break;
+ case ItemType::FillRoundedRect: ts << "fill-rounded-rect"; break;
+ case ItemType::FillRectWithRoundedHole: ts << "fill-rect-with-rounded-hole"; break;
+ case ItemType::FillPath: ts << "fill-path"; break;
+ case ItemType::FillEllipse: ts << "fill-ellipse"; break;
+ case ItemType::StrokeRect: ts << "stroke-rect"; break;
+ case ItemType::StrokePath: ts << "stroke-path"; break;
+ case ItemType::StrokeEllipse: ts << "stroke-ellipse"; break;
+ case ItemType::ClearRect: ts << "clear-rect"; break;
+ case ItemType::BeginTransparencyLayer: ts << "begin-transparency-layer"; break;
+ case ItemType::EndTransparencyLayer: ts << "end-transparency-layer"; break;
+#if USE(CG)
+ case ItemType::ApplyStrokePattern: ts << "apply-stroke-pattern"; break;
+ case ItemType::ApplyFillPattern: ts << "apply-fill-pattern"; break;
+#endif
+ case ItemType::ApplyDeviceScaleFactor: ts << "apply-device-scale-factor"; break;
+ case ItemType::ClearShadow: ts << "clear-shadow"; break;
+ }
+ return ts;
+}
+
+TextStream& operator<<(TextStream& ts, const Item& item)
+{
+ TextStream::GroupScope group(ts);
+ ts << item.type();
+
+ // FIXME: Make a macro which takes a macro for all these enumeration switches
+ switch (item.type()) {
+ case ItemType::Save:
+ ts << downcast<Save>(item);
+ break;
+ case ItemType::Translate:
+ ts << downcast<Translate>(item);
+ break;
+ case ItemType::Rotate:
+ ts << downcast<Rotate>(item);
+ break;
+ case ItemType::Scale:
+ ts << downcast<Scale>(item);
+ break;
+ case ItemType::ConcatenateCTM:
+ ts << downcast<ConcatenateCTM>(item);
+ break;
+ case ItemType::SetState:
+ ts << downcast<SetState>(item);
+ break;
+ case ItemType::SetLineCap:
+ ts << downcast<SetLineCap>(item);
+ break;
+ case ItemType::SetLineDash:
+ ts << downcast<SetLineDash>(item);
+ break;
+ case ItemType::SetLineJoin:
+ ts << downcast<SetLineJoin>(item);
+ break;
+ case ItemType::SetMiterLimit:
+ ts << downcast<SetMiterLimit>(item);
+ break;
+ case ItemType::Clip:
+ ts << downcast<Clip>(item);
+ break;
+ case ItemType::ClipOut:
+ ts << downcast<ClipOut>(item);
+ break;
+ case ItemType::ClipOutToPath:
+ ts << downcast<ClipOutToPath>(item);
+ break;
+ case ItemType::ClipPath:
+ ts << downcast<ClipPath>(item);
+ break;
+ case ItemType::ClipConvexPolygon:
+ ts << downcast<ClipConvexPolygon>(item);
+ break;
+ case ItemType::DrawGlyphs:
+ ts << downcast<DrawGlyphs>(item);
+ break;
+ case ItemType::DrawImage:
+ ts << downcast<DrawImage>(item);
+ break;
+ case ItemType::DrawTiledImage:
+ ts << downcast<DrawTiledImage>(item);
+ break;
+ case ItemType::DrawTiledScaledImage:
+ ts << downcast<DrawTiledScaledImage>(item);
+ break;
+#if USE(CG) || USE(CAIRO)
+ case ItemType::DrawNativeImage:
+ ts << downcast<DrawNativeImage>(item);
+ break;
+#endif
+ case ItemType::DrawPattern:
+ ts << downcast<DrawPattern>(item);
+ break;
+ case ItemType::DrawRect:
+ ts << downcast<DrawRect>(item);
+ break;
+ case ItemType::DrawLine:
+ ts << downcast<DrawLine>(item);
+ break;
+ case ItemType::DrawLinesForText:
+ ts << downcast<DrawLinesForText>(item);
+ break;
+ case ItemType::DrawLineForDocumentMarker:
+ ts << downcast<DrawLineForDocumentMarker>(item);
+ break;
+ case ItemType::DrawEllipse:
+ ts << downcast<DrawEllipse>(item);
+ break;
+ case ItemType::DrawConvexPolygon:
+ ts << downcast<DrawConvexPolygon>(item);
+ break;
+ case ItemType::DrawPath:
+ ts << downcast<DrawPath>(item);
+ break;
+ case ItemType::DrawFocusRingPath:
+ ts << downcast<DrawFocusRingPath>(item);
+ break;
+ case ItemType::DrawFocusRingRects:
+ ts << downcast<DrawFocusRingRects>(item);
+ break;
+ case ItemType::FillRect:
+ ts << downcast<FillRect>(item);
+ break;
+ case ItemType::FillRectWithColor:
+ ts << downcast<FillRectWithColor>(item);
+ break;
+ case ItemType::FillRectWithGradient:
+ ts << downcast<FillRectWithGradient>(item);
+ break;
+ case ItemType::FillCompositedRect:
+ ts << downcast<FillCompositedRect>(item);
+ break;
+ case ItemType::FillRoundedRect:
+ ts << downcast<FillRoundedRect>(item);
+ break;
+ case ItemType::FillRectWithRoundedHole:
+ ts << downcast<FillRectWithRoundedHole>(item);
+ break;
+ case ItemType::FillPath:
+ ts << downcast<FillPath>(item);
+ break;
+ case ItemType::FillEllipse:
+ ts << downcast<FillEllipse>(item);
+ break;
+ case ItemType::StrokeRect:
+ ts << downcast<StrokeRect>(item);
+ break;
+ case ItemType::StrokePath:
+ ts << downcast<StrokePath>(item);
+ break;
+ case ItemType::StrokeEllipse:
+ ts << downcast<StrokeEllipse>(item);
+ break;
+ case ItemType::ClearRect:
+ ts << downcast<ClearRect>(item);
+ break;
+ case ItemType::BeginTransparencyLayer:
+ ts << downcast<BeginTransparencyLayer>(item);
+ break;
+ case ItemType::ApplyDeviceScaleFactor:
+ ts << downcast<ApplyDeviceScaleFactor>(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 "FloatPoint.h"
+#include "FloatRect.h"
+#include "FloatRoundedRect.h"
+#include "Font.h"
+#include "GlyphBuffer.h"
+#include "GraphicsContext.h"
+#include "Image.h"
+#include <wtf/RefCounted.h>
+#include <wtf/TypeCasts.h>
+
+#if USE(CG)
+#include "GraphicsContextPlatformPrivateCG.h"
+#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<Item> {
+public:
+ Item() = delete;
+
+ Item(ItemType type)
+ : m_type(type)
+ {
+ }
+
+ virtual ~Item() { }
+
+ ItemType type() const
+ {
+ return m_type;
+ }
+
+ virtual void apply(GraphicsContext&) 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&);
+
+private:
+ ItemType m_type;
+};
+
+class DrawingItem : public Item {
+public:
+ DrawingItem(ItemType type)
+ : Item(type)
+ {
+ }
+
+ void setExtent(const FloatRect& r) { m_extent = r; }
+ const FloatRect& extent() const { return m_extent.value(); }
+
+ bool extentKnown() const { return static_cast<bool>(m_extent); }
+
+ // Return bounds of this drawing operation in local coordinates.
+ // Does not include effets of transform, shadow etc in the state.
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const { return Nullopt; }
+
+private:
+ virtual bool isDrawingItem() const { return true; }
+
+ Optional<FloatRect> m_extent; // In base coordinates, taking shadows and transforms into account.
+};
+
+class Save : public Item {
+public:
+ static Ref<Save> 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&) const override;
+
+ size_t m_restoreIndex { 0 };
+};
+
+class Restore : public Item {
+public:
+ static Ref<Restore> create()
+ {
+ return adoptRef(*new Restore);
+ }
+
+private:
+ Restore()
+ : Item(ItemType::Restore)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+};
+
+class Translate : public Item {
+public:
+ static Ref<Translate> 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&) const override;
+
+ float m_x;
+ float m_y;
+};
+
+class Rotate : public Item {
+public:
+ static Ref<Rotate> 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&) const override;
+
+ float m_angle; // In radians.
+};
+
+class Scale : public Item {
+public:
+ static Ref<Scale> create(const FloatSize& size)
+ {
+ return adoptRef(*new Scale(size));
+ }
+
+ const FloatSize& amount() const { return m_size; }
+
+private:
+ Scale(const FloatSize& size)
+ : Item(ItemType::Scale)
+ , m_size(size)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ FloatSize m_size;
+};
+
+class ConcatenateCTM : public Item {
+public:
+ static Ref<ConcatenateCTM> create(const AffineTransform& matrix)
+ {
+ return adoptRef(*new ConcatenateCTM(matrix));
+ }
+
+ const AffineTransform& transform() const { return m_transform; }
+
+private:
+ ConcatenateCTM(const AffineTransform&);
+
+ virtual void apply(GraphicsContext&) const override;
+
+ AffineTransform m_transform;
+};
+
+class SetState : public Item {
+public:
+ static Ref<SetState> create(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
+ {
+ return adoptRef(*new SetState(state, flags));
+ }
+
+ const GraphicsContextStateChange& state() const { return m_state; }
+
+ void accumulate(const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
+
+ void accumulate(GraphicsContextState&) const;
+
+ static void applyState(GraphicsContext&, const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
+
+ static void dumpStateChanges(TextStream&, const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
+private:
+ SetState(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags)
+ : Item(ItemType::SetState)
+ , m_state(state, flags)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ GraphicsContextStateChange m_state;
+};
+
+class SetLineCap : public Item {
+public:
+ static Ref<SetLineCap> 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&) const override;
+
+ LineCap m_lineCap;
+};
+
+class SetLineDash : public Item {
+public:
+ static Ref<SetLineDash> create(const DashArray& dashArray, float dashOffset)
+ {
+ return adoptRef(*new SetLineDash(dashArray, dashOffset));
+ }
+
+ const DashArray& dashArray() const { return m_dashArray; }
+ float dashOffset() const { return m_dashOffset; }
+
+private:
+ SetLineDash(const DashArray& dashArray, float dashOffset)
+ : Item(ItemType::SetLineDash)
+ , m_dashArray(dashArray)
+ , m_dashOffset(dashOffset)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ DashArray m_dashArray;
+ float m_dashOffset;
+};
+
+class SetLineJoin : public Item {
+public:
+ static Ref<SetLineJoin> 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&) const override;
+
+ LineJoin m_lineJoin;
+};
+
+class SetMiterLimit : public Item {
+public:
+ static Ref<SetMiterLimit> 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&) const override;
+
+ float m_miterLimit;
+};
+
+class ClearShadow : public Item {
+public:
+ static Ref<ClearShadow> create()
+ {
+ return adoptRef(*new ClearShadow);
+ }
+
+private:
+ ClearShadow()
+ : Item(ItemType::ClearShadow)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+};
+
+// FIXME: treat as DrawingItem?
+class Clip : public Item {
+public:
+ static Ref<Clip> create(const FloatRect& rect)
+ {
+ return adoptRef(*new Clip(rect));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ Clip(const FloatRect& rect)
+ : Item(ItemType::Clip)
+ , m_rect(rect)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ FloatRect m_rect;
+};
+
+class ClipOut : public Item {
+public:
+ static Ref<ClipOut> create(const FloatRect& rect)
+ {
+ return adoptRef(*new ClipOut(rect));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ ClipOut(const FloatRect& rect)
+ : Item(ItemType::ClipOut)
+ , m_rect(rect)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ FloatRect m_rect;
+};
+
+class ClipOutToPath : public Item {
+public:
+ static Ref<ClipOutToPath> create(const Path& path)
+ {
+ return adoptRef(*new ClipOutToPath(path));
+ }
+
+ const Path& path() const { return m_path; }
+
+private:
+ ClipOutToPath(const Path& path)
+ : Item(ItemType::ClipOutToPath)
+ , m_path(path)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ const Path m_path;
+};
+
+class ClipPath : public Item {
+public:
+ static Ref<ClipPath> create(const Path& path, WindRule windRule)
+ {
+ return adoptRef(*new ClipPath(path, windRule));
+ }
+
+ const Path& path() const { return m_path; }
+ WindRule windRule() const { return m_windRule; }
+
+private:
+ ClipPath(const Path& path, WindRule windRule)
+ : Item(ItemType::ClipPath)
+ , m_path(path)
+ , m_windRule(windRule)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ const Path m_path;
+ WindRule m_windRule;
+};
+
+class ClipConvexPolygon : public Item {
+public:
+ static Ref<ClipConvexPolygon> create(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+ {
+ return adoptRef(*new ClipConvexPolygon(numberOfPoints, points, antialiased));
+ }
+
+ const Vector<FloatPoint>& points() const { return m_points; }
+ bool antialias() const { return m_antialias; }
+
+private:
+ ClipConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased);
+
+ virtual void apply(GraphicsContext&) const override;
+
+ Vector<FloatPoint> m_points;
+ bool m_antialias;
+};
+
+class DrawGlyphs : public DrawingItem {
+public:
+ static Ref<DrawGlyphs> create(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode smoothingMode)
+ {
+ return adoptRef(*new DrawGlyphs(font, glyphs, advances, count, blockLocation, localAnchor, smoothingMode));
+ }
+
+ const FloatPoint& blockLocation() const { return m_blockLocation; }
+ void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; }
+
+ const FloatSize& localAnchor() const { return m_localAnchor; }
+
+ FloatPoint anchorPoint() const { return m_blockLocation + m_localAnchor; }
+
+ const Vector<GlyphBufferGlyph, 128>& glyphs() const { return m_glyphs; }
+
+private:
+ DrawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode);
+
+ void computeBounds();
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ GlyphBuffer generateGlyphBuffer() const;
+
+ Ref<Font> m_font;
+ Vector<GlyphBufferGlyph, 128> m_glyphs;
+ Vector<GlyphBufferAdvance, 128> m_advances;
+ FloatRect m_bounds;
+ FloatPoint m_blockLocation;
+ FloatSize m_localAnchor;
+ FontSmoothingMode m_smoothingMode;
+};
+
+class DrawImage : public DrawingItem {
+public:
+ static Ref<DrawImage> create(Image& image, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& imagePaintingOptions)
+ {
+ return adoptRef(*new DrawImage(image, destination, source, imagePaintingOptions));
+ }
+
+ const Image& image() const { return m_image.get(); }
+ FloatRect source() const { return m_source; }
+ FloatRect destination() const { return m_destination; }
+
+private:
+ DrawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions&);
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
+
+ mutable Ref<Image> 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<DrawTiledImage> create(Image& image, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& imagePaintingOptions)
+ {
+ return adoptRef(*new DrawTiledImage(image, destination, source, tileSize, spacing, imagePaintingOptions));
+ }
+
+ const Image& 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&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions&);
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
+
+ mutable Ref<Image> 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<DrawTiledScaledImage> create(Image& image, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions& imagePaintingOptions)
+ {
+ return adoptRef(*new DrawTiledScaledImage(image, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions));
+ }
+
+ const Image& image() const { return m_image.get(); }
+ FloatRect source() const { return m_source; }
+ FloatRect destination() const { return m_destination; }
+
+private:
+ DrawTiledScaledImage(Image&, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&);
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
+
+ mutable Ref<Image> 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<DrawNativeImage> create(PassNativeImagePtr imagePtr, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& 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& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientation);
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
+
+#if USE(CG)
+ RetainPtr<CGImageRef> 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<DrawPattern> create(Image& image, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
+ {
+ return adoptRef(*new DrawPattern(image, tileRect, patternTransform, phase, spacing, op, destRect, blendMode));
+ }
+
+ const Image& image() const { return m_image.get(); }
+ const AffineTransform& 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&, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal);
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; }
+
+ mutable Ref<Image> 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<BeginTransparencyLayer> 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&) const override;
+
+ float m_opacity;
+};
+
+class EndTransparencyLayer : public DrawingItem {
+public:
+ static Ref<EndTransparencyLayer> create()
+ {
+ return adoptRef(*new EndTransparencyLayer);
+ }
+
+private:
+ EndTransparencyLayer()
+ : DrawingItem(ItemType::EndTransparencyLayer)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+};
+
+class DrawRect : public DrawingItem {
+public:
+ static Ref<DrawRect> create(const FloatRect& 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& rect, float borderThickness)
+ : DrawingItem(ItemType::DrawRect)
+ , m_rect(rect)
+ , m_borderThickness(borderThickness)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+ float m_borderThickness;
+};
+
+class DrawLine : public DrawingItem {
+public:
+ static Ref<DrawLine> create(const FloatPoint& point1, const FloatPoint& point2)
+ {
+ return adoptRef(*new DrawLine(point1, point2));
+ }
+
+ FloatPoint point1() const { return m_point1; }
+ FloatPoint point2() const { return m_point2; }
+
+private:
+ DrawLine(const FloatPoint& point1, const FloatPoint& point2)
+ : DrawingItem(ItemType::DrawLine)
+ , m_point1(point1)
+ , m_point2(point2)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ FloatPoint m_point1;
+ FloatPoint m_point2;
+};
+
+class DrawLinesForText : public DrawingItem {
+public:
+ static Ref<DrawLinesForText> create(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& widths, bool printing, bool doubleLines, float strokeWidth)
+ {
+ return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, widths, printing, doubleLines, strokeWidth));
+ }
+
+ void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; }
+ const FloatPoint& blockLocation() const { return m_blockLocation; }
+ const FloatSize& localAnchor() const { return m_localAnchor; }
+ FloatPoint point() const { return m_blockLocation + m_localAnchor; }
+ const DashArray& widths() const { return m_widths; }
+ bool isPrinting() const { return m_printing; }
+ bool doubleLines() const { return m_doubleLines; }
+
+private:
+ DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& 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&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) 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<DrawLineForDocumentMarker> create(const FloatPoint& 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& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+ : DrawingItem(ItemType::DrawLineForDocumentMarker)
+ , m_point(point)
+ , m_width(width)
+ , m_style(style)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ FloatPoint m_point;
+ float m_width;
+ GraphicsContext::DocumentMarkerLineStyle m_style;
+};
+
+class DrawEllipse : public DrawingItem {
+public:
+ static Ref<DrawEllipse> create(const FloatRect& rect)
+ {
+ return adoptRef(*new DrawEllipse(rect));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ DrawEllipse(const FloatRect& rect)
+ : DrawingItem(ItemType::DrawEllipse)
+ , m_rect(rect)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+};
+
+class DrawConvexPolygon : public DrawingItem {
+public:
+ static Ref<DrawConvexPolygon> create(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+ {
+ return adoptRef(*new DrawConvexPolygon(numberOfPoints, points, antialiased));
+ }
+
+ const Vector<FloatPoint>& points() const { return m_points; }
+ bool antialiased() const { return m_antialiased; }
+
+private:
+ DrawConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased);
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ Vector<FloatPoint> m_points;
+ bool m_antialiased;
+};
+
+class DrawPath : public DrawingItem {
+public:
+ static Ref<DrawPath> create(const Path& path)
+ {
+ return adoptRef(*new DrawPath(path));
+ }
+
+ const Path& path() const { return m_path; }
+
+private:
+ DrawPath(const Path& path)
+ : DrawingItem(ItemType::DrawPath)
+ , m_path(path)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_path.fastBoundingRect(); }
+
+ const Path m_path;
+};
+
+class DrawFocusRingPath : public DrawingItem {
+public:
+ static Ref<DrawFocusRingPath> create(const Path& path, int width, int offset, const Color& color)
+ {
+ return adoptRef(*new DrawFocusRingPath(path, width, offset, color));
+ }
+
+ const Path& 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& path, int width, int offset, const Color& color)
+ : DrawingItem(ItemType::DrawFocusRingPath)
+ , m_path(path)
+ , m_width(width)
+ , m_offset(offset)
+ , m_color(color)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ const Path m_path;
+ int m_width;
+ int m_offset;
+ Color m_color;
+};
+
+class DrawFocusRingRects : public DrawingItem {
+public:
+ static Ref<DrawFocusRingRects> create(const Vector<IntRect>& rects, int width, int offset, const Color& color)
+ {
+ return adoptRef(*new DrawFocusRingRects(rects, width, offset, color));
+ }
+
+ const Vector<IntRect> 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<IntRect>& rects, int width, int offset, const Color& color)
+ : DrawingItem(ItemType::DrawFocusRingRects)
+ , m_rects(rects)
+ , m_width(width)
+ , m_offset(offset)
+ , m_color(color)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ Vector<IntRect> m_rects;
+ int m_width;
+ int m_offset;
+ Color m_color;
+};
+
+class FillRect : public DrawingItem {
+public:
+ static Ref<FillRect> create(const FloatRect& rect)
+ {
+ return adoptRef(*new FillRect(rect));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ FillRect(const FloatRect& rect)
+ : DrawingItem(ItemType::FillRect)
+ , m_rect(rect)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+};
+
+// FIXME: Make these inherit from FillRect proper.
+class FillRectWithColor : public DrawingItem {
+public:
+ static Ref<FillRectWithColor> create(const FloatRect& rect, const Color& color)
+ {
+ return adoptRef(*new FillRectWithColor(rect, color));
+ }
+
+ FloatRect rect() const { return m_rect; }
+ Color color() const { return m_color; }
+
+private:
+ FillRectWithColor(const FloatRect& rect, const Color& color)
+ : DrawingItem(ItemType::FillRectWithColor)
+ , m_rect(rect)
+ , m_color(color)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+ Color m_color;
+};
+
+class FillRectWithGradient : public DrawingItem {
+public:
+ static Ref<FillRectWithGradient> create(const FloatRect& rect, Gradient& gradient)
+ {
+ return adoptRef(*new FillRectWithGradient(rect, gradient));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ FillRectWithGradient(const FloatRect& rect, Gradient& gradient)
+ : DrawingItem(ItemType::FillRectWithGradient)
+ , m_rect(rect)
+ , m_gradient(gradient)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+ mutable Ref<Gradient> m_gradient; // FIXME: Make this not mutable
+};
+
+class FillCompositedRect : public DrawingItem {
+public:
+ static Ref<FillCompositedRect> create(const FloatRect& rect, const Color& 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& rect, const Color& color, CompositeOperator op, BlendMode blendMode)
+ : DrawingItem(ItemType::FillCompositedRect)
+ , m_rect(rect)
+ , m_color(color)
+ , m_op(op)
+ , m_blendMode(blendMode)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+ Color m_color;
+ CompositeOperator m_op;
+ BlendMode m_blendMode;
+};
+
+class FillRoundedRect : public DrawingItem {
+public:
+ static Ref<FillRoundedRect> create(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode)
+ {
+ return adoptRef(*new FillRoundedRect(rect, color, blendMode));
+ }
+
+ const FloatRoundedRect& roundedRect() const { return m_rect; }
+ Color color() const { return m_color; }
+ BlendMode blendMode() const { return m_blendMode; }
+
+private:
+ FillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode)
+ : DrawingItem(ItemType::FillRoundedRect)
+ , m_rect(rect)
+ , m_color(color)
+ , m_blendMode(blendMode)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect.rect(); }
+
+ FloatRoundedRect m_rect;
+ Color m_color;
+ BlendMode m_blendMode;
+};
+
+class FillRectWithRoundedHole : public DrawingItem {
+public:
+ static Ref<FillRectWithRoundedHole> create(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
+ {
+ return adoptRef(*new FillRectWithRoundedHole(rect, roundedHoleRect, color));
+ }
+
+ const FloatRect& rect() const { return m_rect; }
+ const FloatRoundedRect& roundedHoleRect() const { return m_roundedHoleRect; }
+ Color color() const { return m_color; }
+
+private:
+ FillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
+ : DrawingItem(ItemType::FillRectWithRoundedHole)
+ , m_rect(rect)
+ , m_roundedHoleRect(roundedHoleRect)
+ , m_color(color)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+ FloatRoundedRect m_roundedHoleRect;
+ Color m_color;
+};
+
+class FillPath : public DrawingItem {
+public:
+ static Ref<FillPath> create(const Path& path)
+ {
+ return adoptRef(*new FillPath(path));
+ }
+
+ const Path& path() const { return m_path; }
+
+private:
+ FillPath(const Path& path)
+ : DrawingItem(ItemType::FillPath)
+ , m_path(path)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_path.fastBoundingRect(); }
+
+ const Path m_path;
+};
+
+class FillEllipse : public DrawingItem {
+public:
+ static Ref<FillEllipse> create(const FloatRect& rect)
+ {
+ return adoptRef(*new FillEllipse(rect));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ FillEllipse(const FloatRect& rect)
+ : DrawingItem(ItemType::FillEllipse)
+ , m_rect(rect)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+};
+
+class StrokeRect : public DrawingItem {
+public:
+ static Ref<StrokeRect> create(const FloatRect& 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& rect, float lineWidth)
+ : DrawingItem(ItemType::StrokeRect)
+ , m_rect(rect)
+ , m_lineWidth(lineWidth)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ FloatRect m_rect;
+ float m_lineWidth;
+};
+
+class StrokePath : public DrawingItem {
+public:
+ static Ref<StrokePath> create(const Path& path)
+ {
+ return adoptRef(*new StrokePath(path));
+ }
+
+ const Path& path() const { return m_path; }
+
+private:
+ StrokePath(const Path& path)
+ : DrawingItem(ItemType::StrokePath)
+ , m_path(path)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ const Path m_path;
+ FloatPoint m_blockLocation;
+};
+
+class StrokeEllipse : public DrawingItem {
+public:
+ static Ref<StrokeEllipse> create(const FloatRect& rect)
+ {
+ return adoptRef(*new StrokeEllipse(rect));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ StrokeEllipse(const FloatRect& rect)
+ : DrawingItem(ItemType::StrokeEllipse)
+ , m_rect(rect)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override;
+
+ FloatRect m_rect;
+};
+
+class ClearRect : public DrawingItem {
+public:
+ static Ref<ClearRect> create(const FloatRect& rect)
+ {
+ return adoptRef(*new ClearRect(rect));
+ }
+
+ FloatRect rect() const { return m_rect; }
+
+private:
+ ClearRect(const FloatRect& rect)
+ : DrawingItem(ItemType::ClearRect)
+ , m_rect(rect)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; }
+
+ FloatRect m_rect;
+};
+
+#if USE(CG)
+class ApplyStrokePattern : public Item {
+public:
+ static Ref<ApplyStrokePattern> create()
+ {
+ return adoptRef(*new ApplyStrokePattern);
+ }
+
+private:
+ ApplyStrokePattern()
+ : Item(ItemType::ApplyStrokePattern)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+};
+
+class ApplyFillPattern : public Item {
+public:
+ static Ref<ApplyFillPattern> create()
+ {
+ return adoptRef(*new ApplyFillPattern);
+ }
+
+private:
+ ApplyFillPattern()
+ : Item(ItemType::ApplyFillPattern)
+ {
+ }
+
+ virtual void apply(GraphicsContext&) const override;
+};
+#endif
+
+class ApplyDeviceScaleFactor : public Item {
+public:
+ static Ref<ApplyDeviceScaleFactor> 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&) const override;
+
+ float m_scaleFactor;
+};
+
+// FIXME: this needs to move.
+void addConvexPolygonToPath(Path&, size_t numPoints, const FloatPoint*);
+
+TextStream& operator<<(TextStream&, const Item&);
+
+} // 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& 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& 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 "config.h"
+#include "DisplayListRecorder.h"
+
+#include "DisplayList.h"
+#include "DisplayListItems.h"
+#include "GraphicsContext.h"
+#include "Logging.h"
+#include "TextStream.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+namespace DisplayList {
+
+Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const FloatRect& initialClip, const AffineTransform& baseCTM)
+ : m_graphicsContext(context)
+ , m_displayList(displayList)
+{
+ LOG_WITH_STREAM(DisplayLists, stream << "\nRecording with clip " << 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, "Recorded display list:\n%s", m_displayList.description().data());
+}
+
+void Recorder::willAppendItem(const Item& item)
+{
+ if (item.isDrawingItem()
+#if USE(CG)
+ || item.type() == ItemType::ApplyStrokePattern || item.type() == ItemType::ApplyStrokePattern
+#endif
+ ) {
+ GraphicsContextStateChange& stateChanges = currentState().stateChange;
+ GraphicsContextState::StateChangeFlags changesFromLastState = stateChanges.changesFromState(currentState().lastDrawingState);
+ if (changesFromLastState) {
+ LOG_WITH_STREAM(DisplayLists, stream << "pre-drawing, saving state " << 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& 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& 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& font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawGlyphs::create(font, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs, FloatPoint(), toFloatSize(startPoint), smoothingMode)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawImage(Image& image, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& imagePaintingOptions)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawImage::create(image, destination, source, imagePaintingOptions)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawTiledImage(Image& image, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& imagePaintingOptions)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawTiledImage::create(image, destination, source, tileSize, spacing, imagePaintingOptions)));
+ updateItemExtent(newItem);
+}
+
+#if USE(CG) || USE(CAIRO)
+void Recorder::drawNativeImage(PassNativeImagePtr imagePtr, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawNativeImage::create(imagePtr, imageSize, destRect, srcRect, op, blendMode, orientation)));
+ updateItemExtent(newItem);
+}
+#endif
+
+void Recorder::drawTiledImage(Image& image, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions& imagePaintingOptions)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawTiledScaledImage::create(image, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawPattern(Image& image, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(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 && 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& saveItem = downcast<Save>(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& size)
+{
+ currentState().scale(size);
+ appendItem(Scale::create(size));
+}
+
+void Recorder::concatCTM(const AffineTransform& transform)
+{
+ currentState().concatCTM(transform);
+ appendItem(ConcatenateCTM::create(transform));
+}
+
+void Recorder::beginTransparencyLayer(float opacity)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(BeginTransparencyLayer::create(opacity)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::endTransparencyLayer()
+{
+ appendItem(EndTransparencyLayer::create());
+}
+
+void Recorder::drawRect(const FloatRect& rect, float borderThickness)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawRect::create(rect, borderThickness)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawLine(const FloatPoint& point1, const FloatPoint& point2)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLine::create(point1, point2)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLinesForText::create(FloatPoint(), toFloatSize(point), widths, printing, doubleLines, strokeThickness)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawLineForDocumentMarker(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLineForDocumentMarker::create(point, width, style)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawEllipse(const FloatRect& rect)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawEllipse::create(rect)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawConvexPolygon(size_t numberOfPoints, const FloatPoint* points, bool antialiased)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawConvexPolygon::create(numberOfPoints, points, antialiased)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawPath(const Path& path)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawPath::create(path)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawFocusRing(const Path& path, int width, int offset, const Color& color)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawFocusRingPath::create(path, width, offset, color)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawFocusRingRects::create(rects, width, offset, color)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect& rect)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRect::create(rect)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect& rect, const Color& color)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRectWithColor::create(rect, color)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect& rect, Gradient& gradient)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRectWithGradient::create(rect, gradient)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillRect(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillCompositedRect::create(rect, color, op, blendMode)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRoundedRect::create(rect, color, blendMode)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRectWithRoundedHole::create(rect, roundedHoleRect, color)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillPath(const Path& path)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillPath::create(path)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::fillEllipse(const FloatRect& rect)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillEllipse::create(rect)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::strokeRect(const FloatRect& rect, float lineWidth)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(StrokeRect::create(rect, lineWidth)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::strokePath(const Path& path)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(StrokePath::create(path)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::strokeEllipse(const FloatRect& rect)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(StrokeEllipse::create(rect)));
+ updateItemExtent(newItem);
+}
+
+void Recorder::clearRect(const FloatRect& rect)
+{
+ DrawingItem& newItem = downcast<DrawingItem>(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& rect)
+{
+ currentState().clipBounds.intersect(rect);
+ appendItem(Clip::create(rect));
+}
+
+void Recorder::clipOut(const FloatRect& rect)
+{
+ appendItem(ClipOut::create(rect));
+}
+
+void Recorder::clipOut(const Path& path)
+{
+ appendItem(ClipOutToPath::create(path));
+}
+
+void Recorder::clipPath(const Path& 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& Recorder::appendItem(Ref<Item>&& item)
+{
+ willAppendItem(item.get());
+ return m_displayList.append(WTFMove(item));
+}
+
+void Recorder::updateItemExtent(DrawingItem& item) const
+{
+ if (Optional<FloatRect> 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& rect) const
+{
+ FloatRect bounds = rect;
+ const ContextState& 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& Recorder::currentState() const
+{
+ ASSERT(m_stateStack.size());
+ return m_stateStack.last();
+}
+
+Recorder::ContextState& Recorder::currentState()
+{
+ ASSERT(m_stateStack.size());
+ return m_stateStack.last();
+}
+
+const AffineTransform& Recorder::ctm() const
+{
+ return currentState().ctm;
+}
+
+const FloatRect& 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<double>(angleInRadians));
+ ctm.rotate(angleInDegrees);
+
+ AffineTransform rotation;
+ rotation.rotate(angleInDegrees);
+
+ if (Optional<AffineTransform> inverse = rotation.inverse())
+ clipBounds = inverse.value().mapRect(clipBounds);
+}
+
+void Recorder::ContextState::scale(const FloatSize& size)
+{
+ ctm.scale(size);
+ clipBounds.scale(1 / size.width(), 1 / size.height());
+}
+
+void Recorder::ContextState::concatCTM(const AffineTransform& matrix)
+{
+ ctm *= matrix;
+
+ if (Optional<AffineTransform> 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 "DisplayList.h"
+#include "GraphicsContext.h" // For InterpolationQuality.
+#include "Image.h" // For Image::TileRule.
+#include "TextFlags.h"
+#include <wtf/Noncopyable.h>
+
+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&, DisplayList&, const FloatRect& initialClip, const AffineTransform&);
+ ~Recorder();
+
+ void updateState(const GraphicsContextState&, GraphicsContextState::StateChangeFlags);
+ void clearShadow();
+
+ void setLineCap(LineCap);
+ void setLineDash(const DashArray&, float dashOffset);
+ void setLineJoin(LineJoin);
+ void setMiterLimit(float);
+
+ void fillRect(const FloatRect&);
+ void fillRect(const FloatRect&, const Color&);
+ void fillRect(const FloatRect&, Gradient&);
+ void fillRect(const FloatRect&, const Color&, CompositeOperator, BlendMode);
+ void fillRoundedRect(const FloatRoundedRect&, const Color&, BlendMode);
+ void fillRectWithRoundedHole(const FloatRect&, const FloatRoundedRect& roundedHoleRect, const Color&);
+ void fillPath(const Path&);
+ void fillEllipse(const FloatRect&);
+ void strokeRect(const FloatRect&, float lineWidth);
+ void strokePath(const Path&);
+ void strokeEllipse(const FloatRect&);
+ void clearRect(const FloatRect&);
+
+#if USE(CG)
+ void applyStrokePattern();
+ void applyFillPattern();
+#endif
+
+ void drawGlyphs(const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode);
+
+ void drawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions&);
+ void drawTiledImage(Image&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions&);
+ void drawTiledImage(Image&, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&);
+#if USE(CG) || USE(CAIRO)
+ void drawNativeImage(PassNativeImagePtr, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientation);
+#endif
+ void drawPattern(Image&, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal);
+
+ void drawRect(const FloatRect&, float borderThickness);
+ void drawLine(const FloatPoint&, const FloatPoint&);
+ void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness);
+ void drawLineForDocumentMarker(const FloatPoint&, float width, GraphicsContext::DocumentMarkerLineStyle);
+ void drawEllipse(const FloatRect&);
+ void drawConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased);
+ void drawPath(const Path&);
+
+ void drawFocusRing(const Path&, int width, int offset, const Color&);
+ void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&);
+
+ void save();
+ void restore();
+
+ void translate(float x, float y);
+ void rotate(float angleInRadians);
+ void scale(const FloatSize&);
+ void concatCTM(const AffineTransform&);
+
+ void beginTransparencyLayer(float opacity);
+ void endTransparencyLayer();
+
+ void clip(const FloatRect&);
+ void clipOut(const FloatRect&);
+ void clipOut(const Path&);
+ void clipPath(const Path&, WindRule);
+ void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias);
+
+ void applyDeviceScaleFactor(float);
+
+ size_t size() const { return m_displayList.size(); }
+
+private:
+ Item& appendItem(Ref<Item>&&);
+ void willAppendItem(const Item&);
+
+ FloatRect extentFromLocalBounds(const FloatRect&) const;
+ void updateItemExtent(DrawingItem&) const;
+
+ const AffineTransform& ctm() const;
+ const FloatRect& clipBounds() const;
+
+ struct ContextState {
+ AffineTransform ctm;
+ FloatRect clipBounds;
+ GraphicsContextStateChange stateChange;
+ GraphicsContextState lastDrawingState;
+ bool wasUsedForDrawing { false };
+ size_t saveItemIndex { 0 };
+
+ ContextState(const AffineTransform& transform, const FloatRect& 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&);
+ void concatCTM(const AffineTransform&);
+ };
+
+ const ContextState& currentState() const;
+ ContextState& currentState();
+
+ GraphicsContext& m_graphicsContext;
+ DisplayList& m_displayList;
+
+ Vector<ContextState, 32> 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 "config.h"
+#include "DisplayListReplayer.h"
+
+#include "DisplayList.h"
+#include "DisplayListItems.h"
+#include "GraphicsContext.h"
+#include "Logging.h"
+#include "TextStream.h"
+
+namespace WebCore {
+namespace DisplayList {
+
+Replayer::Replayer(GraphicsContext& context, const DisplayList& displayList)
+ : m_displayList(displayList)
+ , m_context(context)
+{
+}
+
+Replayer::~Replayer()
+{
+}
+
+void Replayer::replay(const FloatRect& initialClip)
+{
+ LOG_WITH_STREAM(DisplayLists, stream << "\nReplaying with clip " << initialClip);
+ UNUSED_PARAM(initialClip);
+
+ size_t numItems = m_displayList.size();
+ for (size_t i = 0; i < numItems; ++i) {
+ auto& item = m_displayList.list()[i].get();
+ LOG_WITH_STREAM(DisplayLists, stream << "drawing " << i << " " << 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 <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class FloatRect;
+class GraphicsContext;
+
+namespace DisplayList {
+
+class DisplayList;
+
+class Replayer {
+ WTF_MAKE_NONCOPYABLE(Replayer);
+public:
+ Replayer(GraphicsContext&, const DisplayList&);
+ ~Replayer();
+
+ void replay(const FloatRect& initialClip);
+
+private:
+ const DisplayList& m_displayList;
+ GraphicsContext& m_context;
+};
+
+}
+}
+
+#endif // DisplayListReplayer_h
</ins></span></pre>
</div>
</div>
</body>
</html>