• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TiledDrawingArea(WebPage * webPage)46 TiledDrawingArea::TiledDrawingArea(WebPage* webPage)
47     : DrawingArea(DrawingAreaTypeTiled, 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 
~TiledDrawingArea()55 TiledDrawingArea::~TiledDrawingArea()
56 {
57 }
58 
scroll(const IntRect & scrollRect,const IntSize & scrollDelta)59 void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
60 {
61     // FIXME: Do something much smarter.
62     setNeedsDisplay(scrollRect);
63 }
64 
setNeedsDisplay(const IntRect & rect)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 
display()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 
scheduleDisplay()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 
setSize(const IntSize & viewSize)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 
suspendPainting()113 void TiledDrawingArea::suspendPainting()
114 {
115     ASSERT(m_shouldPaint);
116 
117     m_shouldPaint = false;
118     m_displayTimer.stop();
119 }
120 
resumePainting()121 void TiledDrawingArea::resumePainting()
122 {
123     ASSERT(!m_shouldPaint);
124 
125     m_shouldPaint = true;
126 
127     // Display if needed.
128     display();
129 }
130 
didUpdate()131 void TiledDrawingArea::didUpdate()
132 {
133     // Display if needed.
134     display();
135 }
136 
updateTile(int tileID,const IntRect & dirtyRect,float scale)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 
tileUpdateTimerFired()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 
didReceiveMessage(CoreIPC::Connection *,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments)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
237