summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-13 16:23:25 +0100
committerBen Murdoch <benm@google.com>2011-05-16 11:35:02 +0100
commit65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch)
treef478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp
parent47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff)
downloadexternal_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp')
-rw-r--r--Source/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp624
1 files changed, 624 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp b/Source/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp
new file mode 100644
index 0000000..b687192
--- /dev/null
+++ b/Source/WebKit2/UIProcess/TiledDrawingAreaProxy.cpp
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "TiledDrawingAreaProxy.h"
+
+#if ENABLE(TILED_BACKING_STORE)
+#include "DrawingAreaMessageKinds.h"
+#include "DrawingAreaProxyMessageKinds.h"
+#include "MessageID.h"
+#include "UpdateChunk.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPageProxy.h"
+#include "WebProcessProxy.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static const int defaultTileWidth = 1024;
+static const int defaultTileHeight = 1024;
+
+PassOwnPtr<TiledDrawingAreaProxy> TiledDrawingAreaProxy::create(PlatformWebView* webView, WebPageProxy* webPageProxy)
+{
+ return adoptPtr(new TiledDrawingAreaProxy(webView, webPageProxy));
+}
+
+TiledDrawingAreaProxy::TiledDrawingAreaProxy(PlatformWebView* webView, WebPageProxy* webPageProxy)
+ : DrawingAreaProxy(DrawingAreaInfo::Tiled, webPageProxy)
+ , m_isWaitingForDidSetFrameNotification(false)
+ , m_isVisible(true)
+ , m_webView(webView)
+ , m_tileBufferUpdateTimer(RunLoop::main(), this, &TiledDrawingAreaProxy::tileBufferUpdateTimerFired)
+ , m_tileCreationTimer(RunLoop::main(), this, &TiledDrawingAreaProxy::tileCreationTimerFired)
+ , m_tileSize(defaultTileWidth, defaultTileHeight)
+ , m_tileCreationDelay(0.01)
+ , m_keepAreaMultiplier(2.5, 4.5)
+ , m_coverAreaMultiplier(2, 3)
+ , m_contentsScale(1)
+{
+}
+
+TiledDrawingAreaProxy::~TiledDrawingAreaProxy()
+{
+}
+
+void TiledDrawingAreaProxy::sizeDidChange()
+{
+ WebPageProxy* page = this->page();
+ if (!page || !page->isValid())
+ return;
+
+ if (m_size.isEmpty())
+ return;
+
+ m_viewSize = m_size;
+ m_lastSetViewSize = m_size;
+
+ if (m_isWaitingForDidSetFrameNotification)
+ return;
+ m_isWaitingForDidSetFrameNotification = true;
+
+ page->process()->responsivenessTimer()->start();
+ page->process()->send(DrawingAreaLegacyMessage::SetSize, page->pageID(), CoreIPC::In(m_size));
+}
+
+void TiledDrawingAreaProxy::setPageIsVisible(bool isVisible)
+{
+ WebPageProxy* page = this->page();
+
+ if (isVisible == m_isVisible)
+ return;
+
+ m_isVisible = isVisible;
+ if (!page || !page->isValid())
+ return;
+
+ if (!m_isVisible) {
+ // Tell the web process that it doesn't need to paint anything for now.
+ page->process()->send(DrawingAreaLegacyMessage::SuspendPainting, page->pageID(), CoreIPC::In());
+ return;
+ }
+
+ // The page is now visible.
+ page->process()->send(DrawingAreaLegacyMessage::ResumePainting, page->pageID(), CoreIPC::In());
+
+ // FIXME: We should request a full repaint here if needed.
+}
+
+void TiledDrawingAreaProxy::didSetSize(const IntSize& viewSize)
+{
+ ASSERT(m_isWaitingForDidSetFrameNotification);
+ m_isWaitingForDidSetFrameNotification = false;
+
+ if (viewSize != m_lastSetViewSize)
+ setSize(m_lastSetViewSize);
+
+ WebPageProxy* page = this->page();
+ page->process()->responsivenessTimer()->stop();
+}
+
+void TiledDrawingAreaProxy::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
+{
+ switch (messageID.get<DrawingAreaProxyLegacyMessage::Kind>()) {
+ case DrawingAreaProxyLegacyMessage::TileUpdated: {
+ int tileID;
+ UpdateChunk updateChunk;
+ float scale;
+ unsigned pendingUpdateCount;
+ if (!arguments->decode(CoreIPC::Out(tileID, updateChunk, scale, pendingUpdateCount)))
+ return;
+
+ TiledDrawingAreaTile* tile = m_tilesByID.get(tileID);
+ ASSERT(!tile || tile->ID() == tileID);
+ if (tile)
+ tile->updateFromChunk(&updateChunk, scale);
+ tileBufferUpdateComplete();
+ break;
+ }
+ case DrawingAreaProxyLegacyMessage::DidSetSize: {
+ IntSize size;
+ if (!arguments->decode(CoreIPC::Out(size)))
+ return;
+
+ didSetSize(size);
+ break;
+ }
+ case DrawingAreaProxyLegacyMessage::Invalidate: {
+ IntRect rect;
+ if (!arguments->decode(CoreIPC::Out(rect)))
+ return;
+
+ invalidate(rect);
+ break;
+ }
+ case DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed: {
+ tileBufferUpdateComplete();
+ break;
+ }
+ case DrawingAreaProxyLegacyMessage::SnapshotTaken: {
+ UpdateChunk chunk;
+ if (!arguments->decode(CoreIPC::Out(chunk)))
+ return;
+ snapshotTaken(chunk);
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void TiledDrawingAreaProxy::didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder&)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void TiledDrawingAreaProxy::requestTileUpdate(int tileID, const IntRect& dirtyRect)
+{
+ page()->process()->connection()->send(DrawingAreaLegacyMessage::RequestTileUpdate, page()->pageID(), CoreIPC::In(tileID, dirtyRect, contentsScale()));
+}
+
+void TiledDrawingAreaProxy::waitUntilUpdatesComplete()
+{
+ while (hasPendingUpdates()) {
+ int tileID;
+ UpdateChunk updateChunk;
+ float scale;
+ unsigned pendingUpdateCount;
+ static const double tileUpdateTimeout = 10.0;
+ OwnPtr<CoreIPC::ArgumentDecoder> arguments = page()->process()->connection()->waitFor(DrawingAreaProxyLegacyMessage::TileUpdated, page()->pageID(), tileUpdateTimeout);
+ if (!arguments)
+ break;
+ if (!arguments->decode(CoreIPC::Out(tileID, updateChunk, scale, pendingUpdateCount)))
+ break;
+ TiledDrawingAreaTile* tile = m_tilesByID.get(tileID);
+ ASSERT(!tile || tile->ID() == tileID);
+ if (tile)
+ tile->updateFromChunk(&updateChunk, scale);
+ }
+ tileBufferUpdateComplete();
+}
+
+PassRefPtr<TiledDrawingAreaTile> TiledDrawingAreaProxy::createTile(const TiledDrawingAreaTile::Coordinate& coordinate)
+{
+ RefPtr<TiledDrawingAreaTile> tile = TiledDrawingAreaTile::create(this, coordinate);
+ setTile(coordinate, tile);
+ return tile;
+}
+
+void TiledDrawingAreaProxy::setTileSize(const IntSize& size)
+{
+ if (m_tileSize == size)
+ return;
+ m_tileSize = size;
+ removeAllTiles();
+ startTileCreationTimer();
+}
+
+void TiledDrawingAreaProxy::setTileCreationDelay(double delay)
+{
+ m_tileCreationDelay = delay;
+}
+
+void TiledDrawingAreaProxy::setKeepAndCoverAreaMultipliers(const FloatSize& keepMultiplier, const FloatSize& coverMultiplier)
+{
+ m_keepAreaMultiplier = keepMultiplier;
+ m_coverAreaMultiplier = coverMultiplier;
+ startTileCreationTimer();
+}
+
+void TiledDrawingAreaProxy::takeSnapshot(const IntSize& size, const IntRect& contentsRect)
+{
+ WebPageProxy* page = this->page();
+ page->process()->send(DrawingAreaLegacyMessage::TakeSnapshot, page->pageID(), CoreIPC::Out(size, contentsRect));
+}
+
+void TiledDrawingAreaProxy::invalidate(const IntRect& contentsDirtyRect)
+{
+ IntRect dirtyRect(mapFromContents(contentsDirtyRect));
+
+ TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.topLeft());
+ TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(dirtyRect.bottomRight());
+
+ IntRect coverRect = calculateCoverRect(m_previousVisibleRect);
+
+ Vector<TiledDrawingAreaTile::Coordinate> tilesToRemove;
+
+ for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
+ for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
+ RefPtr<TiledDrawingAreaTile> currentTile = tileAt(TiledDrawingAreaTile::Coordinate(xCoordinate, yCoordinate));
+ if (!currentTile)
+ continue;
+ if (!currentTile->rect().intersects(dirtyRect))
+ continue;
+ // If a tile outside out current cover rect gets invalidated, just drop it instead of updating.
+ if (!currentTile->rect().intersects(coverRect)) {
+ tilesToRemove.append(currentTile->coordinate());
+ continue;
+ }
+ currentTile->invalidate(dirtyRect);
+ }
+ }
+
+ unsigned removeCount = tilesToRemove.size();
+ for (unsigned n = 0; n < removeCount; ++n)
+ removeTile(tilesToRemove[n]);
+
+ startTileBufferUpdateTimer();
+}
+
+void TiledDrawingAreaProxy::updateTileBuffers()
+{
+ Vector<RefPtr<TiledDrawingAreaTile> > newDirtyTiles;
+ TileMap::iterator end = m_tiles.end();
+ for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+ RefPtr<TiledDrawingAreaTile>& current = it->second;
+ if (!current->isDirty())
+ continue;
+ newDirtyTiles.append(it->second);
+ }
+
+ if (newDirtyTiles.isEmpty())
+ return;
+
+ unsigned size = newDirtyTiles.size();
+ for (unsigned n = 0; n < size; ++n)
+ newDirtyTiles[n]->updateBackBuffer();
+}
+
+void TiledDrawingAreaProxy::tileBufferUpdateComplete()
+{
+ // Bail out if all tile back buffers have not been updated.
+ Vector<TiledDrawingAreaTile*> tilesToFlip;
+ TileMap::iterator end = m_tiles.end();
+ for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+ RefPtr<TiledDrawingAreaTile>& current = it->second;
+ if (current->isReadyToPaint() && (current->isDirty() || current->hasBackBufferUpdatePending()))
+ return;
+ if (current->hasReadyBackBuffer())
+ tilesToFlip.append(current.get());
+ }
+ // Everything done, move back buffers to front.
+ Vector<IntRect> paintedArea;
+ unsigned size = tilesToFlip.size();
+ for (unsigned n = 0; n < size; ++n) {
+ TiledDrawingAreaTile* tile = tilesToFlip[n];
+ tile->swapBackBufferToFront();
+ // FIXME: should not request system repaint for the full tile.
+ paintedArea.append(mapToContents(tile->rect()));
+ }
+ if (size)
+ updateWebView(paintedArea);
+
+ m_tileCreationTimer.startOneShot(0);
+}
+
+bool TiledDrawingAreaProxy::paint(const IntRect& rect, PlatformDrawingContext context)
+{
+ if (m_isWaitingForDidSetFrameNotification) {
+ WebPageProxy* page = this->page();
+ if (!page->isValid())
+ return false;
+
+ if (page->process()->isLaunching())
+ return false;
+ }
+
+ adjustVisibleRect();
+
+ GraphicsContext gc(context);
+ gc.save();
+
+ // Assumes the backing store is painted with the scale transform applied.
+ // Since tile content is already scaled, first revert the scaling from the painter.
+ gc.scale(FloatSize(1 / m_contentsScale, 1 / m_contentsScale));
+
+ IntRect dirtyRect = mapFromContents(rect);
+
+ TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.topLeft());
+ TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(dirtyRect.bottomRight());
+
+ for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
+ for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
+ TiledDrawingAreaTile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
+ RefPtr<TiledDrawingAreaTile> currentTile = tileAt(currentCoordinate);
+ if (currentTile && currentTile->isReadyToPaint())
+ currentTile->paint(&gc, dirtyRect);
+ }
+ }
+
+ gc.restore();
+ return true;
+}
+
+void TiledDrawingAreaProxy::adjustVisibleRect()
+{
+ IntRect visibleRect = mapFromContents(webViewVisibleRect());
+ if (m_previousVisibleRect == visibleRect)
+ return;
+ m_previousVisibleRect = visibleRect;
+
+ startTileCreationTimer();
+}
+
+void TiledDrawingAreaProxy::setContentsScale(float scale)
+{
+ if (m_contentsScale == scale)
+ return;
+ m_contentsScale = scale;
+ removeAllTiles();
+ createTiles();
+}
+
+void TiledDrawingAreaProxy::removeAllTiles()
+{
+ Vector<RefPtr<TiledDrawingAreaTile> > tilesToRemove;
+ copyValuesToVector(m_tiles, tilesToRemove);
+ unsigned removeCount = tilesToRemove.size();
+ for (unsigned n = 0; n < removeCount; ++n)
+ removeTile(tilesToRemove[n]->coordinate());
+}
+
+double TiledDrawingAreaProxy::tileDistance(const IntRect& viewport, const TiledDrawingAreaTile::Coordinate& tileCoordinate)
+{
+ if (viewport.intersects(tileRectForCoordinate(tileCoordinate)))
+ return 0;
+
+ IntPoint viewCenter = viewport.location() + IntSize(viewport.width() / 2, viewport.height() / 2);
+ TiledDrawingAreaTile::Coordinate centerCoordinate = tileCoordinateForPoint(viewCenter);
+
+ // Manhattan distance, biased so that vertical distances are shorter.
+ const double horizontalBias = 1.3;
+ return abs(centerCoordinate.y() - tileCoordinate.y()) + horizontalBias * abs(centerCoordinate.x() - tileCoordinate.x());
+}
+
+IntRect TiledDrawingAreaProxy::calculateKeepRect(const IntRect& visibleRect) const
+{
+ IntRect result = visibleRect;
+ result.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1));
+ result.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1));
+ result.intersect(contentsRect());
+ return result;
+}
+
+IntRect TiledDrawingAreaProxy::calculateCoverRect(const IntRect& visibleRect) const
+{
+ IntRect result = visibleRect;
+ result.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1));
+ result.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1));
+ result.intersect(contentsRect());
+ return result;
+}
+
+void TiledDrawingAreaProxy::createTiles()
+{
+ IntRect visibleRect = mapFromContents(webViewVisibleRect());
+ m_previousVisibleRect = visibleRect;
+
+ if (visibleRect.isEmpty())
+ return;
+
+ // Resize tiles on edges in case the contents size has changed.
+ bool didResizeTiles = resizeEdgeTiles();
+
+ // Remove tiles outside out current maximum keep rect.
+ dropTilesOutsideRect(calculateKeepRect(visibleRect));
+
+ // Cover the cover rect with tiles.
+ IntRect coverRect = calculateCoverRect(visibleRect);
+
+ // Search for the tile position closest to the viewport center that does not yet contain a tile.
+ // Which position is considered the closest depends on the tileDistance function.
+ double shortestDistance = std::numeric_limits<double>::infinity();
+ Vector<TiledDrawingAreaTile::Coordinate> tilesToCreate;
+ unsigned requiredTileCount = 0;
+ bool hasVisibleCheckers = false;
+ TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(coverRect.topLeft());
+ TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(coverRect.bottomRight());
+ for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
+ for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
+ TiledDrawingAreaTile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
+ // Distance is 0 for all currently visible tiles.
+ double distance = tileDistance(visibleRect, currentCoordinate);
+
+ RefPtr<TiledDrawingAreaTile> tile = tileAt(currentCoordinate);
+ if (!distance && (!tile || !tile->isReadyToPaint()))
+ hasVisibleCheckers = true;
+ if (tile)
+ continue;
+
+ ++requiredTileCount;
+
+ if (distance > shortestDistance)
+ continue;
+ if (distance < shortestDistance) {
+ tilesToCreate.clear();
+ shortestDistance = distance;
+ }
+ tilesToCreate.append(currentCoordinate);
+ }
+ }
+
+ if (hasVisibleCheckers && shortestDistance > 0)
+ return;
+
+ // Now construct the tile(s).
+ unsigned tilesToCreateCount = tilesToCreate.size();
+ for (unsigned n = 0; n < tilesToCreateCount; ++n)
+ createTile(tilesToCreate[n]);
+
+ requiredTileCount -= tilesToCreateCount;
+
+ // Paint the content of the newly created tiles.
+ if (tilesToCreateCount || didResizeTiles)
+ updateTileBuffers();
+
+ // Keep creating tiles until the whole coverRect is covered.
+ if (requiredTileCount)
+ m_tileCreationTimer.startOneShot(m_tileCreationDelay);
+}
+
+bool TiledDrawingAreaProxy::resizeEdgeTiles()
+{
+ IntRect contentsRect = this->contentsRect();
+ bool wasResized = false;
+
+ Vector<TiledDrawingAreaTile::Coordinate> tilesToRemove;
+ TileMap::iterator end = m_tiles.end();
+ for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+ TiledDrawingAreaTile::Coordinate tileCoordinate = it->second->coordinate();
+ IntRect tileRect = it->second->rect();
+ IntRect expectedTileRect = tileRectForCoordinate(tileCoordinate);
+ if (!contentsRect.contains(tileRect))
+ tilesToRemove.append(tileCoordinate);
+ else if (expectedTileRect != tileRect) {
+ it->second->resize(expectedTileRect.size());
+ wasResized = true;
+ }
+ }
+ unsigned removeCount = tilesToRemove.size();
+ for (unsigned n = 0; n < removeCount; ++n)
+ removeTile(tilesToRemove[n]);
+ return wasResized;
+}
+
+void TiledDrawingAreaProxy::dropTilesOutsideRect(const IntRect& keepRect)
+{
+ FloatRect keepRectF = keepRect;
+
+ Vector<TiledDrawingAreaTile::Coordinate> toRemove;
+ TileMap::iterator end = m_tiles.end();
+ for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
+ TiledDrawingAreaTile::Coordinate coordinate = it->second->coordinate();
+ FloatRect tileRect = it->second->rect();
+ if (!tileRect.intersects(keepRectF))
+ toRemove.append(coordinate);
+ }
+ unsigned removeCount = toRemove.size();
+ for (unsigned n = 0; n < removeCount; ++n)
+ removeTile(toRemove[n]);
+}
+
+PassRefPtr<TiledDrawingAreaTile> TiledDrawingAreaProxy::tileAt(const TiledDrawingAreaTile::Coordinate& coordinate) const
+{
+ return m_tiles.get(coordinate);
+}
+
+void TiledDrawingAreaProxy::setTile(const TiledDrawingAreaTile::Coordinate& coordinate, RefPtr<TiledDrawingAreaTile> tile)
+{
+ m_tiles.set(coordinate, tile);
+ m_tilesByID.set(tile->ID(), tile.get());
+}
+
+void TiledDrawingAreaProxy::removeTile(const TiledDrawingAreaTile::Coordinate& coordinate)
+{
+ RefPtr<TiledDrawingAreaTile> tile = m_tiles.take(coordinate);
+
+ m_tilesByID.remove(tile->ID());
+
+ if (!tile->hasBackBufferUpdatePending())
+ return;
+ WebPageProxy* page = this->page();
+ page->process()->send(DrawingAreaLegacyMessage::CancelTileUpdate, page->pageID(), CoreIPC::In(tile->ID()));
+}
+
+IntRect TiledDrawingAreaProxy::mapToContents(const IntRect& rect) const
+{
+ return enclosingIntRect(FloatRect(rect.x() / m_contentsScale,
+ rect.y() / m_contentsScale,
+ rect.width() / m_contentsScale,
+ rect.height() / m_contentsScale));
+}
+
+IntRect TiledDrawingAreaProxy::mapFromContents(const IntRect& rect) const
+{
+ return enclosingIntRect(FloatRect(rect.x() * m_contentsScale,
+ rect.y() * m_contentsScale,
+ rect.width() * m_contentsScale,
+ rect.height() * m_contentsScale));
+}
+
+IntRect TiledDrawingAreaProxy::contentsRect() const
+{
+ return mapFromContents(IntRect(IntPoint(0, 0), m_viewSize));
+}
+
+IntRect TiledDrawingAreaProxy::tileRectForCoordinate(const TiledDrawingAreaTile::Coordinate& coordinate) const
+{
+ IntRect rect(coordinate.x() * m_tileSize.width(),
+ coordinate.y() * m_tileSize.height(),
+ m_tileSize.width(),
+ m_tileSize.height());
+
+ rect.intersect(contentsRect());
+ return rect;
+}
+
+TiledDrawingAreaTile::Coordinate TiledDrawingAreaProxy::tileCoordinateForPoint(const IntPoint& point) const
+{
+ int x = point.x() / m_tileSize.width();
+ int y = point.y() / m_tileSize.height();
+ return TiledDrawingAreaTile::Coordinate(std::max(x, 0), std::max(y, 0));
+}
+
+
+void TiledDrawingAreaProxy::startTileBufferUpdateTimer()
+{
+ if (m_tileBufferUpdateTimer.isActive())
+ return;
+ m_tileBufferUpdateTimer.startOneShot(0);
+}
+
+void TiledDrawingAreaProxy::tileBufferUpdateTimerFired()
+{
+ updateTileBuffers();
+}
+
+void TiledDrawingAreaProxy::startTileCreationTimer()
+{
+ if (m_tileCreationTimer.isActive())
+ return;
+ m_tileCreationTimer.startOneShot(0);
+}
+
+void TiledDrawingAreaProxy::tileCreationTimerFired()
+{
+ createTiles();
+}
+
+bool TiledDrawingAreaProxy::hasPendingUpdates() const
+{
+ TileMap::const_iterator end = m_tiles.end();
+ for (TileMap::const_iterator it = m_tiles.begin(); it != end; ++it) {
+ const RefPtr<TiledDrawingAreaTile>& current = it->second;
+ if (current->hasBackBufferUpdatePending())
+ return true;
+ }
+ return false;
+}
+
+} // namespace WebKit
+
+#endif