<!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>[206019] 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/206019">206019</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-09-16 02:59:52 -0700 (Fri, 16 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[TextureMapper] Scrolling through 01.org/dleyna crashes WebKitWebProcess
https://bugs.webkit.org/show_bug.cgi?id=162020

Reviewed by Žan Doberšek.

The problem is that we are trying to clone a ReferenceFilterOperation, which is not expected to be cloned, from
FilterAnimationValue copy constructor, and FilterOperations are never expected to be nullptr, so we end up
crashing. We just need to validate the filters before setting then and before creating a TextureMapperAnimation
for them.

* platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
(WebCore::GraphicsLayerTextureMapper::filtersCanBeComposited): Return false if there are reference filters or no
filters at all. I don't know if we really support other filters, but at least we won't crash for the others.
(WebCore::GraphicsLayerTextureMapper::addAnimation): Check if filters can be composited before creating a
TextureMapperAnimation.
(WebCore::GraphicsLayerTextureMapper::setFilters): Check if filters can be composited before setting them.
* platform/graphics/texmap/GraphicsLayerTextureMapper.h:
* platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
(WebCore::CoordinatedGraphicsLayer::filtersCanBeComposited): Return false if there are reference filters or no
filters at all. I don't know if we really support other filters, but at least we won't crash for the others.
(WebCore::CoordinatedGraphicsLayer::setFilters): Check if filters can be composited before setting them.
(WebCore::CoordinatedGraphicsLayer::addAnimation): Check if filters can be composited before creating a
TextureMapperAnimation.
* platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstexmapGraphicsLayerTextureMappercpp">trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstexmapGraphicsLayerTextureMapperh">trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstexmapcoordinatedCoordinatedGraphicsLayercpp">trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicstexmapcoordinatedCoordinatedGraphicsLayerh">trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (206018 => 206019)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-16 09:47:46 UTC (rev 206018)
+++ trunk/Source/WebCore/ChangeLog        2016-09-16 09:59:52 UTC (rev 206019)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2016-09-16  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [TextureMapper] Scrolling through 01.org/dleyna crashes WebKitWebProcess
+        https://bugs.webkit.org/show_bug.cgi?id=162020
+
+        Reviewed by Žan Doberšek.
+
+        The problem is that we are trying to clone a ReferenceFilterOperation, which is not expected to be cloned, from
+        FilterAnimationValue copy constructor, and FilterOperations are never expected to be nullptr, so we end up
+        crashing. We just need to validate the filters before setting then and before creating a TextureMapperAnimation
+        for them.
+
+        * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
+        (WebCore::GraphicsLayerTextureMapper::filtersCanBeComposited): Return false if there are reference filters or no
+        filters at all. I don't know if we really support other filters, but at least we won't crash for the others.
+        (WebCore::GraphicsLayerTextureMapper::addAnimation): Check if filters can be composited before creating a
+        TextureMapperAnimation.
+        (WebCore::GraphicsLayerTextureMapper::setFilters): Check if filters can be composited before setting them.
+        * platform/graphics/texmap/GraphicsLayerTextureMapper.h:
+        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
+        (WebCore::CoordinatedGraphicsLayer::filtersCanBeComposited): Return false if there are reference filters or no
+        filters at all. I don't know if we really support other filters, but at least we won't crash for the others.
+        (WebCore::CoordinatedGraphicsLayer::setFilters): Check if filters can be composited before setting them.
+        (WebCore::CoordinatedGraphicsLayer::addAnimation): Check if filters can be composited before creating a
+        TextureMapperAnimation.
+        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:
+
</ins><span class="cx"> 2016-09-16  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CachedFont do not need to be updated according Origin/Fetch mode
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstexmapGraphicsLayerTextureMappercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp (206018 => 206019)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp        2016-09-16 09:47:46 UTC (rev 206018)
+++ trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp        2016-09-16 09:59:52 UTC (rev 206019)
</span><span class="lines">@@ -560,6 +560,19 @@
</span><span class="cx">     return drawsContent() &amp;&amp; contentsAreVisible() &amp;&amp; !m_size.isEmpty();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool GraphicsLayerTextureMapper::filtersCanBeComposited(const FilterOperations&amp; filters) const
+{
+    if (!filters.size())
+        return false;
+
+    for (const auto&amp; filterOperation : filters.operations()) {
+        if (filterOperation-&gt;type() == FilterOperation::REFERENCE)
+            return false;
+    }
+
+    return true;
+}
+
</ins><span class="cx"> bool GraphicsLayerTextureMapper::addAnimation(const KeyframeValueList&amp; valueList, const FloatSize&amp; boxSize, const Animation* anim, const String&amp; keyframesName, double timeOffset)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!keyframesName.isEmpty());
</span><span class="lines">@@ -567,6 +580,16 @@
</span><span class="cx">     if (!anim || anim-&gt;isEmptyOrZeroDuration() || valueList.size() &lt; 2 || (valueList.property() != AnimatedPropertyTransform &amp;&amp; valueList.property() != AnimatedPropertyOpacity))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (valueList.property() == AnimatedPropertyFilter) {
+        int listIndex = validateFilterOperations(valueList);
+        if (listIndex &lt; 0)
+            return false;
+
+        const auto&amp; filters = static_cast&lt;const FilterAnimationValue&amp;&gt;(valueList.at(listIndex)).value();
+        if (!filtersCanBeComposited(filters))
+            return false;
+    }
+
</ins><span class="cx">     bool listsMatch = false;
</span><span class="cx">     bool hasBigRotation;
</span><span class="cx"> 
</span><span class="lines">@@ -604,11 +627,23 @@
</span><span class="cx"> 
</span><span class="cx"> bool GraphicsLayerTextureMapper::setFilters(const FilterOperations&amp; filters)
</span><span class="cx"> {
</span><del>-    TextureMapper* textureMapper = m_layer.textureMapper();
-    if (!textureMapper)
</del><ins>+    if (!m_layer.textureMapper())
</ins><span class="cx">         return false;
</span><del>-    notifyChange(FilterChange);
-    return GraphicsLayer::setFilters(filters);
</del><ins>+
+    bool canCompositeFilters = filtersCanBeComposited(filters);
+    if (GraphicsLayer::filters() == filters)
+        return canCompositeFilters;
+
+    if (canCompositeFilters) {
+        if (!GraphicsLayer::setFilters(filters))
+            return false;
+        notifyChange(FilterChange);
+    } else if (GraphicsLayer::filters().size()) {
+        clearFilters();
+        notifyChange(FilterChange);
+    }
+
+    return canCompositeFilters;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void GraphicsLayerTextureMapper::setFixedToViewport(bool fixed)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstexmapGraphicsLayerTextureMapperh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h (206018 => 206019)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h        2016-09-16 09:47:46 UTC (rev 206018)
+++ trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h        2016-09-16 09:59:52 UTC (rev 206019)
</span><span class="lines">@@ -117,6 +117,8 @@
</span><span class="cx">     void prepareBackingStoreIfNeeded();
</span><span class="cx">     bool shouldHaveBackingStore() const;
</span><span class="cx"> 
</span><ins>+    bool filtersCanBeComposited(const FilterOperations&amp;) const;
+
</ins><span class="cx">     // This set of flags help us defer which properties of the layer have been
</span><span class="cx">     // modified by the compositor, so we can know what to look for in the next flush.
</span><span class="cx">     enum ChangeMask {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstexmapcoordinatedCoordinatedGraphicsLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp (206018 => 206019)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp        2016-09-16 09:47:46 UTC (rev 206018)
+++ trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp        2016-09-16 09:59:52 UTC (rev 206019)
</span><span class="lines">@@ -426,16 +426,35 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool CoordinatedGraphicsLayer::filtersCanBeComposited(const FilterOperations&amp; filters) const
+{
+    if (!filters.size())
+        return false;
+
+    for (const auto&amp; filterOperation : filters.operations()) {
+        if (filterOperation-&gt;type() == FilterOperation::REFERENCE)
+            return false;
+    }
+
+    return true;
+}
+
</ins><span class="cx"> bool CoordinatedGraphicsLayer::setFilters(const FilterOperations&amp; newFilters)
</span><span class="cx"> {
</span><ins>+    bool canCompositeFilters = filtersCanBeComposited(newFilters);
</ins><span class="cx">     if (filters() == newFilters)
</span><del>-        return true;
</del><ins>+        return canCompositeFilters;
</ins><span class="cx"> 
</span><del>-    if (!GraphicsLayer::setFilters(newFilters))
-        return false;
</del><ins>+    if (canCompositeFilters) {
+        if (!GraphicsLayer::setFilters(newFilters))
+            return false;
+        didChangeFilters();
+    } else if (filters().size()) {
+        clearFilters();
+        didChangeFilters();
+    }
</ins><span class="cx"> 
</span><del>-    didChangeFilters();
-    return true;
</del><ins>+    return canCompositeFilters;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CoordinatedGraphicsLayer::setContentsToSolidColor(const Color&amp; color)
</span><span class="lines">@@ -1163,6 +1182,16 @@
</span><span class="cx">     if (!anim || anim-&gt;isEmptyOrZeroDuration() || valueList.size() &lt; 2 || (valueList.property() != AnimatedPropertyTransform &amp;&amp; valueList.property() != AnimatedPropertyOpacity &amp;&amp; valueList.property() != AnimatedPropertyFilter))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (valueList.property() == AnimatedPropertyFilter) {
+        int listIndex = validateFilterOperations(valueList);
+        if (listIndex &lt; 0)
+            return false;
+
+        const auto&amp; filters = static_cast&lt;const FilterAnimationValue&amp;&gt;(valueList.at(listIndex)).value();
+        if (!filtersCanBeComposited(filters))
+            return false;
+    }
+
</ins><span class="cx">     bool listsMatch = false;
</span><span class="cx">     bool ignoredHasBigRotation;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicstexmapcoordinatedCoordinatedGraphicsLayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h (206018 => 206019)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h        2016-09-16 09:47:46 UTC (rev 206018)
+++ trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h        2016-09-16 09:59:52 UTC (rev 206019)
</span><span class="lines">@@ -207,6 +207,8 @@
</span><span class="cx"> 
</span><span class="cx">     void animationStartedTimerFired();
</span><span class="cx"> 
</span><ins>+    bool filtersCanBeComposited(const FilterOperations&amp;) const;
+
</ins><span class="cx">     CoordinatedLayerID m_id;
</span><span class="cx">     CoordinatedGraphicsLayerState m_layerState;
</span><span class="cx">     GraphicsLayerTransform m_layerTransform;
</span></span></pre>
</div>
</div>

</body>
</html>