OSDN Git Service

Merge WebKit at r78450: Initial merge by git.
[android-x86/external-webkit.git] / Source / WebKit2 / WebProcess / WebPage / TiledDrawingArea.cpp
1 /*
2  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
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 "TiledDrawingArea.h"
28
29 #if ENABLE(TILED_BACKING_STORE)
30
31 #include "DrawingAreaMessageKinds.h"
32 #include "DrawingAreaProxyMessageKinds.h"
33 #include "MessageID.h"
34 #include "UpdateChunk.h"
35 #include "WebCore/Frame.h"
36 #include "WebCore/FrameView.h"
37 #include "WebCoreArgumentCoders.h"
38 #include "WebFrame.h"
39 #include "WebPage.h"
40 #include "WebProcess.h"
41
42 using namespace WebCore;
43
44 namespace WebKit {
45
46 TiledDrawingArea::TiledDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage)
47     : DrawingArea(DrawingAreaInfo::Tiled, identifier, webPage)
48     , m_isWaitingForUpdate(false)
49     , m_shouldPaint(true)
50     , m_displayTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::display)
51     , m_tileUpdateTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::tileUpdateTimerFired)
52 {
53 }
54
55 TiledDrawingArea::~TiledDrawingArea()
56 {
57 }
58
59 void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
60 {
61     // FIXME: Do something much smarter.
62     setNeedsDisplay(scrollRect);
63 }
64
65 void TiledDrawingArea::setNeedsDisplay(const IntRect& rect)
66 {
67     // FIXME: Collect a set of rects/region instead of just the union of all rects.
68     m_dirtyRect.unite(rect);
69     scheduleDisplay();
70 }
71
72 void TiledDrawingArea::display()
73 {
74     if (!m_shouldPaint)
75         return;
76
77     if (m_dirtyRect.isEmpty())
78         return;
79
80     m_webPage->layoutIfNeeded();
81
82     IntRect dirtyRect = m_dirtyRect;
83     m_dirtyRect = IntRect();
84
85     WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::Invalidate, m_webPage->pageID(), CoreIPC::In(dirtyRect));
86
87     m_displayTimer.stop();
88 }
89
90 void TiledDrawingArea::scheduleDisplay()
91 {
92     if (!m_shouldPaint)
93         return;
94
95     if (m_displayTimer.isActive())
96         return;
97
98     m_displayTimer.startOneShot(0);
99 }
100
101 void TiledDrawingArea::setSize(const IntSize& viewSize)
102 {
103     ASSERT(m_shouldPaint);
104     ASSERT_ARG(viewSize, !viewSize.isEmpty());
105
106     m_webPage->setSize(viewSize);
107
108     scheduleDisplay();
109
110     WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize));
111 }
112
113 void TiledDrawingArea::suspendPainting()
114 {
115     ASSERT(m_shouldPaint);
116
117     m_shouldPaint = false;
118     m_displayTimer.stop();
119 }
120
121 void TiledDrawingArea::resumePainting()
122 {
123     ASSERT(!m_shouldPaint);
124
125     m_shouldPaint = true;
126
127     // Display if needed.
128     display();
129 }
130
131 void TiledDrawingArea::didUpdate()
132 {
133     // Display if needed.
134     display();
135 }
136
137 void TiledDrawingArea::updateTile(int tileID, const IntRect& dirtyRect, float scale)
138 {
139     m_webPage->layoutIfNeeded();
140
141     UpdateChunk updateChunk(dirtyRect);
142     paintIntoUpdateChunk(&updateChunk, scale);
143
144     unsigned pendingUpdateCount = m_pendingUpdates.size();
145     WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::TileUpdated, m_webPage->pageID(), CoreIPC::In(tileID, updateChunk, scale, pendingUpdateCount));
146 }
147
148 void TiledDrawingArea::tileUpdateTimerFired()
149 {
150     ASSERT(!m_pendingUpdates.isEmpty());
151
152     UpdateMap::iterator it = m_pendingUpdates.begin();
153     TileUpdate update = it->second;
154     m_pendingUpdates.remove(it);
155
156     updateTile(update.tileID, update.dirtyRect, update.scale);
157
158     if (m_pendingUpdates.isEmpty())
159         WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In());
160     else
161         m_tileUpdateTimer.startOneShot(0.001);
162 }
163
164 void TiledDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
165 {
166     switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) {
167     case DrawingAreaLegacyMessage::SetSize: {
168         IntSize size;
169         if (!arguments->decode(CoreIPC::Out(size)))
170             return;
171
172         setSize(size);
173         break;
174     }
175     case DrawingAreaLegacyMessage::SuspendPainting:
176         suspendPainting();
177         break;
178     case DrawingAreaLegacyMessage::ResumePainting:
179         resumePainting();
180         break;
181     case DrawingAreaLegacyMessage::CancelTileUpdate: {
182         int tileID;
183         if (!arguments->decode(CoreIPC::Out(tileID)))
184             return;
185         UpdateMap::iterator it = m_pendingUpdates.find(tileID);
186         if (it != m_pendingUpdates.end()) {
187             m_pendingUpdates.remove(it);
188             if (m_pendingUpdates.isEmpty()) {
189                 WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In());
190                 m_tileUpdateTimer.stop();
191             }
192         }
193         break;
194     }
195     case DrawingAreaLegacyMessage::RequestTileUpdate: {
196         TileUpdate update;
197         if (!arguments->decode(CoreIPC::Out(update.tileID, update.dirtyRect, update.scale)))
198             return;
199         UpdateMap::iterator it = m_pendingUpdates.find(update.tileID);
200         if (it != m_pendingUpdates.end())
201             it->second.dirtyRect.unite(update.dirtyRect);
202         else {
203             m_pendingUpdates.add(update.tileID, update);
204             if (!m_tileUpdateTimer.isActive())
205                 m_tileUpdateTimer.startOneShot(0);
206         }
207         break;
208     }
209     case DrawingAreaLegacyMessage::TakeSnapshot: {
210         IntSize targetSize;
211         IntRect contentsRect;
212
213         if (!arguments->decode(CoreIPC::Out(targetSize, contentsRect)))
214             return;
215
216         m_webPage->layoutIfNeeded();
217
218         contentsRect.intersect(IntRect(IntPoint::zero(), m_webPage->mainFrame()->coreFrame()->view()->contentsSize()));
219
220         float targetScale = float(targetSize.width()) / contentsRect.width();
221
222         UpdateChunk updateChunk(IntRect(IntPoint(contentsRect.x() * targetScale, contentsRect.y() * targetScale), targetSize));
223         paintIntoUpdateChunk(&updateChunk, targetScale);
224
225         WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::SnapshotTaken, m_webPage->pageID(), CoreIPC::In(updateChunk));
226         break;
227     }
228     default:
229         ASSERT_NOT_REACHED();
230         break;
231     }
232 }
233
234 } // namespace WebKit
235
236 #endif // TILED_BACKING_STORE