Changeset 173394 in webkit


Ignore:
Timestamp:
Sep 8, 2014 1:01:43 PM (10 years ago)
Author:
Antti Koivisto
Message:

Buffer images on web process side
https://bugs.webkit.org/show_bug.cgi?id=136631

Reviewed by Darin Adler.

We can substantially reduce IPC and decoding time for large images by allowing some buffering.

This patch makes us buffer image data up to 0.5s before sending it over to the web process.

  • NetworkProcess/NetworkResourceLoader.cpp:

(WebKit::NetworkResourceLoader::NetworkResourceLoader):
(WebKit::NetworkResourceLoader::cleanup):
(WebKit::NetworkResourceLoader::didReceiveBuffer):

Start the timer.

(WebKit::NetworkResourceLoader::didFinishLoading):
(WebKit::NetworkResourceLoader::startBufferingTimerIfNeeded):
(WebKit::NetworkResourceLoader::bufferingTimerFired):
(WebKit::NetworkResourceLoader::sendBuffer):

Send the data when the timer fires or the load finishes, whichever happens first.

  • NetworkProcess/NetworkResourceLoader.h:
  • Platform/IPC/ArgumentCoders.h:

Support encoding std::chrono::duration

  • Shared/Network/NetworkResourceLoadParameters.cpp:

(WebKit::NetworkResourceLoadParameters::NetworkResourceLoadParameters):
(WebKit::NetworkResourceLoadParameters::encode):
(WebKit::NetworkResourceLoadParameters::decode):

  • Shared/Network/NetworkResourceLoadParameters.h:

Pass maximimum buffering duration.

  • WebProcess/Network/WebResourceLoadScheduler.cpp:

(WebKit::maximumBufferingTime):

Deterimine duration from the resource type.
Enabled full buffering for font resources. They are not decoded incrementally.

(WebKit::WebResourceLoadScheduler::scheduleLoad):

Location:
trunk/Source/WebKit2
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r173393 r173394  
     12014-09-08  Antti Koivisto  <antti@apple.com>
     2
     3        Buffer images on web process side
     4        https://bugs.webkit.org/show_bug.cgi?id=136631
     5
     6        Reviewed by Darin Adler.
     7
     8        We can substantially reduce IPC and decoding time for large images by allowing some buffering.
     9
     10        This patch makes us buffer image data up to 0.5s before sending it over to the web process.
     11
     12        * NetworkProcess/NetworkResourceLoader.cpp:
     13        (WebKit::NetworkResourceLoader::NetworkResourceLoader):
     14        (WebKit::NetworkResourceLoader::cleanup):
     15        (WebKit::NetworkResourceLoader::didReceiveBuffer):
     16
     17            Start the timer.
     18
     19        (WebKit::NetworkResourceLoader::didFinishLoading):
     20        (WebKit::NetworkResourceLoader::startBufferingTimerIfNeeded):
     21        (WebKit::NetworkResourceLoader::bufferingTimerFired):
     22        (WebKit::NetworkResourceLoader::sendBuffer):
     23
     24            Send the data when the timer fires or the load finishes, whichever happens first.
     25
     26        * NetworkProcess/NetworkResourceLoader.h:
     27        * Platform/IPC/ArgumentCoders.h:
     28
     29            Support encoding std::chrono::duration
     30
     31        * Shared/Network/NetworkResourceLoadParameters.cpp:
     32        (WebKit::NetworkResourceLoadParameters::NetworkResourceLoadParameters):
     33        (WebKit::NetworkResourceLoadParameters::encode):
     34        (WebKit::NetworkResourceLoadParameters::decode):
     35        * Shared/Network/NetworkResourceLoadParameters.h:
     36
     37            Pass maximimum buffering duration.
     38
     39        * WebProcess/Network/WebResourceLoadScheduler.cpp:
     40        (WebKit::maximumBufferingTime):
     41
     42            Deterimine duration from the resource type.
     43            Enabled full buffering for font resources. They are not decoded incrementally.
     44
     45        (WebKit::WebResourceLoadScheduler::scheduleLoad):
     46
    1472014-09-08  Dan Bernstein  <mitz@apple.com>
    248
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp

    r173115 r173394  
    8484}
    8585
    86 NetworkResourceLoader::NetworkResourceLoader(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply)
     86NetworkResourceLoader::NetworkResourceLoader(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> synchronousReply)
    8787    : m_bytesReceived(0)
    8888    , m_handleConvertedToDownload(false)
     
    9898    , m_isLoadingMainResource(parameters.isMainResource)
    9999    , m_defersLoading(parameters.defersLoading)
     100    , m_maximumBufferingTime(parameters.maximumBufferingTime)
     101    , m_bufferingTimer(this, &NetworkResourceLoader::bufferingTimerFired)
    100102    , m_sandboxExtensionsAreConsumed(false)
    101103    , m_connection(connection)
     104    , m_bufferedDataEncodedDataLength(0)
    102105{
    103106    // Either this loader has both a webPageID and webFrameID, or it is not allowed to ask the client for authentication credentials.
     
    128131    ASSERT(RunLoop::isMain());
    129132   
    130     if (reply || parameters.shouldBufferResource)
     133    if (synchronousReply || m_maximumBufferingTime > 0_ms)
    131134        m_bufferedData = WebCore::SharedBuffer::create();
    132135
    133     if (reply)
    134         m_synchronousLoadData = std::make_unique<SynchronousLoadData>(m_request, reply);
     136    if (synchronousReply)
     137        m_synchronousLoadData = std::make_unique<SynchronousLoadData>(m_request, synchronousReply);
    135138}
    136139
     
    184187    ASSERT(RunLoop::isMain());
    185188
     189    m_bufferingTimer.stop();
     190
    186191    invalidateSandboxExtensions();
    187192
     
    239244}
    240245
    241 void NetworkResourceLoader::didReceiveBuffer(ResourceHandle* handle, PassRefPtr<SharedBuffer> buffer, int encodedDataLength)
    242 {
    243     ASSERT_UNUSED(handle, handle == m_handle);
     246void NetworkResourceLoader::didReceiveBuffer(ResourceHandle* handle, PassRefPtr<SharedBuffer> buffer, int reportedEncodedDataLength)
     247{
     248    ASSERT_UNUSED(handle, handle == m_handle);
     249
     250    // FIXME: At least on OS X Yosemite we always get -1 from the resource handle.
     251    unsigned encodedDataLength = reportedEncodedDataLength >= 0 ? reportedEncodedDataLength : buffer->size();
    244252
    245253    m_bytesReceived += buffer->size();
    246254    if (m_bufferedData) {
    247255        m_bufferedData->append(buffer.get());
     256        m_bufferedDataEncodedDataLength += encodedDataLength;
     257        startBufferingTimerIfNeeded();
    248258        return;
    249259    }
     
    259269    else {
    260270        if (m_bufferedData && m_bufferedData->size())
    261             sendBuffer(m_bufferedData.get(), m_bufferedData->size());
     271            sendBuffer(m_bufferedData.get(), -1);
    262272        send(Messages::WebResourceLoader::DidFinishResourceLoad(finishTime));
    263273    }
     
    400410}
    401411
     412void NetworkResourceLoader::startBufferingTimerIfNeeded()
     413{
     414    if (isSynchronous())
     415        return;
     416    if (m_bufferingTimer.isActive())
     417        return;
     418    m_bufferingTimer.startOneShot(m_maximumBufferingTime);
     419}
     420
     421void NetworkResourceLoader::bufferingTimerFired(Timer<NetworkResourceLoader>&)
     422{
     423    ASSERT(m_bufferedData);
     424    ASSERT(m_handle);
     425    if (!m_bufferedData->size())
     426        return;
     427
     428    IPC::SharedBufferDataReference dataReference(m_bufferedData.get());
     429    sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveData(dataReference, m_bufferedDataEncodedDataLength));
     430
     431    m_bufferedData = WebCore::SharedBuffer::create();
     432    m_bufferedDataEncodedDataLength = 0;
     433}
     434
    402435void NetworkResourceLoader::sendBuffer(WebCore::SharedBuffer* buffer, int encodedDataLength)
    403436{
  • trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h

    r173115 r173394  
    3939#include <WebCore/ResourceResponse.h>
    4040#include <WebCore/SessionID.h>
     41#include <WebCore/Timer.h>
    4142#include <wtf/MainThread.h>
    4243#include <wtf/RunLoop.h>
     
    162163    void platformDidReceiveResponse(const WebCore::ResourceResponse&);
    163164
     165    void startBufferingTimerIfNeeded();
     166    void bufferingTimerFired(WebCore::Timer<NetworkResourceLoader>&);
    164167    void sendBuffer(WebCore::SharedBuffer*, int encodedDataLength);
    165168
     
    191194    bool m_isLoadingMainResource;
    192195    bool m_defersLoading;
     196    const std::chrono::milliseconds m_maximumBufferingTime;
     197
     198    WebCore::Timer<NetworkResourceLoader> m_bufferingTimer;
    193199
    194200    Vector<RefPtr<SandboxExtension>> m_requestBodySandboxExtensions;
     
    200206   
    201207    RefPtr<WebCore::SharedBuffer> m_bufferedData;
     208    size_t m_bufferedDataEncodedDataLength;
    202209};
    203210
  • trunk/Source/WebKit2/Platform/IPC/ArgumentCoders.h

    r170774 r173394  
    105105};
    106106
     107template<typename Rep, typename Period> struct ArgumentCoder<std::chrono::duration<Rep, Period>> {
     108    static void encode(ArgumentEncoder& encoder, const std::chrono::duration<Rep, Period>& duration)
     109    {
     110        encoder << duration.count();
     111    }
     112
     113    static bool decode(ArgumentDecoder& decoder, std::chrono::duration<Rep, Period>& result)
     114    {
     115        Rep count;
     116        if (!decoder.decode(count))
     117            return false;
     118        result = std::chrono::duration<Rep, Period>(count);
     119        return true;
     120    }
     121};
     122
    107123template<typename KeyType, typename ValueType> struct ArgumentCoder<WTF::KeyValuePair<KeyType, ValueType>> {
    108124    static void encode(ArgumentEncoder& encoder, const WTF::KeyValuePair<KeyType, ValueType>& pair)
  • trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.cpp

    r172946 r173394  
    4848    , isMainResource(false)
    4949    , defersLoading(false)
    50     , shouldBufferResource(false)
     50    , maximumBufferingTime(0_ms)
    5151{
    5252}
     
    9696    encoder << isMainResource;
    9797    encoder << defersLoading;
    98     encoder << shouldBufferResource;
     98    encoder << maximumBufferingTime;
    9999}
    100100
     
    147147    if (!decoder.decode(result.defersLoading))
    148148        return false;
    149     if (!decoder.decode(result.shouldBufferResource))
     149    if (!decoder.decode(result.maximumBufferingTime))
    150150        return false;
    151151
  • trunk/Source/WebKit2/Shared/Network/NetworkResourceLoadParameters.h

    r172946 r173394  
    6464    bool isMainResource;
    6565    bool defersLoading;
    66     bool shouldBufferResource;
     66    std::chrono::milliseconds maximumBufferingTime;
    6767};
    6868
  • trunk/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.cpp

    r172946 r173394  
    8686}
    8787
     88static std::chrono::milliseconds maximumBufferingTime(CachedResource* resource)
     89{
     90    if (!resource)
     91        return 0_ms;
     92
     93    switch (resource->type()) {
     94    case CachedResource::CSSStyleSheet:
     95    case CachedResource::Script:
     96    case CachedResource::FontResource:
     97        return std::chrono::milliseconds::max();
     98    case CachedResource::ImageResource:
     99        return 500_ms;
     100    case CachedResource::MainResource:
     101    case CachedResource::RawResource:
     102    case CachedResource::SVGDocumentResource:
     103#if ENABLE(LINK_PREFETCH)
     104    case CachedResource::LinkPrefetch:
     105    case CachedResource::LinkSubresource:
     106#endif
     107#if ENABLE(VIDEO_TRACK)
     108    case CachedResource::TextTrackResource:
     109#endif
     110#if ENABLE(XSLT)
     111    case CachedResource::XSLStyleSheet:
     112#endif
     113        return 0_ms;
     114    }
     115}
     116
    88117void WebResourceLoadScheduler::scheduleLoad(ResourceLoader* resourceLoader, CachedResource* resource, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
    89118{
     
    142171    loadParameters.isMainResource = resource && resource->type() == CachedResource::MainResource;
    143172    loadParameters.defersLoading = resourceLoader->defersLoading();
    144     loadParameters.shouldBufferResource = resource && (resource->type() == CachedResource::CSSStyleSheet || resource->type() == CachedResource::Script);
     173    loadParameters.maximumBufferingTime = maximumBufferingTime(resource);
    145174
    146175    ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == DoNotAskClientForAnyCredentials);
Note: See TracChangeset for help on using the changeset viewer.