Home | History | Annotate | Download | only in WebPage
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "ChunkedUpdateDrawingArea.h"
     28 
     29 #include "DrawingAreaMessageKinds.h"
     30 #include "DrawingAreaProxyMessageKinds.h"
     31 #include "MessageID.h"
     32 #include "UpdateChunk.h"
     33 #include "WebCoreArgumentCoders.h"
     34 #include "WebPage.h"
     35 #include "WebProcess.h"
     36 
     37 using namespace WebCore;
     38 
     39 namespace WebKit {
     40 
     41 ChunkedUpdateDrawingArea::ChunkedUpdateDrawingArea(WebPage* webPage)
     42     : DrawingArea(DrawingAreaTypeChunkedUpdate, webPage)
     43     , m_isWaitingForUpdate(false)
     44     , m_paintingIsSuspended(false)
     45     , m_displayTimer(WebProcess::shared().runLoop(), this, &ChunkedUpdateDrawingArea::display)
     46 {
     47 }
     48 
     49 ChunkedUpdateDrawingArea::~ChunkedUpdateDrawingArea()
     50 {
     51 }
     52 
     53 void ChunkedUpdateDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
     54 {
     55     // FIXME: Do something much smarter.
     56     setNeedsDisplay(scrollRect);
     57 }
     58 
     59 void ChunkedUpdateDrawingArea::setNeedsDisplay(const IntRect& rect)
     60 {
     61     // FIXME: Collect a set of rects/region instead of just the union
     62     // of all rects.
     63     m_dirtyRect.unite(rect);
     64     scheduleDisplay();
     65 }
     66 
     67 void ChunkedUpdateDrawingArea::display()
     68 {
     69     ASSERT(!m_isWaitingForUpdate);
     70 
     71     if (m_paintingIsSuspended)
     72         return;
     73 
     74     if (m_dirtyRect.isEmpty())
     75         return;
     76 
     77     // Layout if necessary.
     78     m_webPage->layoutIfNeeded();
     79 
     80     IntRect dirtyRect = m_dirtyRect;
     81     m_dirtyRect = IntRect();
     82 
     83     // Create a new UpdateChunk and paint into it.
     84     UpdateChunk updateChunk(dirtyRect);
     85     paintIntoUpdateChunk(&updateChunk);
     86 
     87     WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::Update, m_webPage->pageID(), CoreIPC::In(updateChunk));
     88 
     89     m_isWaitingForUpdate = true;
     90     m_displayTimer.stop();
     91 }
     92 
     93 void ChunkedUpdateDrawingArea::forceRepaint()
     94 {
     95     m_isWaitingForUpdate = false;
     96     display();
     97 }
     98 
     99 void ChunkedUpdateDrawingArea::scheduleDisplay()
    100 {
    101     if (m_paintingIsSuspended)
    102         return;
    103 
    104     if (m_isWaitingForUpdate)
    105         return;
    106 
    107     if (m_dirtyRect.isEmpty())
    108         return;
    109 
    110     if (m_displayTimer.isActive())
    111         return;
    112 
    113     m_displayTimer.startOneShot(0);
    114 }
    115 
    116 void ChunkedUpdateDrawingArea::setSize(const IntSize& viewSize)
    117 {
    118     ASSERT_ARG(viewSize, !viewSize.isEmpty());
    119 
    120     // We don't want to wait for an update until we display.
    121     m_isWaitingForUpdate = false;
    122 
    123     m_webPage->setSize(viewSize);
    124     m_webPage->layoutIfNeeded();
    125 
    126     if (m_paintingIsSuspended) {
    127         ASSERT(!m_displayTimer.isActive());
    128 
    129         // Painting is suspended, just send back an empty update chunk.
    130         WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(UpdateChunk()));
    131         return;
    132     }
    133 
    134     // Create a new UpdateChunk and paint into it.
    135     UpdateChunk updateChunk(IntRect(0, 0, viewSize.width(), viewSize.height()));
    136     paintIntoUpdateChunk(&updateChunk);
    137 
    138     m_displayTimer.stop();
    139 
    140     WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(updateChunk));
    141 }
    142 
    143 void ChunkedUpdateDrawingArea::suspendPainting()
    144 {
    145     ASSERT(!m_paintingIsSuspended);
    146 
    147     m_paintingIsSuspended = true;
    148     m_displayTimer.stop();
    149 }
    150 
    151 void ChunkedUpdateDrawingArea::deprecatedResumePainting(bool forceRepaint)
    152 {
    153     ASSERT(m_paintingIsSuspended);
    154 
    155     m_paintingIsSuspended = false;
    156 
    157     if (forceRepaint) {
    158         // Just set the dirty rect to the entire page size.
    159         m_dirtyRect = m_webPage->bounds();
    160     }
    161 
    162     // Schedule a display.
    163     scheduleDisplay();
    164 }
    165 
    166 void ChunkedUpdateDrawingArea::didUpdate()
    167 {
    168     m_isWaitingForUpdate = false;
    169 
    170     // Display if needed.
    171     display();
    172 }
    173 
    174 void ChunkedUpdateDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
    175 {
    176     switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) {
    177         case DrawingAreaLegacyMessage::SetSize: {
    178             IntSize size;
    179             if (!arguments->decode(CoreIPC::Out(size)))
    180                 return;
    181 
    182             setSize(size);
    183             break;
    184         }
    185 
    186         case DrawingAreaLegacyMessage::SuspendPainting:
    187             suspendPainting();
    188             break;
    189 
    190         case DrawingAreaLegacyMessage::ResumePainting: {
    191             bool forceRepaint;
    192             if (!arguments->decode(CoreIPC::Out(forceRepaint)))
    193                 return;
    194 
    195             deprecatedResumePainting(forceRepaint);
    196             break;
    197         }
    198         case DrawingAreaLegacyMessage::DidUpdate:
    199             didUpdate();
    200             break;
    201 
    202         default:
    203             ASSERT_NOT_REACHED();
    204             break;
    205     }
    206 }
    207 
    208 } // namespace WebKit
    209