<!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>[159314] 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/159314">159314</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2013-11-14 15:15:24 -0800 (Thu, 14 Nov 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Cairo] Avoid extra copy when drawing images
https://bugs.webkit.org/show_bug.cgi?id=124209

Patch by Aloisio Almeida Jr &lt;aloisio.almeida@openbossa.org&gt; on 2013-11-14
Reviewed by Martin Robinson.

To solve the bug #58309 a cairo subsurface is being used to limit the
source image boundaries.
In many cases, when a cairo subsurface is used for drawing an image,
it occurs an image copy, causing performance penalty. In the case of
the function PlatformContextCairo::drawSurfaceToContext, the image
copy always happens.
So, we should use the subsurface only when it's really necessary.
In cases where we're drawing the whole image, the subsurface is
unnecessary.

The proposed patch avoid the use of subsurfaces when sampling the whole
image.

No new tests. It's an enhancement. Already covered by existing tests.

* platform/graphics/cairo/PlatformContextCairo.cpp:
(WebCore::PlatformContextCairo::drawSurfaceToContext):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscairoPlatformContextCairocpp">trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (159313 => 159314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2013-11-14 23:03:32 UTC (rev 159313)
+++ trunk/Source/WebCore/ChangeLog        2013-11-14 23:15:24 UTC (rev 159314)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2013-11-14  Aloisio Almeida Jr  &lt;aloisio.almeida@openbossa.org&gt;
+
+        [Cairo] Avoid extra copy when drawing images
+        https://bugs.webkit.org/show_bug.cgi?id=124209
+
+        Reviewed by Martin Robinson.
+
+        To solve the bug #58309 a cairo subsurface is being used to limit the
+        source image boundaries.
+        In many cases, when a cairo subsurface is used for drawing an image,
+        it occurs an image copy, causing performance penalty. In the case of
+        the function PlatformContextCairo::drawSurfaceToContext, the image
+        copy always happens.
+        So, we should use the subsurface only when it's really necessary.
+        In cases where we're drawing the whole image, the subsurface is
+        unnecessary.
+
+        The proposed patch avoid the use of subsurfaces when sampling the whole
+        image.
+
+        No new tests. It's an enhancement. Already covered by existing tests.
+
+        * platform/graphics/cairo/PlatformContextCairo.cpp:
+        (WebCore::PlatformContextCairo::drawSurfaceToContext):
+
</ins><span class="cx"> 2013-11-14  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Implement raw format for WebCrypto key export
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscairoPlatformContextCairocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp (159313 => 159314)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp        2013-11-14 23:03:32 UTC (rev 159313)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp        2013-11-14 23:15:24 UTC (rev 159314)
</span><span class="lines">@@ -172,15 +172,26 @@
</span><span class="cx">         srcRect.setHeight(std::fabs(originalSrcRect.height()));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Cairo subsurfaces don't support floating point boundaries well, so we expand the rectangle.
-    IntRect expandedSrcRect(enclosingIntRect(srcRect));
</del><ins>+    cairo_surface_t* patternSurface = surface;
+    RefPtr&lt;cairo_surface_t&gt; subsurface;
+    float leftPadding = 0;
+    float topPadding = 0;
+    if (srcRect.x() || srcRect.y() || srcRect.size() == cairoSurfaceSize(surface)) {
+        // Cairo subsurfaces don't support floating point boundaries well, so we expand the rectangle.
+        IntRect expandedSrcRect(enclosingIntRect(srcRect));
</ins><span class="cx"> 
</span><del>-    // We use a subsurface here so that we don't end up sampling outside the originalSrcRect rectangle.
-    // See https://bugs.webkit.org/show_bug.cgi?id=58309
-    RefPtr&lt;cairo_surface_t&gt; subsurface = adoptRef(cairo_surface_create_for_rectangle(
-        surface, expandedSrcRect.x(), expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height()));
-    RefPtr&lt;cairo_pattern_t&gt; pattern = adoptRef(cairo_pattern_create_for_surface(subsurface.get()));
</del><ins>+        // We use a subsurface here so that we don't end up sampling outside the originalSrcRect rectangle.
+        // See https://bugs.webkit.org/show_bug.cgi?id=58309
+        subsurface = adoptRef(cairo_surface_create_for_rectangle(surface, expandedSrcRect.x(),
+            expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height()));
+        patternSurface = subsurface.get();
</ins><span class="cx"> 
</span><ins>+        leftPadding = static_cast&lt;float&gt;(expandedSrcRect.x()) - floorf(srcRect.x());
+        topPadding = static_cast&lt;float&gt;(expandedSrcRect.y()) - floorf(srcRect.y());
+    }
+
+    RefPtr&lt;cairo_pattern_t&gt; pattern = adoptRef(cairo_pattern_create_for_surface(patternSurface));
+
</ins><span class="cx">     ASSERT(m_state);
</span><span class="cx">     switch (m_state-&gt;m_imageInterpolationQuality) {
</span><span class="cx">     case InterpolationNone:
</span><span class="lines">@@ -203,8 +214,6 @@
</span><span class="cx">     // of the scale since the original width and height might be negative.
</span><span class="cx">     float scaleX = std::fabs(srcRect.width() / destRect.width());
</span><span class="cx">     float scaleY = std::fabs(srcRect.height() / destRect.height());
</span><del>-    float leftPadding = static_cast&lt;float&gt;(expandedSrcRect.x()) - floorf(srcRect.x());
-    float topPadding = static_cast&lt;float&gt;(expandedSrcRect.y()) - floorf(srcRect.y());
</del><span class="cx">     cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding };
</span><span class="cx">     cairo_pattern_set_matrix(pattern.get(), &amp;matrix);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>