Home | History | Annotate | Download | only in UIProcess
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     24  * THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include "config.h"
     28 #include "ChunkedUpdateDrawingAreaProxy.h"
     29 
     30 #include "DrawingAreaMessageKinds.h"
     31 #include "DrawingAreaProxyMessageKinds.h"
     32 #include "MessageID.h"
     33 #include "UpdateChunk.h"
     34 #include "WebCoreArgumentCoders.h"
     35 #include "WebPageProxy.h"
     36 #include "WebProcessProxy.h"
     37 
     38 using namespace WebCore;
     39 
     40 namespace WebKit {
     41 
     42 PassOwnPtr<ChunkedUpdateDrawingAreaProxy> ChunkedUpdateDrawingAreaProxy::create(PlatformWebView* webView, WebPageProxy* webPageProxy)
     43 {
     44     return adoptPtr(new ChunkedUpdateDrawingAreaProxy(webView, webPageProxy));
     45 }
     46 
     47 ChunkedUpdateDrawingAreaProxy::ChunkedUpdateDrawingAreaProxy(PlatformWebView* webView, WebPageProxy* webPageProxy)
     48     : DrawingAreaProxy(DrawingAreaTypeChunkedUpdate, webPageProxy)
     49     , m_isWaitingForDidSetFrameNotification(false)
     50     , m_isVisible(true)
     51     , m_forceRepaintWhenResumingPainting(false)
     52 #if PLATFORM(GTK)
     53     , m_backingStoreImage(0)
     54 #endif
     55     , m_webView(webView)
     56 {
     57 }
     58 
     59 ChunkedUpdateDrawingAreaProxy::~ChunkedUpdateDrawingAreaProxy()
     60 {
     61 }
     62 
     63 bool ChunkedUpdateDrawingAreaProxy::paint(const IntRect& rect, PlatformDrawingContext context)
     64 {
     65     if (m_isWaitingForDidSetFrameNotification) {
     66         WebPageProxy* page = this->page();
     67         if (!page->isValid())
     68             return false;
     69 
     70         if (page->process()->isLaunching())
     71             return false;
     72 
     73         OwnPtr<CoreIPC::ArgumentDecoder> arguments = page->process()->connection()->deprecatedWaitFor(DrawingAreaProxyLegacyMessage::DidSetSize, page->pageID(), 0.04);
     74         if (arguments)
     75             didReceiveMessage(page->process()->connection(), CoreIPC::MessageID(DrawingAreaProxyLegacyMessage::DidSetSize), arguments.get());
     76     }
     77 
     78     return platformPaint(rect, context);
     79 }
     80 
     81 void ChunkedUpdateDrawingAreaProxy::sizeDidChange()
     82 {
     83     sendSetSize();
     84 }
     85 
     86 void ChunkedUpdateDrawingAreaProxy::setPageIsVisible(bool isVisible)
     87 {
     88     WebPageProxy* page = this->page();
     89 
     90     if (isVisible == m_isVisible)
     91         return;
     92 
     93     m_isVisible = isVisible;
     94     if (!page->isValid())
     95         return;
     96 
     97     if (!m_isVisible) {
     98         // Tell the web process that it doesn't need to paint anything for now.
     99         page->process()->deprecatedSend(DrawingAreaLegacyMessage::SuspendPainting, page->pageID(), CoreIPC::In());
    100         return;
    101     }
    102 
    103     // The page is now visible, resume painting.
    104     page->process()->deprecatedSend(DrawingAreaLegacyMessage::ResumePainting, page->pageID(), CoreIPC::In(m_forceRepaintWhenResumingPainting));
    105     m_forceRepaintWhenResumingPainting = false;
    106 }
    107 
    108 void ChunkedUpdateDrawingAreaProxy::didSetSize(UpdateChunk* updateChunk)
    109 {
    110     ASSERT(m_isWaitingForDidSetFrameNotification);
    111     m_isWaitingForDidSetFrameNotification = false;
    112 
    113     IntSize viewSize = updateChunk->rect().size();
    114 
    115     if (viewSize != m_size)
    116         sendSetSize();
    117 
    118     invalidateBackingStore();
    119     if (!updateChunk->isEmpty())
    120         drawUpdateChunkIntoBackingStore(updateChunk);
    121 }
    122 
    123 void ChunkedUpdateDrawingAreaProxy::deprecatedUpdate(UpdateChunk* updateChunk)
    124 {
    125     if (!m_isVisible) {
    126         // We got an update request that must have been sent before we told the web process to suspend painting.
    127         // Don't paint this into the backing store, because that could leave the backing store in an inconsistent state.
    128         // Instead, we will just tell the drawing area to repaint everything when we resume painting.
    129         m_forceRepaintWhenResumingPainting = true;
    130     } else {
    131         // Just paint into backing store.
    132         drawUpdateChunkIntoBackingStore(updateChunk);
    133     }
    134 
    135     WebPageProxy* page = this->page();
    136     page->process()->deprecatedSend(DrawingAreaLegacyMessage::DidUpdate, page->pageID(), CoreIPC::In());
    137 }
    138 
    139 void ChunkedUpdateDrawingAreaProxy::sendSetSize()
    140 {
    141     if (!m_webPageProxy->isValid())
    142         return;
    143 
    144     if (m_isWaitingForDidSetFrameNotification)
    145         return;
    146     m_isWaitingForDidSetFrameNotification = true;
    147 
    148     m_webPageProxy->process()->deprecatedSend(DrawingAreaLegacyMessage::SetSize, m_webPageProxy->pageID(), CoreIPC::In(m_size));
    149 }
    150 
    151 void ChunkedUpdateDrawingAreaProxy::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
    152 {
    153     switch (messageID.get<DrawingAreaProxyLegacyMessage::Kind>()) {
    154         case DrawingAreaProxyLegacyMessage::Update: {
    155             UpdateChunk updateChunk;
    156             if (!arguments->decode(updateChunk))
    157                 return;
    158 
    159             deprecatedUpdate(&updateChunk);
    160             break;
    161         }
    162         case DrawingAreaProxyLegacyMessage::DidSetSize: {
    163             UpdateChunk updateChunk;
    164             if (!arguments->decode(CoreIPC::Out(updateChunk)))
    165                 return;
    166 
    167             didSetSize(&updateChunk);
    168             break;
    169         }
    170         default:
    171             ASSERT_NOT_REACHED();
    172     }
    173 }
    174 
    175 } // namespace WebKit
    176