• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ChunkedUpdateDrawingArea(WebPage * webPage)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 
~ChunkedUpdateDrawingArea()49 ChunkedUpdateDrawingArea::~ChunkedUpdateDrawingArea()
50 {
51 }
52 
scroll(const IntRect & scrollRect,const IntSize & scrollOffset)53 void ChunkedUpdateDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
54 {
55     // FIXME: Do something much smarter.
56     setNeedsDisplay(scrollRect);
57 }
58 
setNeedsDisplay(const IntRect & rect)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 
display()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 
forceRepaint()93 void ChunkedUpdateDrawingArea::forceRepaint()
94 {
95     m_isWaitingForUpdate = false;
96     display();
97 }
98 
scheduleDisplay()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 
setSize(const IntSize & viewSize)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 
suspendPainting()143 void ChunkedUpdateDrawingArea::suspendPainting()
144 {
145     ASSERT(!m_paintingIsSuspended);
146 
147     m_paintingIsSuspended = true;
148     m_displayTimer.stop();
149 }
150 
deprecatedResumePainting(bool forceRepaint)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 
didUpdate()166 void ChunkedUpdateDrawingArea::didUpdate()
167 {
168     m_isWaitingForUpdate = false;
169 
170     // Display if needed.
171     display();
172 }
173 
didReceiveMessage(CoreIPC::Connection *,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments)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