<!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>[223091] 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/223091">223091</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2017-10-09 17:07:48 -0700 (Mon, 09 Oct 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Image data should be coalesced if it comes in small chunks before updating the ImageSource
https://bugs.webkit.org/show_bug.cgi?id=175890

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2017-10-09
Reviewed by Simon Fraser.

Coalesce the updates, which an Image makes when receiving encoded data in
small chunks, for all platforms. Ensure the clients of the CachedImage
won't be notified unless an update in the ImageSource happens.

I need to change some functions' names to better implement this patch.
The names of these functions have been confusing:
    CachedImage::addData(SharedBuffer&)
    CachedImage::addDataBuffer(const char* data, unsigned)
    CachedImage::addIncrementalDataBuffer(SharedBuffer&)

The image data is not buffered incrementally into the CachedImage. When
new data is received, SubresourceLoader calls CachedImage to "update" its
m_data with either a SharedBuffer or a data pointer. In either case the
SharedBuffer or the pointer contains all the loaded data. SubresourceLoader
calls CachedImage to update its m_data, to ensure its m_image is created
and to notify its clients with the new data.

The verb "add" in the functions' name is misleading. I am suggesting the
following names instead:
    CachedImage::updateBuffer(SharedBuffer&)
    CachedImage::updateData(const char*, unsigned)
    CachedImage::doUpdateBuffer(SharedBuffer&)

The first two are the virtual ones. They are called form SubresourceLoader.
The third one is the internal implementation to update the m_data member.
The same names will be used in the following classes:
    CachedResource which is the base class of CachedImage
    CachedRawResource which is derived from CachedResource
    CachedTextTrack which is derived from CachedResource

* html/ImageDocument.cpp:
(WebCore::ImageDocument::updateDuringParsing):
* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::didReceiveDataOrBuffer):
* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::clearImage): Reset the update back off members.
(WebCore::CachedImage::doUpdateBuffer): Don't update CachedImage with
the new data if it comes in small chunks with fast rate.
(WebCore::CachedImage::shouldDeferUpdateImageData const): This code is moved
from ImageSource::dataChanged().
(WebCore::CachedImage::didUpdateImageData): Ditto.
(WebCore::CachedImage::updateImageData):
(WebCore::CachedImage::updateBuffer):
(WebCore::CachedImage::updateData):
(WebCore::CachedImage::finishLoading):
(WebCore::CachedImage::addIncrementalDataBuffer): Deleted.
(WebCore::CachedImage::setImageDataBuffer): Deleted.
(WebCore::CachedImage::addDataBuffer): Deleted.
(WebCore::CachedImage::addData): Deleted.
* loader/cache/CachedImage.h:
* loader/cache/CachedRawResource.cpp:
(WebCore::CachedRawResource::updateBuffer):
(WebCore::CachedRawResource::updateData):
(WebCore::CachedRawResource::addDataBuffer): Deleted.
(WebCore::CachedRawResource::addData): Deleted.
* loader/cache/CachedRawResource.h:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::updateBuffer):
(WebCore::CachedResource::updateData):
(WebCore::CachedResource::addDataBuffer): Deleted.
(WebCore::CachedResource::addData): Deleted.
* loader/cache/CachedResource.h:
* loader/cache/CachedTextTrack.cpp:
(WebCore::CachedTextTrack::doUpdateBuffer): Rename updateData() to doUpdateBuffer().
(WebCore::CachedTextTrack::updateBuffer): Rename addDataBuffer() to updateBuffer().
(WebCore::CachedTextTrack::finishLoading): Call the internal function doUpdateBuffer().
(WebCore::CachedTextTrack::updateData): Deleted.
(WebCore::CachedTextTrack::addDataBuffer): Deleted.
* loader/cache/CachedTextTrack.h:
* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::dataChanged): Move the update back off code to CachedImage::updateData().
* platform/graphics/ImageSource.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorehtmlImageDocumentcpp">trunk/Source/WebCore/html/ImageDocument.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderSubresourceLoadercpp">trunk/Source/WebCore/loader/SubresourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImagecpp">trunk/Source/WebCore/loader/cache/CachedImage.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImageh">trunk/Source/WebCore/loader/cache/CachedImage.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedRawResourcecpp">trunk/Source/WebCore/loader/cache/CachedRawResource.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedRawResourceh">trunk/Source/WebCore/loader/cache/CachedRawResource.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourcecpp">trunk/Source/WebCore/loader/cache/CachedResource.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceh">trunk/Source/WebCore/loader/cache/CachedResource.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedTextTrackcpp">trunk/Source/WebCore/loader/cache/CachedTextTrack.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedTextTrackh">trunk/Source/WebCore/loader/cache/CachedTextTrack.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageSourcecpp">trunk/Source/WebCore/platform/graphics/ImageSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageSourceh">trunk/Source/WebCore/platform/graphics/ImageSource.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/ChangeLog      2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -1,3 +1,83 @@
</span><ins>+2017-10-09  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Image data should be coalesced if it comes in small chunks before updating the ImageSource
+        https://bugs.webkit.org/show_bug.cgi?id=175890
+
+        Reviewed by Simon Fraser.
+
+        Coalesce the updates, which an Image makes when receiving encoded data in
+        small chunks, for all platforms. Ensure the clients of the CachedImage
+        won't be notified unless an update in the ImageSource happens.
+
+        I need to change some functions' names to better implement this patch. 
+        The names of these functions have been confusing:
+            CachedImage::addData(SharedBuffer&)
+            CachedImage::addDataBuffer(const char* data, unsigned)
+            CachedImage::addIncrementalDataBuffer(SharedBuffer&)
+
+        The image data is not buffered incrementally into the CachedImage. When
+        new data is received, SubresourceLoader calls CachedImage to "update" its
+        m_data with either a SharedBuffer or a data pointer. In either case the
+        SharedBuffer or the pointer contains all the loaded data. SubresourceLoader
+        calls CachedImage to update its m_data, to ensure its m_image is created 
+        and to notify its clients with the new data.
+
+        The verb "add" in the functions' name is misleading. I am suggesting the
+        following names instead:
+            CachedImage::updateBuffer(SharedBuffer&)
+            CachedImage::updateData(const char*, unsigned)
+            CachedImage::doUpdateBuffer(SharedBuffer&)
+
+        The first two are the virtual ones. They are called form SubresourceLoader.
+        The third one is the internal implementation to update the m_data member.
+        The same names will be used in the following classes:
+            CachedResource which is the base class of CachedImage
+            CachedRawResource which is derived from CachedResource
+            CachedTextTrack which is derived from CachedResource
+
+        * html/ImageDocument.cpp:
+        (WebCore::ImageDocument::updateDuringParsing):
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::didReceiveDataOrBuffer):
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::clearImage): Reset the update back off members.
+        (WebCore::CachedImage::doUpdateBuffer): Don't update CachedImage with
+        the new data if it comes in small chunks with fast rate.
+        (WebCore::CachedImage::shouldDeferUpdateImageData const): This code is moved 
+        from ImageSource::dataChanged().
+        (WebCore::CachedImage::didUpdateImageData): Ditto.
+        (WebCore::CachedImage::updateImageData):
+        (WebCore::CachedImage::updateBuffer):
+        (WebCore::CachedImage::updateData):
+        (WebCore::CachedImage::finishLoading):
+        (WebCore::CachedImage::addIncrementalDataBuffer): Deleted.
+        (WebCore::CachedImage::setImageDataBuffer): Deleted.
+        (WebCore::CachedImage::addDataBuffer): Deleted.
+        (WebCore::CachedImage::addData): Deleted.
+        * loader/cache/CachedImage.h:
+        * loader/cache/CachedRawResource.cpp:
+        (WebCore::CachedRawResource::updateBuffer):
+        (WebCore::CachedRawResource::updateData):
+        (WebCore::CachedRawResource::addDataBuffer): Deleted.
+        (WebCore::CachedRawResource::addData): Deleted.
+        * loader/cache/CachedRawResource.h:
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::updateBuffer):
+        (WebCore::CachedResource::updateData):
+        (WebCore::CachedResource::addDataBuffer): Deleted.
+        (WebCore::CachedResource::addData): Deleted.
+        * loader/cache/CachedResource.h:
+        * loader/cache/CachedTextTrack.cpp:
+        (WebCore::CachedTextTrack::doUpdateBuffer): Rename updateData() to doUpdateBuffer().
+        (WebCore::CachedTextTrack::updateBuffer): Rename addDataBuffer() to updateBuffer().
+        (WebCore::CachedTextTrack::finishLoading): Call the internal function doUpdateBuffer().
+        (WebCore::CachedTextTrack::updateData): Deleted.
+        (WebCore::CachedTextTrack::addDataBuffer): Deleted.
+        * loader/cache/CachedTextTrack.h:
+        * platform/graphics/ImageSource.cpp:
+        (WebCore::ImageSource::dataChanged): Move the update back off code to CachedImage::updateData().
+        * platform/graphics/ImageSource.h:
+
</ins><span class="cx"> 2017-10-09  Michael Saboff  <msaboff@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Implement RegExp Unicode property escapes
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlImageDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/ImageDocument.cpp (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/ImageDocument.cpp      2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/html/ImageDocument.cpp 2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx">         createDocumentStructure();
</span><span class="cx"> 
</span><span class="cx">     if (RefPtr<SharedBuffer> buffer = loader()->mainResourceData())
</span><del>-        m_imageElement->cachedImage()->addDataBuffer(*buffer);
</del><ins>+        m_imageElement->cachedImage()->updateBuffer(*buffer);
</ins><span class="cx"> 
</span><span class="cx">     imageUpdated();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderSubresourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/SubresourceLoader.cpp        2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp   2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -403,9 +403,9 @@
</span><span class="cx"> 
</span><span class="cx">     if (!m_loadingMultipartContent) {
</span><span class="cx">         if (auto* resourceData = this->resourceData())
</span><del>-            m_resource->addDataBuffer(*resourceData);
</del><ins>+            m_resource->updateBuffer(*resourceData);
</ins><span class="cx">         else
</span><del>-            m_resource->addData(buffer ? buffer->data() : data, buffer ? buffer->size() : length);
</del><ins>+            m_resource->updateData(buffer ? buffer->data() : data, buffer ? buffer->size() : length);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedImage.cpp        2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp   2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -404,18 +404,25 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_image = nullptr;
</span><ins>+    m_lastUpdateImageDataTime = { };
+    m_updateImageDataCount = 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedImage::addIncrementalDataBuffer(SharedBuffer& data)
</del><ins>+void CachedImage::updateBufferInternal(SharedBuffer& data)
</ins><span class="cx"> {
</span><span class="cx">     m_data = &data;
</span><del>-
</del><span class="cx">     createImage();
</span><ins>+    setEncodedSize(m_image->data() ? m_image->data()->size() : 0);
</ins><span class="cx"> 
</span><del>-    // Have the image update its data from its internal buffer.
-    // It will not do anything now, but will delay decoding until
-    // queried for info (like size or specific image frames).
-    EncodedDataStatus encodedDataStatus = setImageDataBuffer(&data, false);
</del><ins>+    // Don't update the image with the new buffer very often. Changing the decoder
+    // internal data and repainting the observers sometimes are very expensive operations.
+    if (shouldDeferUpdateImageData())
+        return;
+    
+    // Have the image update its data from its internal buffer. Decoding the image data
+    // will be delayed until info (like size or specific image frames) are queried which
+    // usually happens when the observers are repainted.
+    EncodedDataStatus encodedDataStatus = updateImageData(&data, false);
</ins><span class="cx">     if (encodedDataStatus > EncodedDataStatus::Error && encodedDataStatus < EncodedDataStatus::SizeAvailable)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -430,31 +437,46 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Tell our observers to try to draw.
</span><del>-    // Each chunk from the network causes observers to repaint, which will force that chunk to decode.
-    // It would be nice to only redraw the decoded band of the image, but with the current design
-    // (decoding delayed until painting) that seems hard.
</del><span class="cx">     notifyObservers();
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    setEncodedSize(m_image->data() ? m_image->data()->size() : 0);
</del><ins>+bool CachedImage::shouldDeferUpdateImageData() const
+{
+    static const double updateImageDataBackoffIntervals[] = { 0, 1, 3, 6, 15 };
+    unsigned interval = std::min<unsigned>(m_updateImageDataCount, 4);
+
+    // The first time through, the chunk time will be 0 and the image will get an update.
+    return (MonotonicTime::now() - m_lastUpdateImageDataTime).seconds() < updateImageDataBackoffIntervals[interval];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-EncodedDataStatus CachedImage::setImageDataBuffer(SharedBuffer* data, bool allDataReceived)
</del><ins>+void CachedImage::didUpdateImageData()
</ins><span class="cx"> {
</span><del>-    return m_image ? m_image->setData(data, allDataReceived) : EncodedDataStatus::Error;
</del><ins>+    m_lastUpdateImageDataTime = MonotonicTime::now();
+    ASSERT(m_updateImageDataCount < std::numeric_limits<unsigned>::max());
+    ++m_updateImageDataCount;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedImage::addDataBuffer(SharedBuffer& data)
</del><ins>+EncodedDataStatus CachedImage::updateImageData(SharedBuffer* data, bool allDataReceived)
</ins><span class="cx"> {
</span><ins>+    if (!m_image)
+        return EncodedDataStatus::Error;
+    EncodedDataStatus result = m_image->setData(data, allDataReceived);
+    didUpdateImageData();
+    return result;
+}
+
+void CachedImage::updateBuffer(SharedBuffer& data)
+{
</ins><span class="cx">     ASSERT(dataBufferingPolicy() == BufferData);
</span><del>-    addIncrementalDataBuffer(data);
-    CachedResource::addDataBuffer(data);
</del><ins>+    updateBufferInternal(data);
+    CachedResource::updateBuffer(data);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedImage::addData(const char* data, unsigned length)
</del><ins>+void CachedImage::updateData(const char* data, unsigned length)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(dataBufferingPolicy() == DoNotBufferData);
</span><del>-    addIncrementalDataBuffer(SharedBuffer::create(data, length));
-    CachedResource::addData(data, length);
</del><ins>+    updateBufferInternal(SharedBuffer::create(data, length));
+    CachedResource::updateData(data, length);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CachedImage::finishLoading(SharedBuffer* data)
</span><span class="lines">@@ -463,7 +485,7 @@
</span><span class="cx">     if (!m_image && data)
</span><span class="cx">         createImage();
</span><span class="cx"> 
</span><del>-    EncodedDataStatus encodedDataStatus = setImageDataBuffer(data, true);
</del><ins>+    EncodedDataStatus encodedDataStatus = updateImageData(data, true);
</ins><span class="cx"> 
</span><span class="cx">     if (encodedDataStatus == EncodedDataStatus::Error || m_image->isNull()) {
</span><span class="cx">         // Image decoding failed; the image data is malformed.
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.h (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedImage.h  2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedImage.h     2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">     bool imageHasRelativeWidth() const { return m_image && m_image->hasRelativeWidth(); }
</span><span class="cx">     bool imageHasRelativeHeight() const { return m_image && m_image->hasRelativeHeight(); }
</span><span class="cx"> 
</span><del>-    void addDataBuffer(SharedBuffer&) override;
</del><ins>+    void updateBuffer(SharedBuffer&) override;
</ins><span class="cx">     void finishLoading(SharedBuffer*) override;
</span><span class="cx"> 
</span><span class="cx">     enum SizeType {
</span><span class="lines">@@ -109,8 +109,10 @@
</span><span class="cx">     void allClientsRemoved() override;
</span><span class="cx">     void destroyDecodedData() override;
</span><span class="cx"> 
</span><del>-    EncodedDataStatus setImageDataBuffer(SharedBuffer*, bool allDataReceived);
-    void addData(const char* data, unsigned length) override;
</del><ins>+    bool shouldDeferUpdateImageData() const;
+    void didUpdateImageData();
+    EncodedDataStatus updateImageData(SharedBuffer*, bool allDataReceived);
+    void updateData(const char* data, unsigned length) override;
</ins><span class="cx">     void error(CachedResource::Status) override;
</span><span class="cx">     void responseReceived(const ResourceResponse&) override;
</span><span class="cx"> 
</span><span class="lines">@@ -149,7 +151,7 @@
</span><span class="cx">     void imageFrameAvailable(const Image&, ImageAnimatingState, const IntRect* changeRect = nullptr, DecodingStatus = DecodingStatus::Invalid);
</span><span class="cx">     void changedInRect(const Image&, const IntRect*);
</span><span class="cx"> 
</span><del>-    void addIncrementalDataBuffer(SharedBuffer&);
</del><ins>+    void updateBufferInternal(SharedBuffer&);
</ins><span class="cx"> 
</span><span class="cx">     void didReplaceSharedBufferContents() override;
</span><span class="cx"> 
</span><span class="lines">@@ -166,6 +168,9 @@
</span><span class="cx"> 
</span><span class="cx">     RefPtr<CachedImageObserver> m_imageObserver;
</span><span class="cx">     RefPtr<Image> m_image;
</span><ins>+    MonotonicTime m_lastUpdateImageDataTime;
+    unsigned m_updateImageDataCount { 0 };
+
</ins><span class="cx">     std::unique_ptr<SVGImageCache> m_svgImageCache;
</span><span class="cx">     bool m_isManuallyCached { false };
</span><span class="cx">     bool m_shouldPaintBrokenImage { true };
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedRawResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedRawResource.cpp (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedRawResource.cpp  2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedRawResource.cpp     2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">     return data->getSomeData(previousDataLength);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedRawResource::addDataBuffer(SharedBuffer& data)
</del><ins>+void CachedRawResource::updateBuffer(SharedBuffer& data)
</ins><span class="cx"> {
</span><span class="cx">     CachedResourceHandle<CachedRawResource> protectedThis(this);
</span><span class="cx">     ASSERT(dataBufferingPolicy() == BufferData);
</span><span class="lines">@@ -69,14 +69,14 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    CachedResource::addDataBuffer(data);
</del><ins>+    CachedResource::updateBuffer(data);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedRawResource::addData(const char* data, unsigned length)
</del><ins>+void CachedRawResource::updateData(const char* data, unsigned length)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(dataBufferingPolicy() == DoNotBufferData);
</span><span class="cx">     notifyClientsDataWasReceived(data, length);
</span><del>-    CachedResource::addData(data, length);
</del><ins>+    CachedResource::updateData(data, length);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CachedRawResource::finishLoading(SharedBuffer* data)
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedRawResourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedRawResource.h (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedRawResource.h    2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedRawResource.h       2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -55,8 +55,8 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void didAddClient(CachedResourceClient&) final;
</span><del>-    void addDataBuffer(SharedBuffer&) final;
-    void addData(const char* data, unsigned length) final;
</del><ins>+    void updateBuffer(SharedBuffer&) final;
+    void updateData(const char* data, unsigned length) final;
</ins><span class="cx">     void finishLoading(SharedBuffer*) final;
</span><span class="cx"> 
</span><span class="cx">     bool shouldIgnoreHTTPStatusCodeErrors() const override { return true; }
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.cpp     2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp        2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -342,12 +342,12 @@
</span><span class="cx">         client->notifyFinished(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedResource::addDataBuffer(SharedBuffer&)
</del><ins>+void CachedResource::updateBuffer(SharedBuffer&)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(dataBufferingPolicy() == BufferData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedResource::addData(const char*, unsigned)
</del><ins>+void CachedResource::updateData(const char*, unsigned)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(dataBufferingPolicy() == DoNotBufferData);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.h       2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedResource.h  2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -102,8 +102,8 @@
</span><span class="cx">     virtual void setEncoding(const String&) { }
</span><span class="cx">     virtual String encoding() const { return String(); }
</span><span class="cx">     virtual const TextResourceDecoder* textResourceDecoder() const { return nullptr; }
</span><del>-    virtual void addDataBuffer(SharedBuffer&);
-    virtual void addData(const char* data, unsigned length);
</del><ins>+    virtual void updateBuffer(SharedBuffer&);
+    virtual void updateData(const char* data, unsigned length);
</ins><span class="cx">     virtual void finishLoading(SharedBuffer*);
</span><span class="cx">     virtual void error(CachedResource::Status);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedTextTrackcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedTextTrack.cpp (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedTextTrack.cpp    2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedTextTrack.cpp       2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedTextTrack::updateData(SharedBuffer* data)
</del><ins>+void CachedTextTrack::doUpdateBuffer(SharedBuffer* data)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(dataBufferingPolicy() == BufferData);
</span><span class="cx">     m_data = data;
</span><span class="lines">@@ -53,15 +53,15 @@
</span><span class="cx">         client->deprecatedDidReceiveCachedResource(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CachedTextTrack::addDataBuffer(SharedBuffer& data)
</del><ins>+void CachedTextTrack::updateBuffer(SharedBuffer& data)
</ins><span class="cx"> {
</span><del>-    updateData(&data);
-    CachedResource::addDataBuffer(data);
</del><ins>+    doUpdateBuffer(&data);
+    CachedResource::updateBuffer(data);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CachedTextTrack::finishLoading(SharedBuffer* data)
</span><span class="cx"> {
</span><del>-    updateData(data);
</del><ins>+    doUpdateBuffer(data);
</ins><span class="cx">     CachedResource::finishLoading(data);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedTextTrackh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedTextTrack.h (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedTextTrack.h      2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/loader/cache/CachedTextTrack.h 2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -37,10 +37,10 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     bool mayTryReplaceEncodedData() const override { return true; }
</span><del>-    void addDataBuffer(SharedBuffer&) override;
</del><ins>+    void updateBuffer(SharedBuffer&) override;
</ins><span class="cx">     void finishLoading(SharedBuffer*) override;
</span><span class="cx"> 
</span><del>-    void updateData(SharedBuffer*);
</del><ins>+    void doUpdateBuffer(SharedBuffer*);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp   2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp      2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -113,34 +113,13 @@
</span><span class="cx"> 
</span><span class="cx"> EncodedDataStatus ImageSource::dataChanged(SharedBuffer* data, bool allDataReceived)
</span><span class="cx"> {
</span><del>-#if PLATFORM(IOS)
-    // FIXME: We should expose a setting to enable/disable progressive loading and make this
-    // code conditional on it. Then we can remove the PLATFORM(IOS)-guard.
-    static const double chunkLoadIntervals[] = {0, 1, 3, 6, 15};
-    double interval = chunkLoadIntervals[std::min(m_progressiveLoadChunkCount, static_cast<uint16_t>(4))];
-
-    bool needsUpdate = false;
-
-    // The first time through, the chunk time will be 0 and the image will get an update.
-    if (currentTime() - m_progressiveLoadChunkTime > interval) {
-        needsUpdate = true;
-        m_progressiveLoadChunkTime = currentTime();
-        ASSERT(m_progressiveLoadChunkCount <= std::numeric_limits<uint16_t>::max());
-        ++m_progressiveLoadChunkCount;
-    }
-
-    if (needsUpdate || allDataReceived)
-        setData(data, allDataReceived);
-#else
</del><span class="cx">     setData(data, allDataReceived);
</span><del>-#endif
</del><ins>+    m_frameCache->clearMetadata();
</ins><span class="cx"> 
</span><del>-    m_frameCache->clearMetadata();
</del><span class="cx">     EncodedDataStatus status = encodedDataStatus();
</span><del>-    if (status < EncodedDataStatus::SizeAvailable)
-        return status;
</del><ins>+    if (status >= EncodedDataStatus::SizeAvailable)
+        m_frameCache->growFrames();
</ins><span class="cx"> 
</span><del>-    m_frameCache->growFrames();
</del><span class="cx">     return status;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageSource.h (223090 => 223091)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageSource.h     2017-10-10 00:07:45 UTC (rev 223090)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h        2017-10-10 00:07:48 UTC (rev 223091)
</span><span class="lines">@@ -121,12 +121,6 @@
</span><span class="cx"> 
</span><span class="cx">     std::optional<SubsamplingLevel> m_maximumSubsamplingLevel;
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS)
-    // FIXME: We should expose a setting to enable/disable progressive loading so that we can remove the PLATFORM(IOS)-guard.
-    double m_progressiveLoadChunkTime { 0 };
-    uint16_t m_progressiveLoadChunkCount { 0 };
-#endif
-
</del><span class="cx">     AlphaOption m_alphaOption { AlphaOption::Premultiplied };
</span><span class="cx">     GammaAndColorProfileOption m_gammaAndColorProfileOption { GammaAndColorProfileOption::Applied };
</span><span class="cx"> };
</span></span></pre>
</div>
</div>

</body>
</html>