Changeset 80306 in webkit


Ignore:
Timestamp:
Mar 3, 2011 5:36:29 PM (13 years ago)
Author:
Adam Roben
Message:

Add a way to tell the web process to perform a full backing store update on its next paint

Messages::DrawingArea::UpdateBackingStoreState now takes a boolean specifying whether the
full backing store update should happen immediately or should be deferred until the next
paint or compositing mode change occurs. The deferred update isn't used yet, but will be
used when we start throwing away backing stores to save memory.

Fixes <http://webkit.org/b/55730> UI process needs a way to tell the web process its backing
store needs a full update on the next paint

Reviewed by Anders Carlsson.

  • UIProcess/DrawingAreaProxyImpl.cpp:

(WebKit::DrawingAreaProxyImpl::paint): If we have an outstanding backing store state change
request, tell the web process to perform the backing store update right away, in case we
previously told it it could defer the update.
(WebKit::DrawingAreaProxyImpl::sizeDidChange): Specify that we need an immediate backing
store update.
(WebKit::DrawingAreaProxyImpl::didUpdateBackingStoreState): We can no longer assert that we
were waiting for a DidUpdateBackingStoreState message when we receive one, as it's possible
for the web process to decide to send us this message on its own (if we asked it to do a
deferred backing store update and then it needed to paint some part of the page). Specify
that we need an immediate backing store update if the web process hasn't updated to our
latest state, as we're about to draw potentially out-of-date bits to the screen and want to
get the right bits as soon as possible. Also added a FIXME about a potential optimization.
(WebKit::DrawingAreaProxyImpl::backingStoreStateDidChange): Added a RespondImmediatelyOrNot
parameter, which is just passed through to sendUpdateBackingStoreState.
(WebKit::DrawingAreaProxyImpl::sendUpdateBackingStoreState): Added a RespondImmediatelyOrNot
parameter that is used to specify to the web process whether to perform the full backing
store update immediately. We now only wait for a DidUpdateBackingStoreState message (and
thus suppress any more UpdateBackingStoreState messages until one is received) when we ask
the web process for an immediate response; otherwise we could end up accidentally calling
waitForAndDispatchDidUpdateBackingStoreState when the web process hasn't been told to send
us such a message.

  • UIProcess/DrawingAreaProxyImpl.h: Added RespondImmediatelyOrNot.
  • WebProcess/WebPage/DrawingArea.h:

(WebKit::DrawingArea::updateBackingStoreState): Added respondImmediately argument.

  • WebProcess/WebPage/DrawingArea.messages.in: Added respondImmediately argument to

UpdateBackingStoreState message.

  • WebProcess/WebPage/DrawingAreaImpl.cpp:

(WebKit::DrawingAreaImpl::DrawingAreaImpl): Initialize new member that's used to track
whether we should send a DidUpdateBackingStoreState message instead of an Update or
compositing mode change message. This will be set to true when a deferred backing store
update is pending.
(WebKit::DrawingAreaImpl::layerHostDidFlushLayers): If a deferred update is pending, send a
DidUpdateBackingStoreState message instead of a compositing mode change message.
(WebKit::DrawingAreaImpl::updateBackingStoreState): Added respondImmediately argument. If
we've already been told about this state ID (as can happen when the UI process decides it
needs an immediate update to a state that it previously requested a deferred update to),
don't bother updating the page's size, etc. In addition, if we've already sent a
DidUpdateBackingStoreState message for this state, we don't have to do anything at all.
Moved code to send the DidUpdateBackingStoreState message from here...
(WebKit::DrawingAreaImpl::sendDidUpdateBackingStoreState): ...to here.
(WebKit::DrawingAreaImpl::exitAcceleratedCompositingMode): Always update our dirty region,
even if painting is suspended or we're in the process of updating the backing store state.
It causes no harm and simplifies the code. If a deferred update is pending, send a
DidUpdateBackingStoreState message instead of a compositing mode change message. Also
removed a redundant if.
(WebKit::DrawingAreaImpl::display): Added an assertion that this isn't called while updating
backing store state, as otherwise we might end up sending two DidUpdateBackingStoreState
messages. If a deferred update is pending, send a DidUpdateBackingStoreState message instead
of an Update message.

  • WebProcess/WebPage/DrawingAreaImpl.h: Updated updateBackingStoreState to match the base

class. Added sendDidUpdateBackingStoreState and m_shouldSendDidUpdateBackingStoreState.

Location:
trunk/Source/WebKit2
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r80297 r80306  
     12011-03-03  Adam Roben  <aroben@apple.com>
     2
     3        Add a way to tell the web process to perform a full backing store update on its next paint
     4
     5        Messages::DrawingArea::UpdateBackingStoreState now takes a boolean specifying whether the
     6        full backing store update should happen immediately or should be deferred until the next
     7        paint or compositing mode change occurs. The deferred update isn't used yet, but will be
     8        used when we start throwing away backing stores to save memory.
     9
     10        Fixes <http://webkit.org/b/55730> UI process needs a way to tell the web process its backing
     11        store needs a full update on the next paint
     12
     13        Reviewed by Anders Carlsson.
     14
     15        * UIProcess/DrawingAreaProxyImpl.cpp:
     16        (WebKit::DrawingAreaProxyImpl::paint): If we have an outstanding backing store state change
     17        request, tell the web process to perform the backing store update right away, in case we
     18        previously told it it could defer the update.
     19        (WebKit::DrawingAreaProxyImpl::sizeDidChange): Specify that we need an immediate backing
     20        store update.
     21        (WebKit::DrawingAreaProxyImpl::didUpdateBackingStoreState): We can no longer assert that we
     22        were waiting for a DidUpdateBackingStoreState message when we receive one, as it's possible
     23        for the web process to decide to send us this message on its own (if we asked it to do a
     24        deferred backing store update and then it needed to paint some part of the page). Specify
     25        that we need an immediate backing store update if the web process hasn't updated to our
     26        latest state, as we're about to draw potentially out-of-date bits to the screen and want to
     27        get the right bits as soon as possible. Also added a FIXME about a potential optimization.
     28        (WebKit::DrawingAreaProxyImpl::backingStoreStateDidChange): Added a RespondImmediatelyOrNot
     29        parameter, which is just passed through to sendUpdateBackingStoreState.
     30        (WebKit::DrawingAreaProxyImpl::sendUpdateBackingStoreState): Added a RespondImmediatelyOrNot
     31        parameter that is used to specify to the web process whether to perform the full backing
     32        store update immediately. We now only wait for a DidUpdateBackingStoreState message (and
     33        thus suppress any more UpdateBackingStoreState messages until one is received) when we ask
     34        the web process for an immediate response; otherwise we could end up accidentally calling
     35        waitForAndDispatchDidUpdateBackingStoreState when the web process hasn't been told to send
     36        us such a message.
     37
     38        * UIProcess/DrawingAreaProxyImpl.h: Added RespondImmediatelyOrNot.
     39
     40        * WebProcess/WebPage/DrawingArea.h:
     41        (WebKit::DrawingArea::updateBackingStoreState): Added respondImmediately argument.
     42
     43        * WebProcess/WebPage/DrawingArea.messages.in: Added respondImmediately argument to
     44        UpdateBackingStoreState message.
     45
     46        * WebProcess/WebPage/DrawingAreaImpl.cpp:
     47        (WebKit::DrawingAreaImpl::DrawingAreaImpl): Initialize new member that's used to track
     48        whether we should send a DidUpdateBackingStoreState message instead of an Update or
     49        compositing mode change message. This will be set to true when a deferred backing store
     50        update is pending.
     51        (WebKit::DrawingAreaImpl::layerHostDidFlushLayers): If a deferred update is pending, send a
     52        DidUpdateBackingStoreState message instead of a compositing mode change message.
     53        (WebKit::DrawingAreaImpl::updateBackingStoreState): Added respondImmediately argument. If
     54        we've already been told about this state ID (as can happen when the UI process decides it
     55        needs an immediate update to a state that it previously requested a deferred update to),
     56        don't bother updating the page's size, etc. In addition, if we've already sent a
     57        DidUpdateBackingStoreState message for this state, we don't have to do anything at all.
     58        Moved code to send the DidUpdateBackingStoreState message from here...
     59        (WebKit::DrawingAreaImpl::sendDidUpdateBackingStoreState): ...to here.
     60        (WebKit::DrawingAreaImpl::exitAcceleratedCompositingMode): Always update our dirty region,
     61        even if painting is suspended or we're in the process of updating the backing store state.
     62        It causes no harm and simplifies the code. If a deferred update is pending, send a
     63        DidUpdateBackingStoreState message instead of a compositing mode change message. Also
     64        removed a redundant if.
     65        (WebKit::DrawingAreaImpl::display): Added an assertion that this isn't called while updating
     66        backing store state, as otherwise we might end up sending two DidUpdateBackingStoreState
     67        messages. If a deferred update is pending, send a DidUpdateBackingStoreState message instead
     68        of an Update message.
     69
     70        * WebProcess/WebPage/DrawingAreaImpl.h: Updated updateBackingStoreState to match the base
     71        class. Added sendDidUpdateBackingStoreState and m_shouldSendDidUpdateBackingStoreState.
     72
    1732011-03-03  Andy Estes  <aestes@apple.com>
    274
  • trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp

    r79869 r80306  
    7272    ASSERT(!isInAcceleratedCompositingMode());
    7373
    74     if (m_isWaitingForDidUpdateBackingStoreState) {
    75         // Wait for a DidUpdateBackingStoreState message that contains the new bits before we paint
    76         // what's currently in the backing store.
    77         waitForAndDispatchDidUpdateBackingStoreState();
    78 
    79         // Dispatching DidUpdateBackingStoreState could destroy our backing store or change the compositing mode.
     74    ASSERT(m_currentBackingStoreStateID <= m_nextBackingStoreStateID);
     75    if (m_currentBackingStoreStateID < m_nextBackingStoreStateID) {
     76        // Tell the web process to do a full backing store update now, in case we previously told
     77        // it about our next state but didn't request an immediate update.
     78        sendUpdateBackingStoreState(RespondImmediately);
     79
     80        if (m_isWaitingForDidUpdateBackingStoreState) {
     81            // Wait for a DidUpdateBackingStoreState message that contains the new bits before we paint
     82            // what's currently in the backing store.
     83            waitForAndDispatchDidUpdateBackingStoreState();
     84        }
     85
     86        // Dispatching DidUpdateBackingStoreState (either beneath sendUpdateBackingStoreState or
     87        // beneath waitForAndDispatchDidUpdateBackingStoreState) could destroy our backing store or
     88        // change the compositing mode.
    8089        if (!m_backingStore || isInAcceleratedCompositingMode())
    8190            return;
    82     }
     91    } else
     92        ASSERT(!m_isWaitingForDidUpdateBackingStoreState);
    8393
    8494    m_backingStore->paint(context, rect);
     
    104114void DrawingAreaProxyImpl::sizeDidChange()
    105115{
    106     backingStoreStateDidChange();
     116    backingStoreStateDidChange(RespondImmediately);
    107117}
    108118
     
    141151    m_currentBackingStoreStateID = backingStoreStateID;
    142152
    143     ASSERT(m_isWaitingForDidUpdateBackingStoreState);
    144153    m_isWaitingForDidUpdateBackingStoreState = false;
    145154
    146155    if (m_nextBackingStoreStateID != m_currentBackingStoreStateID)
    147         sendUpdateBackingStoreState();
     156        sendUpdateBackingStoreState(RespondImmediately);
    148157
    149158    if (layerTreeContext != m_layerTreeContext) {
     
    164173    }
    165174
     175    // FIXME: We could just reuse our existing backing store if it's the same size as
     176    // updateInfo.viewSize.
    166177    m_backingStore = nullptr;
    167178    incorporateUpdate(updateInfo);
     
    215226}
    216227
    217 void DrawingAreaProxyImpl::backingStoreStateDidChange()
     228void DrawingAreaProxyImpl::backingStoreStateDidChange(RespondImmediatelyOrNot respondImmediatelyOrNot)
    218229{
    219230    ++m_nextBackingStoreStateID;
    220     sendUpdateBackingStoreState();
    221 }
    222 
    223 void DrawingAreaProxyImpl::sendUpdateBackingStoreState()
     231    sendUpdateBackingStoreState(respondImmediatelyOrNot);
     232}
     233
     234void DrawingAreaProxyImpl::sendUpdateBackingStoreState(RespondImmediatelyOrNot respondImmediatelyOrNot)
    224235{
    225236    ASSERT(m_currentBackingStoreStateID < m_nextBackingStoreStateID);
     
    231242        return;
    232243
    233     m_isWaitingForDidUpdateBackingStoreState = true;
    234     m_webPageProxy->process()->send(Messages::DrawingArea::UpdateBackingStoreState(m_nextBackingStoreStateID, m_size, m_scrollOffset), m_webPageProxy->pageID());
     244    m_isWaitingForDidUpdateBackingStoreState = respondImmediatelyOrNot == RespondImmediately;
     245    m_webPageProxy->process()->send(Messages::DrawingArea::UpdateBackingStoreState(m_nextBackingStoreStateID, respondImmediatelyOrNot == RespondImmediately, m_size, m_scrollOffset), m_webPageProxy->pageID());
    235246    m_scrollOffset = IntSize();
    236247
    237     if (!m_layerTreeContext.isEmpty()) {
     248    if (m_isWaitingForDidUpdateBackingStoreState && !m_layerTreeContext.isEmpty()) {
    238249        // Wait for the DidUpdateBackingStoreState message. Normally we don this in DrawingAreaProxyImpl::paint, but that
    239250        // function is never called when in accelerated compositing mode.
  • trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h

    r79869 r80306  
    6363    void incorporateUpdate(const UpdateInfo&);
    6464
    65     void backingStoreStateDidChange();
    66     void sendUpdateBackingStoreState();
     65    enum RespondImmediatelyOrNot { DoNotRespondImmediately, RespondImmediately };
     66    void backingStoreStateDidChange(RespondImmediatelyOrNot);
     67    void sendUpdateBackingStoreState(RespondImmediatelyOrNot);
    6768    void waitForAndDispatchDidUpdateBackingStoreState();
    6869
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h

    r79868 r80306  
    8787    // CoreIPC message handlers.
    8888    // FIXME: These should be pure virtual.
    89     virtual void updateBackingStoreState(uint64_t backingStoreStateID, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset) { }
     89    virtual void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset) { }
    9090    virtual void didUpdate() { }
    9191    virtual void suspendPainting() { }
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in

    r79868 r80306  
    2222
    2323messages -> DrawingArea {
    24     UpdateBackingStoreState(uint64_t backingStoreStateID, WebCore::IntSize size, WebCore::IntSize scrollOffset)
     24    UpdateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, WebCore::IntSize size, WebCore::IntSize scrollOffset)
    2525    DidUpdate()
    2626    SuspendPainting()
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp

    r80292 r80306  
    6161    , m_backingStoreStateID(0)
    6262    , m_inUpdateBackingStoreState(false)
     63    , m_shouldSendDidUpdateBackingStoreState(false)
    6364    , m_isWaitingForDidUpdate(false)
    6465    , m_isPaintingSuspended(!parameters.isVisible)
     
    188189
    189190    m_layerTreeHost->forceRepaint();
     191
     192    if (m_shouldSendDidUpdateBackingStoreState) {
     193        sendDidUpdateBackingStoreState();
     194        return;
     195    }
    190196
    191197    if (!m_layerTreeHost)
     
    238244}
    239245
    240 void DrawingAreaImpl::updateBackingStoreState(uint64_t stateID, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset)
     246void DrawingAreaImpl::updateBackingStoreState(uint64_t stateID, bool respondImmediately, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset)
    241247{
    242248    ASSERT(!m_inUpdateBackingStoreState);
    243249    m_inUpdateBackingStoreState = true;
    244250
    245     ASSERT_ARG(stateID, stateID > m_backingStoreStateID);
    246     m_backingStoreStateID = stateID;
    247 
    248     // Set this to false since we're about to call display().
     251    ASSERT_ARG(stateID, stateID >= m_backingStoreStateID);
     252    if (stateID != m_backingStoreStateID) {
     253        m_backingStoreStateID = stateID;
     254        m_shouldSendDidUpdateBackingStoreState = true;
     255
     256        m_webPage->setSize(size);
     257        m_webPage->layoutIfNeeded();
     258        m_webPage->scrollMainFrameIfNotAtMaxScrollPosition(scrollOffset);
     259
     260        if (m_layerTreeHost)
     261            m_layerTreeHost->sizeDidChange(size);
     262        else
     263            m_dirtyRegion = m_webPage->bounds();
     264    } else {
     265        ASSERT(size == m_webPage->size());
     266        if (!m_shouldSendDidUpdateBackingStoreState) {
     267            // We've already sent a DidUpdateBackingStoreState message for this state. We have nothing more to do.
     268            m_inUpdateBackingStoreState = false;
     269            return;
     270        }
     271    }
     272
     273    // The UI process has updated to a new backing store state. Any Update messages we sent before
     274    // this point will be ignored. We wait to set this to false until after updating the page's
     275    // size so that any displays triggered by the relayout will be ignored. If we're supposed to
     276    // respond to the UpdateBackingStoreState message immediately, we'll do a display anyway in
     277    // sendDidUpdateBackingStoreState; otherwise we shouldn't do one right now.
    249278    m_isWaitingForDidUpdate = false;
    250279
    251     m_webPage->setSize(size);
    252     m_webPage->layoutIfNeeded();
    253     m_webPage->scrollMainFrameIfNotAtMaxScrollPosition(scrollOffset);
     280    if (respondImmediately)
     281        sendDidUpdateBackingStoreState();
     282
     283    m_inUpdateBackingStoreState = false;
     284}
     285
     286void DrawingAreaImpl::sendDidUpdateBackingStoreState()
     287{
     288    ASSERT(!m_isWaitingForDidUpdate);
     289    ASSERT(m_shouldSendDidUpdateBackingStoreState);
     290
     291    m_shouldSendDidUpdateBackingStoreState = false;
    254292
    255293    UpdateInfo updateInfo;
    256294    LayerTreeContext layerTreeContext;
    257295
    258     if (m_layerTreeHost) {
    259         m_layerTreeHost->sizeDidChange(size);
    260         layerTreeContext = m_layerTreeHost->layerTreeContext();
    261 
    262         // We don't want the layer tree host to notify after the next scheduled
    263         // layer flush because that might end up sending an EnterAcceleratedCompositingMode
    264         // message back to the UI process, but the updated layer tree context
    265         // will be sent back in the DidUpdateBackingStoreState message.
    266         m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
    267     } else
    268         m_dirtyRegion = m_webPage->bounds();
    269 
    270     if (m_isPaintingSuspended || m_layerTreeHost)
     296    if (!m_isPaintingSuspended && !m_layerTreeHost)
     297        display(updateInfo);
     298
     299    if (m_isPaintingSuspended || m_layerTreeHost) {
    271300        updateInfo.viewSize = m_webPage->size();
    272     else {
    273         // The display here should not cause layout to happen, so we can't enter accelerated compositing mode here.
    274         display(updateInfo);
    275         ASSERT(!m_layerTreeHost);
     301
     302        if (m_layerTreeHost) {
     303            layerTreeContext = m_layerTreeHost->layerTreeContext();
     304
     305            // We don't want the layer tree host to notify after the next scheduled
     306            // layer flush because that might end up sending an EnterAcceleratedCompositingMode
     307            // message back to the UI process, but the updated layer tree context
     308            // will be sent back in the DidUpdateBackingStoreState message.
     309            m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
     310        }
    276311    }
    277312
    278313    m_webPage->send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext));
    279 
    280     m_inUpdateBackingStoreState = false;
    281314}
    282315
     
    343376    m_layerTreeHost->invalidate();
    344377    m_layerTreeHost = nullptr;
     378    m_dirtyRegion = m_webPage->bounds();
    345379
    346380    if (m_inUpdateBackingStoreState)
    347381        return;
     382
     383    if (m_shouldSendDidUpdateBackingStoreState) {
     384        sendDidUpdateBackingStoreState();
     385        return;
     386    }
    348387
    349388    UpdateInfo updateInfo;
    350389    if (m_isPaintingSuspended)
    351390        updateInfo.viewSize = m_webPage->size();
    352     else {
    353         m_dirtyRegion = m_webPage->bounds();
     391    else
    354392        display(updateInfo);
    355     }
    356393
    357394    // Send along a complete update of the page so we can paint the contents right after we exit the
    358395    // accelerated compositing mode, eliminiating flicker.
    359     if (!m_inUpdateBackingStoreState)
    360         m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo));
     396    m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo));
    361397}
    362398
     
    390426    ASSERT(!m_layerTreeHost);
    391427    ASSERT(!m_isWaitingForDidUpdate);
     428    ASSERT(!m_inUpdateBackingStoreState);
    392429
    393430    if (m_isPaintingSuspended)
     
    396433    if (m_dirtyRegion.isEmpty())
    397434        return;
     435
     436    if (m_shouldSendDidUpdateBackingStoreState) {
     437        sendDidUpdateBackingStoreState();
     438        return;
     439    }
    398440
    399441    UpdateInfo updateInfo;
  • trunk/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h

    r79868 r80306  
    6161
    6262    // CoreIPC message handlers.
    63     virtual void updateBackingStoreState(uint64_t backingStoreStateID, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset);
     63    virtual void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset);
    6464    virtual void didUpdate();
    6565    virtual void suspendPainting();
    6666    virtual void resumePainting();
     67
     68    void sendDidUpdateBackingStoreState();
    6769
    6870    void enterAcceleratedCompositingMode(WebCore::GraphicsLayer*);
     
    8284    // Whether we're currently processing an UpdateBackingStoreState message.
    8385    bool m_inUpdateBackingStoreState;
     86
     87    // When true, we should send an UpdateBackingStoreState message instead of any other messages
     88    // we normally send to the UI process.
     89    bool m_shouldSendDidUpdateBackingStoreState;
    8490
    8591    // Whether we're waiting for a DidUpdate message. Used for throttling paints so that the
Note: See TracChangeset for help on using the changeset viewer.