<!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>[183274] 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/183274">183274</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2015-04-24 12:01:48 -0700 (Fri, 24 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make it possible to map a secondary quad through TransformState
https://bugs.webkit.org/show_bug.cgi?id=144156

Reviewed by Dean Jackson.

A future patch will need to map two quads simultaneously through TransformState,
so add the ability to provide an optional secondary quad.

This patch also firms up the setQuad() contract, fixing webkit.org/b/106680,
requiring the state to be flattened when setting the quad (and now, the secondary quad).
Previously, setQuad implicitly flattened but failed to update m_mapPoint when
doing so.

* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::computeVisibleRect): Now we have to explicitly flatten
before setting the quad.
* platform/graphics/ca/GraphicsLayerCA.h: Drive-up #include removal.
* platform/graphics/transforms/TransformState.cpp:
(WebCore::TransformState::operator=): Copy the secondary quad if we have one.
(WebCore::TransformState::translateMappedCoordinates): Move the secondary quad
if we have one.
(WebCore::TransformState::mappedQuad): Code factored into mapQuad().
(WebCore::TransformState::mappedSecondaryQuad): Return the secondary quad mapped
into the state's current coordinate space.
(WebCore::TransformState::mapQuad): Factored code.
* platform/graphics/transforms/TransformState.h:
(WebCore::TransformState::setQuad): Make the contract more explicit with assertions.
(WebCore::TransformState::setSecondaryQuad): Ditto when setting the secondary quad.
(WebCore::TransformState::lastPlanarSecondaryQuad):
(WebCore::TransformState::lastPlanarQuad): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp">trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAh">trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstransformsTransformStatecpp">trunk/Source/WebCore/platform/graphics/transforms/TransformState.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstransformsTransformStateh">trunk/Source/WebCore/platform/graphics/transforms/TransformState.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (183273 => 183274)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-04-24 18:57:25 UTC (rev 183273)
+++ trunk/Source/WebCore/ChangeLog        2015-04-24 19:01:48 UTC (rev 183274)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2015-04-24  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Make it possible to map a secondary quad through TransformState
+        https://bugs.webkit.org/show_bug.cgi?id=144156
+
+        Reviewed by Dean Jackson.
+
+        A future patch will need to map two quads simultaneously through TransformState,
+        so add the ability to provide an optional secondary quad.
+        
+        This patch also firms up the setQuad() contract, fixing webkit.org/b/106680,
+        requiring the state to be flattened when setting the quad (and now, the secondary quad).
+        Previously, setQuad implicitly flattened but failed to update m_mapPoint when
+        doing so.
+
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::computeVisibleRect): Now we have to explicitly flatten
+        before setting the quad.
+        * platform/graphics/ca/GraphicsLayerCA.h: Drive-up #include removal.
+        * platform/graphics/transforms/TransformState.cpp:
+        (WebCore::TransformState::operator=): Copy the secondary quad if we have one.
+        (WebCore::TransformState::translateMappedCoordinates): Move the secondary quad
+        if we have one.
+        (WebCore::TransformState::mappedQuad): Code factored into mapQuad().
+        (WebCore::TransformState::mappedSecondaryQuad): Return the secondary quad mapped
+        into the state's current coordinate space.
+        (WebCore::TransformState::mapQuad): Factored code.
+        * platform/graphics/transforms/TransformState.h:
+        (WebCore::TransformState::setQuad): Make the contract more explicit with assertions.
+        (WebCore::TransformState::setSecondaryQuad): Ditto when setting the secondary quad.
+        (WebCore::TransformState::lastPlanarSecondaryQuad):
+        (WebCore::TransformState::lastPlanarQuad): Deleted.
+
</ins><span class="cx"> 2015-04-24  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Reimplement r182512 and r183153 in a cleaner way
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (183273 => 183274)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2015-04-24 18:57:25 UTC (rev 183273)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2015-04-24 19:01:48 UTC (rev 183274)
</span><span class="lines">@@ -1208,7 +1208,8 @@
</span><span class="cx">     
</span><span class="cx">     if (masksToBounds()) {
</span><span class="cx">         ASSERT(accumulation == TransformState::FlattenTransform);
</span><del>-        // Replace the quad in the TransformState with one that is clipped to this layer's bounds
</del><ins>+        // Flatten, and replace the quad in the TransformState with one that is clipped to this layer's bounds.
+        state.flatten();
</ins><span class="cx">         state.setQuad(clipRectForSelf);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (183273 => 183274)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h        2015-04-24 18:57:25 UTC (rev 183273)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h        2015-04-24 19:01:48 UTC (rev 183274)
</span><span class="lines">@@ -35,10 +35,6 @@
</span><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringHash.h&gt;
</span><span class="cx"> 
</span><del>-#if PLATFORM(COCOA)
-#include &quot;TileController.h&quot;
-#endif
-
</del><span class="cx"> // Enable this to add a light red wash over the visible portion of Tiled Layers, as computed
</span><span class="cx"> // by flushCompositingState().
</span><span class="cx"> // #define VISIBLE_TILE_WASH
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstransformsTransformStatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformState.cpp (183273 => 183274)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/transforms/TransformState.cpp        2015-04-24 18:57:25 UTC (rev 183273)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformState.cpp        2015-04-24 19:01:48 UTC (rev 183274)
</span><span class="lines">@@ -35,8 +35,14 @@
</span><span class="cx">     m_mapQuad = other.m_mapQuad;
</span><span class="cx">     if (m_mapPoint)
</span><span class="cx">         m_lastPlanarPoint = other.m_lastPlanarPoint;
</span><del>-    if (m_mapQuad)
</del><ins>+    if (m_mapQuad) {
</ins><span class="cx">         m_lastPlanarQuad = other.m_lastPlanarQuad;
</span><ins>+        if (other.m_lastPlanarSecondaryQuad)
+            m_lastPlanarSecondaryQuad = std::make_unique&lt;FloatQuad&gt;(*other.m_lastPlanarSecondaryQuad);
+        else
+            m_lastPlanarSecondaryQuad = nullptr;
+        
+    }
</ins><span class="cx">     m_accumulatingTransform = other.m_accumulatingTransform;
</span><span class="cx">     m_direction = other.m_direction;
</span><span class="cx">     
</span><span class="lines">@@ -61,8 +67,11 @@
</span><span class="cx">     LayoutSize adjustedOffset = (m_direction == ApplyTransformDirection) ? offset : -offset;
</span><span class="cx">     if (m_mapPoint)
</span><span class="cx">         m_lastPlanarPoint.move(adjustedOffset);
</span><del>-    if (m_mapQuad)
</del><ins>+    if (m_mapQuad) {
</ins><span class="cx">         m_lastPlanarQuad.move(adjustedOffset);
</span><ins>+        if (m_lastPlanarSecondaryQuad)
+            m_lastPlanarSecondaryQuad-&gt;move(adjustedOffset);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TransformState::move(const LayoutSize&amp; offset, TransformAccumulation accumulate)
</span><span class="lines">@@ -171,14 +180,33 @@
</span><span class="cx">         *wasClamped = false;
</span><span class="cx"> 
</span><span class="cx">     FloatQuad quad = m_lastPlanarQuad;
</span><ins>+    mapQuad(quad, wasClamped);
+    return quad;
+}
+
+std::unique_ptr&lt;FloatQuad&gt; TransformState::mappedSecondaryQuad(bool* wasClamped) const
+{
+    if (wasClamped)
+        *wasClamped = false;
+
+    if (!m_lastPlanarSecondaryQuad)
+        return nullptr;
+
+    FloatQuad quad = *m_lastPlanarSecondaryQuad;
+    mapQuad(quad, wasClamped);
+    return std::make_unique&lt;FloatQuad&gt;(quad);
+}
+
+void TransformState::mapQuad(FloatQuad&amp; quad, bool* wasClamped) const
+{
</ins><span class="cx">     quad.move((m_direction == ApplyTransformDirection) ? m_accumulatedOffset : -m_accumulatedOffset);
</span><span class="cx">     if (!m_accumulatedTransform)
</span><del>-        return quad;
</del><ins>+        return;
</ins><span class="cx"> 
</span><span class="cx">     if (m_direction == ApplyTransformDirection)
</span><del>-        return m_accumulatedTransform-&gt;mapQuad(quad);
</del><ins>+        quad = m_accumulatedTransform-&gt;mapQuad(quad);
</ins><span class="cx"> 
</span><del>-    return m_accumulatedTransform-&gt;inverse().projectQuad(quad, wasClamped);
</del><ins>+    quad = m_accumulatedTransform-&gt;inverse().projectQuad(quad, wasClamped);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TransformState::flattenWithTransform(const TransformationMatrix&amp; t, bool* wasClamped)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstransformsTransformStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/transforms/TransformState.h (183273 => 183274)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/transforms/TransformState.h        2015-04-24 18:57:25 UTC (rev 183273)
+++ trunk/Source/WebCore/platform/graphics/transforms/TransformState.h        2015-04-24 19:01:48 UTC (rev 183274)
</span><span class="lines">@@ -74,30 +74,40 @@
</span><span class="cx">     
</span><span class="cx">     void setQuad(const FloatQuad&amp; quad)
</span><span class="cx">     {
</span><del>-        // FIXME: this assumes that the quad being added is in the coordinate system of the current state.
-        // This breaks if we're simultaneously mapping a point. https://bugs.webkit.org/show_bug.cgi?id=106680
-        ASSERT(!m_mapPoint);
-        m_accumulatedOffset = LayoutSize();
</del><ins>+        // We must be in a flattened state (no accumulated offset) when setting this quad.
+        ASSERT(m_accumulatedOffset == LayoutSize());
</ins><span class="cx">         m_lastPlanarQuad = quad;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void setSecondaryQuad(const FloatQuad* quad)
+    {
+        // We must be in a flattened state (no accumulated offset) when setting this secondary quad.
+        ASSERT(m_accumulatedOffset == LayoutSize());
+        if (quad)
+            m_lastPlanarSecondaryQuad = std::make_unique&lt;FloatQuad&gt;(*quad);
+        else
+            m_lastPlanarSecondaryQuad = nullptr;
+    }
+
</ins><span class="cx">     void move(LayoutUnit x, LayoutUnit y, TransformAccumulation accumulate = FlattenTransform)
</span><span class="cx">     {
</span><span class="cx">         move(LayoutSize(x, y), accumulate);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void move(const LayoutSize&amp;, TransformAccumulation = FlattenTransform);
</span><del>-    void applyTransform(const AffineTransform&amp; transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = 0);
-    void applyTransform(const TransformationMatrix&amp; transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = 0);
-    void flatten(bool* wasClamped = 0);
</del><ins>+    void applyTransform(const AffineTransform&amp; transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = nullptr);
+    void applyTransform(const TransformationMatrix&amp; transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = nullptr);
+    void flatten(bool* wasClamped = nullptr);
</ins><span class="cx"> 
</span><span class="cx">     // Return the coords of the point or quad in the last flattened layer
</span><span class="cx">     FloatPoint lastPlanarPoint() const { return m_lastPlanarPoint; }
</span><span class="cx">     FloatQuad lastPlanarQuad() const { return m_lastPlanarQuad; }
</span><ins>+    FloatQuad* lastPlanarSecondaryQuad() const { return m_lastPlanarSecondaryQuad.get(); }
</ins><span class="cx"> 
</span><span class="cx">     // Return the point or quad mapped through the current transform
</span><del>-    FloatPoint mappedPoint(bool* wasClamped = 0) const;
-    FloatQuad mappedQuad(bool* wasClamped = 0) const;
</del><ins>+    FloatPoint mappedPoint(bool* wasClamped = nullptr) const;
+    FloatQuad mappedQuad(bool* wasClamped = nullptr) const;
+    std::unique_ptr&lt;FloatQuad&gt; mappedSecondaryQuad(bool* wasClamped = nullptr) const;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void translateTransform(const LayoutSize&amp;);
</span><span class="lines">@@ -105,14 +115,18 @@
</span><span class="cx">     void flattenWithTransform(const TransformationMatrix&amp;, bool* wasClamped);
</span><span class="cx">     void applyAccumulatedOffset();
</span><span class="cx">     
</span><ins>+    void mapQuad(FloatQuad&amp;, bool* clamped) const;
+    
</ins><span class="cx">     FloatPoint m_lastPlanarPoint;
</span><span class="cx">     FloatQuad m_lastPlanarQuad;
</span><ins>+    std::unique_ptr&lt;FloatQuad&gt; m_lastPlanarSecondaryQuad; // Optional second quad to map.
</ins><span class="cx"> 
</span><span class="cx">     // We only allocate the transform if we need to
</span><span class="cx">     std::unique_ptr&lt;TransformationMatrix&gt; m_accumulatedTransform;
</span><span class="cx">     LayoutSize m_accumulatedOffset;
</span><span class="cx">     bool m_accumulatingTransform;
</span><del>-    bool m_mapPoint, m_mapQuad;
</del><ins>+    bool m_mapPoint;
+    bool m_mapQuad;
</ins><span class="cx">     TransformDirection m_direction;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>