2 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "TiledDrawingArea.h"
29 #if ENABLE(TILED_BACKING_STORE)
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"
40 #include "WebProcess.h"
42 using namespace WebCore;
46 TiledDrawingArea::TiledDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage)
47 : DrawingArea(DrawingAreaInfo::Tiled, identifier, webPage)
48 , m_isWaitingForUpdate(false)
50 , m_displayTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::display)
51 , m_tileUpdateTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::tileUpdateTimerFired)
55 TiledDrawingArea::~TiledDrawingArea()
59 void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
61 // FIXME: Do something much smarter.
62 setNeedsDisplay(scrollRect);
65 void TiledDrawingArea::setNeedsDisplay(const IntRect& rect)
67 // FIXME: Collect a set of rects/region instead of just the union of all rects.
68 m_dirtyRect.unite(rect);
72 void TiledDrawingArea::display()
77 if (m_dirtyRect.isEmpty())
80 m_webPage->layoutIfNeeded();
82 IntRect dirtyRect = m_dirtyRect;
83 m_dirtyRect = IntRect();
85 WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::Invalidate, m_webPage->pageID(), CoreIPC::In(dirtyRect));
87 m_displayTimer.stop();
90 void TiledDrawingArea::scheduleDisplay()
95 if (m_displayTimer.isActive())
98 m_displayTimer.startOneShot(0);
101 void TiledDrawingArea::setSize(const IntSize& viewSize)
103 ASSERT(m_shouldPaint);
104 ASSERT_ARG(viewSize, !viewSize.isEmpty());
106 m_webPage->setSize(viewSize);
110 WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize));
113 void TiledDrawingArea::suspendPainting()
115 ASSERT(m_shouldPaint);
117 m_shouldPaint = false;
118 m_displayTimer.stop();
121 void TiledDrawingArea::resumePainting()
123 ASSERT(!m_shouldPaint);
125 m_shouldPaint = true;
127 // Display if needed.
131 void TiledDrawingArea::didUpdate()
133 // Display if needed.
137 void TiledDrawingArea::updateTile(int tileID, const IntRect& dirtyRect, float scale)
139 m_webPage->layoutIfNeeded();
141 UpdateChunk updateChunk(dirtyRect);
142 paintIntoUpdateChunk(&updateChunk, scale);
144 unsigned pendingUpdateCount = m_pendingUpdates.size();
145 WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::TileUpdated, m_webPage->pageID(), CoreIPC::In(tileID, updateChunk, scale, pendingUpdateCount));
148 void TiledDrawingArea::tileUpdateTimerFired()
150 ASSERT(!m_pendingUpdates.isEmpty());
152 UpdateMap::iterator it = m_pendingUpdates.begin();
153 TileUpdate update = it->second;
154 m_pendingUpdates.remove(it);
156 updateTile(update.tileID, update.dirtyRect, update.scale);
158 if (m_pendingUpdates.isEmpty())
159 WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In());
161 m_tileUpdateTimer.startOneShot(0.001);
164 void TiledDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
166 switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) {
167 case DrawingAreaLegacyMessage::SetSize: {
169 if (!arguments->decode(CoreIPC::Out(size)))
175 case DrawingAreaLegacyMessage::SuspendPainting:
178 case DrawingAreaLegacyMessage::ResumePainting:
181 case DrawingAreaLegacyMessage::CancelTileUpdate: {
183 if (!arguments->decode(CoreIPC::Out(tileID)))
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();
195 case DrawingAreaLegacyMessage::RequestTileUpdate: {
197 if (!arguments->decode(CoreIPC::Out(update.tileID, update.dirtyRect, update.scale)))
199 UpdateMap::iterator it = m_pendingUpdates.find(update.tileID);
200 if (it != m_pendingUpdates.end())
201 it->second.dirtyRect.unite(update.dirtyRect);
203 m_pendingUpdates.add(update.tileID, update);
204 if (!m_tileUpdateTimer.isActive())
205 m_tileUpdateTimer.startOneShot(0);
209 case DrawingAreaLegacyMessage::TakeSnapshot: {
211 IntRect contentsRect;
213 if (!arguments->decode(CoreIPC::Out(targetSize, contentsRect)))
216 m_webPage->layoutIfNeeded();
218 contentsRect.intersect(IntRect(IntPoint::zero(), m_webPage->mainFrame()->coreFrame()->view()->contentsSize()));
220 float targetScale = float(targetSize.width()) / contentsRect.width();
222 UpdateChunk updateChunk(IntRect(IntPoint(contentsRect.x() * targetScale, contentsRect.y() * targetScale), targetSize));
223 paintIntoUpdateChunk(&updateChunk, targetScale);
225 WebProcess::shared().connection()->deprecatedSend(DrawingAreaProxyLegacyMessage::SnapshotTaken, m_webPage->pageID(), CoreIPC::In(updateChunk));
229 ASSERT_NOT_REACHED();
234 } // namespace WebKit
236 #endif // TILED_BACKING_STORE