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 "TiledDrawingAreaProxy.h"
28
29 #if ENABLE(TILED_BACKING_STORE)
30 #include "DrawingAreaMessageKinds.h"
31 #include "DrawingAreaProxyMessageKinds.h"
32 #include "MessageID.h"
33 #include "UpdateChunk.h"
34 #include "WebCoreArgumentCoders.h"
35 #include "WebPageProxy.h"
36 #include "WebProcessProxy.h"
37
38 using namespace WebCore;
39
40 namespace WebKit {
41
42 static const int defaultTileWidth = 1024;
43 static const int defaultTileHeight = 1024;
44
create(PlatformWebView * webView,WebPageProxy * webPageProxy)45 PassOwnPtr<TiledDrawingAreaProxy> TiledDrawingAreaProxy::create(PlatformWebView* webView, WebPageProxy* webPageProxy)
46 {
47 return adoptPtr(new TiledDrawingAreaProxy(webView, webPageProxy));
48 }
49
TiledDrawingAreaProxy(PlatformWebView * webView,WebPageProxy * webPageProxy)50 TiledDrawingAreaProxy::TiledDrawingAreaProxy(PlatformWebView* webView, WebPageProxy* webPageProxy)
51 : DrawingAreaProxy(DrawingAreaTypeTiled, webPageProxy)
52 , m_isWaitingForDidSetFrameNotification(false)
53 , m_isVisible(true)
54 , m_webView(webView)
55 , m_tileBufferUpdateTimer(RunLoop::main(), this, &TiledDrawingAreaProxy::tileBufferUpdateTimerFired)
56 , m_tileCreationTimer(RunLoop::main(), this, &TiledDrawingAreaProxy::tileCreationTimerFired)
57 , m_tileSize(defaultTileWidth, defaultTileHeight)
58 , m_tileCreationDelay(0.01)
59 , m_keepAreaMultiplier(2.5, 4.5)
60 , m_coverAreaMultiplier(2, 3)
61 , m_contentsScale(1)
62 {
63 }
64
~TiledDrawingAreaProxy()65 TiledDrawingAreaProxy::~TiledDrawingAreaProxy()
66 {
67 }
68
sizeDidChange()69 void TiledDrawingAreaProxy::sizeDidChange()
70 {
71 WebPageProxy* page = this->page();
72 if (!page || !page->isValid())
73 return;
74
75 if (m_size.isEmpty())
76 return;
77
78 m_viewSize = m_size;
79 m_lastSetViewSize = m_size;
80
81 if (m_isWaitingForDidSetFrameNotification)
82 return;
83 m_isWaitingForDidSetFrameNotification = true;
84
85 page->process()->responsivenessTimer()->start();
86 page->process()->deprecatedSend(DrawingAreaLegacyMessage::SetSize, page->pageID(), CoreIPC::In(m_size));
87 }
88
setPageIsVisible(bool isVisible)89 void TiledDrawingAreaProxy::setPageIsVisible(bool isVisible)
90 {
91 WebPageProxy* page = this->page();
92
93 if (isVisible == m_isVisible)
94 return;
95
96 m_isVisible = isVisible;
97 if (!page || !page->isValid())
98 return;
99
100 if (!m_isVisible) {
101 // Tell the web process that it doesn't need to paint anything for now.
102 page->process()->deprecatedSend(DrawingAreaLegacyMessage::SuspendPainting, page->pageID(), CoreIPC::In());
103 return;
104 }
105
106 // The page is now visible.
107 page->process()->deprecatedSend(DrawingAreaLegacyMessage::ResumePainting, page->pageID(), CoreIPC::In());
108
109 // FIXME: We should request a full repaint here if needed.
110 }
111
didSetSize(const IntSize & viewSize)112 void TiledDrawingAreaProxy::didSetSize(const IntSize& viewSize)
113 {
114 ASSERT(m_isWaitingForDidSetFrameNotification);
115 m_isWaitingForDidSetFrameNotification = false;
116
117 if (viewSize != m_lastSetViewSize)
118 setSize(m_lastSetViewSize, IntSize());
119
120 WebPageProxy* page = this->page();
121 page->process()->responsivenessTimer()->stop();
122 }
123
didReceiveMessage(CoreIPC::Connection *,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments)124 void TiledDrawingAreaProxy::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
125 {
126 switch (messageID.get<DrawingAreaProxyLegacyMessage::Kind>()) {
127 case DrawingAreaProxyLegacyMessage::TileUpdated: {
128 int tileID;
129 UpdateChunk updateChunk;
130 float scale;
131 unsigned pendingUpdateCount;
132 if (!arguments->decode(CoreIPC::Out(tileID, updateChunk, scale, pendingUpdateCount)))
133 return;
134
135 TiledDrawingAreaTile* tile = m_tilesByID.get(tileID);
136 ASSERT(!tile || tile->ID() == tileID);
137 if (tile)
138 tile->updateFromChunk(&updateChunk, scale);
139 tileBufferUpdateComplete();
140 break;
141 }
142 case DrawingAreaProxyLegacyMessage::DidSetSize: {
143 IntSize size;
144 if (!arguments->decode(CoreIPC::Out(size)))
145 return;
146
147 didSetSize(size);
148 break;
149 }
150 case DrawingAreaProxyLegacyMessage::Invalidate: {
151 IntRect rect;
152 if (!arguments->decode(CoreIPC::Out(rect)))
153 return;
154
155 invalidate(rect);
156 break;
157 }
158 case DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed: {
159 tileBufferUpdateComplete();
160 break;
161 }
162 case DrawingAreaProxyLegacyMessage::SnapshotTaken: {
163 UpdateChunk chunk;
164 if (!arguments->decode(CoreIPC::Out(chunk)))
165 return;
166 snapshotTaken(chunk);
167 break;
168 }
169 default:
170 ASSERT_NOT_REACHED();
171 }
172 }
173
requestTileUpdate(int tileID,const IntRect & dirtyRect)174 void TiledDrawingAreaProxy::requestTileUpdate(int tileID, const IntRect& dirtyRect)
175 {
176 page()->process()->connection()->deprecatedSend(DrawingAreaLegacyMessage::RequestTileUpdate, page()->pageID(), CoreIPC::In(tileID, dirtyRect, contentsScale()));
177 }
178
waitUntilUpdatesComplete()179 void TiledDrawingAreaProxy::waitUntilUpdatesComplete()
180 {
181 while (hasPendingUpdates()) {
182 int tileID;
183 UpdateChunk updateChunk;
184 float scale;
185 unsigned pendingUpdateCount;
186 static const double tileUpdateTimeout = 10.0;
187 OwnPtr<CoreIPC::ArgumentDecoder> arguments = page()->process()->connection()->deprecatedWaitFor(DrawingAreaProxyLegacyMessage::TileUpdated, page()->pageID(), tileUpdateTimeout);
188 if (!arguments)
189 break;
190 if (!arguments->decode(CoreIPC::Out(tileID, updateChunk, scale, pendingUpdateCount)))
191 break;
192 TiledDrawingAreaTile* tile = m_tilesByID.get(tileID);
193 ASSERT(!tile || tile->ID() == tileID);
194 if (tile)
195 tile->updateFromChunk(&updateChunk, scale);
196 }
197 tileBufferUpdateComplete();
198 }
199
createTile(const TiledDrawingAreaTile::Coordinate & coordinate)200 PassRefPtr<TiledDrawingAreaTile> TiledDrawingAreaProxy::createTile(const TiledDrawingAreaTile::Coordinate& coordinate)
201 {
202 RefPtr<TiledDrawingAreaTile> tile = TiledDrawingAreaTile::create(this, coordinate);
203 setTile(coordinate, tile);
204 return tile;
205 }
206
setTileSize(const IntSize & size)207 void TiledDrawingAreaProxy::setTileSize(const IntSize& size)
208 {
209 if (m_tileSize == size)
210 return;
211 m_tileSize = size;
212 removeAllTiles();
213 startTileCreationTimer();
214 }
215
setTileCreationDelay(double delay)216 void TiledDrawingAreaProxy::setTileCreationDelay(double delay)
217 {
218 m_tileCreationDelay = delay;
219 }
220
setKeepAndCoverAreaMultipliers(const FloatSize & keepMultiplier,const FloatSize & coverMultiplier)221 void TiledDrawingAreaProxy::setKeepAndCoverAreaMultipliers(const FloatSize& keepMultiplier, const FloatSize& coverMultiplier)
222 {
223 m_keepAreaMultiplier = keepMultiplier;
224 m_coverAreaMultiplier = coverMultiplier;
225 startTileCreationTimer();
226 }
227
takeSnapshot(const IntSize & size,const IntRect & contentsRect)228 void TiledDrawingAreaProxy::takeSnapshot(const IntSize& size, const IntRect& contentsRect)
229 {
230 WebPageProxy* page = this->page();
231 page->process()->deprecatedSend(DrawingAreaLegacyMessage::TakeSnapshot, page->pageID(), CoreIPC::Out(size, contentsRect));
232 }
233
invalidate(const IntRect & contentsDirtyRect)234 void TiledDrawingAreaProxy::invalidate(const IntRect& contentsDirtyRect)
235 {
236 IntRect dirtyRect(mapFromContents(contentsDirtyRect));
237
238 TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.location());
239 TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(IntPoint(dirtyRect.maxX(), dirtyRect.maxY()));
240
241 IntRect coverRect = calculateCoverRect(m_previousVisibleRect);
242
243 Vector<TiledDrawingAreaTile::Coordinate> tilesToRemove;
244
245 for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
246 for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
247 RefPtr<TiledDrawingAreaTile> currentTile = tileAt(TiledDrawingAreaTile::Coordinate(xCoordinate, yCoordinate));
248 if (!currentTile)
249 continue;
250 if (!currentTile->rect().intersects(dirtyRect))
251 continue;
252 // If a tile outside out current cover rect gets invalidated, just drop it instead of updating.
253 if (!currentTile->rect().intersects(coverRect)) {
254 tilesToRemove.append(currentTile->coordinate());
255 continue;
256 }
257 currentTile->invalidate(dirtyRect);
258 }
259 }
260
261 unsigned removeCount = tilesToRemove.size();
262 for (unsigned n = 0; n < removeCount; ++n)
263 removeTile(tilesToRemove[n]);
264
265 startTileBufferUpdateTimer();
266 }
267
updateTileBuffers()268 void TiledDrawingAreaProxy::updateTileBuffers()
269 {
270 Vector<RefPtr<TiledDrawingAreaTile> > newDirtyTiles;
271 TileMap::iterator end = m_tiles.end();
272 for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
273 RefPtr<TiledDrawingAreaTile>& current = it->second;
274 if (!current->isDirty())
275 continue;
276 newDirtyTiles.append(it->second);
277 }
278
279 if (newDirtyTiles.isEmpty())
280 return;
281
282 unsigned size = newDirtyTiles.size();
283 for (unsigned n = 0; n < size; ++n)
284 newDirtyTiles[n]->updateBackBuffer();
285 }
286
tileBufferUpdateComplete()287 void TiledDrawingAreaProxy::tileBufferUpdateComplete()
288 {
289 // Bail out if all tile back buffers have not been updated.
290 Vector<TiledDrawingAreaTile*> tilesToFlip;
291 TileMap::iterator end = m_tiles.end();
292 for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
293 RefPtr<TiledDrawingAreaTile>& current = it->second;
294 if (current->isReadyToPaint() && (current->isDirty() || current->hasBackBufferUpdatePending()))
295 return;
296 if (current->hasReadyBackBuffer())
297 tilesToFlip.append(current.get());
298 }
299 // Everything done, move back buffers to front.
300 Vector<IntRect> paintedArea;
301 unsigned size = tilesToFlip.size();
302 for (unsigned n = 0; n < size; ++n) {
303 TiledDrawingAreaTile* tile = tilesToFlip[n];
304 tile->swapBackBufferToFront();
305 // FIXME: should not request system repaint for the full tile.
306 paintedArea.append(mapToContents(tile->rect()));
307 }
308 if (size)
309 updateWebView(paintedArea);
310
311 m_tileCreationTimer.startOneShot(0);
312 }
313
paint(const IntRect & rect,PlatformDrawingContext context)314 bool TiledDrawingAreaProxy::paint(const IntRect& rect, PlatformDrawingContext context)
315 {
316 if (m_isWaitingForDidSetFrameNotification) {
317 WebPageProxy* page = this->page();
318 if (!page->isValid())
319 return false;
320
321 if (page->process()->isLaunching())
322 return false;
323 }
324
325 adjustVisibleRect();
326
327 GraphicsContext gc(context);
328 gc.save();
329
330 // Assumes the backing store is painted with the scale transform applied.
331 // Since tile content is already scaled, first revert the scaling from the painter.
332 gc.scale(FloatSize(1 / m_contentsScale, 1 / m_contentsScale));
333
334 IntRect dirtyRect = mapFromContents(rect);
335
336 TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.location());
337 TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(IntPoint(dirtyRect.maxX(), dirtyRect.maxY()));
338
339 for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
340 for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
341 TiledDrawingAreaTile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
342 RefPtr<TiledDrawingAreaTile> currentTile = tileAt(currentCoordinate);
343 if (currentTile && currentTile->isReadyToPaint())
344 currentTile->paint(&gc, dirtyRect);
345 }
346 }
347
348 gc.restore();
349 return true;
350 }
351
adjustVisibleRect()352 void TiledDrawingAreaProxy::adjustVisibleRect()
353 {
354 IntRect visibleRect = mapFromContents(webViewVisibleRect());
355 if (m_previousVisibleRect == visibleRect)
356 return;
357 m_previousVisibleRect = visibleRect;
358
359 startTileCreationTimer();
360 }
361
setContentsScale(float scale)362 void TiledDrawingAreaProxy::setContentsScale(float scale)
363 {
364 if (m_contentsScale == scale)
365 return;
366 m_contentsScale = scale;
367 removeAllTiles();
368 createTiles();
369 }
370
removeAllTiles()371 void TiledDrawingAreaProxy::removeAllTiles()
372 {
373 Vector<RefPtr<TiledDrawingAreaTile> > tilesToRemove;
374 copyValuesToVector(m_tiles, tilesToRemove);
375 unsigned removeCount = tilesToRemove.size();
376 for (unsigned n = 0; n < removeCount; ++n)
377 removeTile(tilesToRemove[n]->coordinate());
378 }
379
tileDistance(const IntRect & viewport,const TiledDrawingAreaTile::Coordinate & tileCoordinate)380 double TiledDrawingAreaProxy::tileDistance(const IntRect& viewport, const TiledDrawingAreaTile::Coordinate& tileCoordinate)
381 {
382 if (viewport.intersects(tileRectForCoordinate(tileCoordinate)))
383 return 0;
384
385 IntPoint viewCenter = viewport.location() + IntSize(viewport.width() / 2, viewport.height() / 2);
386 TiledDrawingAreaTile::Coordinate centerCoordinate = tileCoordinateForPoint(viewCenter);
387
388 // Manhattan distance, biased so that vertical distances are shorter.
389 const double horizontalBias = 1.3;
390 return abs(centerCoordinate.y() - tileCoordinate.y()) + horizontalBias * abs(centerCoordinate.x() - tileCoordinate.x());
391 }
392
calculateKeepRect(const IntRect & visibleRect) const393 IntRect TiledDrawingAreaProxy::calculateKeepRect(const IntRect& visibleRect) const
394 {
395 IntRect result = visibleRect;
396 // Inflates to both sides, so divide inflate delta by 2
397 result.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1) / 2);
398 result.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1) / 2);
399 result.intersect(contentsRect());
400 return result;
401 }
402
calculateCoverRect(const IntRect & visibleRect) const403 IntRect TiledDrawingAreaProxy::calculateCoverRect(const IntRect& visibleRect) const
404 {
405 IntRect result = visibleRect;
406 // Inflates to both sides, so divide inflate delta by 2
407 result.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1) / 2);
408 result.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1) / 2);
409 result.intersect(contentsRect());
410 return result;
411 }
412
createTiles()413 void TiledDrawingAreaProxy::createTiles()
414 {
415 IntRect visibleRect = mapFromContents(webViewVisibleRect());
416 m_previousVisibleRect = visibleRect;
417
418 if (visibleRect.isEmpty())
419 return;
420
421 // Resize tiles on edges in case the contents size has changed.
422 bool didResizeTiles = resizeEdgeTiles();
423
424 // Remove tiles outside out current maximum keep rect.
425 dropTilesOutsideRect(calculateKeepRect(visibleRect));
426
427 // Cover the cover rect with tiles.
428 IntRect coverRect = calculateCoverRect(visibleRect);
429
430 // Search for the tile position closest to the viewport center that does not yet contain a tile.
431 // Which position is considered the closest depends on the tileDistance function.
432 double shortestDistance = std::numeric_limits<double>::infinity();
433 Vector<TiledDrawingAreaTile::Coordinate> tilesToCreate;
434 unsigned requiredTileCount = 0;
435 bool hasVisibleCheckers = false;
436 TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(visibleRect.location());
437 TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(IntPoint(visibleRect.maxX(), visibleRect.maxY()));
438 for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
439 for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
440 TiledDrawingAreaTile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
441 // Distance is 0 for all currently visible tiles.
442 double distance = tileDistance(visibleRect, currentCoordinate);
443
444 RefPtr<TiledDrawingAreaTile> tile = tileAt(currentCoordinate);
445 if (!distance && (!tile || !tile->isReadyToPaint()))
446 hasVisibleCheckers = true;
447 if (tile)
448 continue;
449
450 ++requiredTileCount;
451
452 if (distance > shortestDistance)
453 continue;
454 if (distance < shortestDistance) {
455 tilesToCreate.clear();
456 shortestDistance = distance;
457 }
458 tilesToCreate.append(currentCoordinate);
459 }
460 }
461
462 if (hasVisibleCheckers && shortestDistance > 0)
463 return;
464
465 // Now construct the tile(s).
466 unsigned tilesToCreateCount = tilesToCreate.size();
467 for (unsigned n = 0; n < tilesToCreateCount; ++n)
468 createTile(tilesToCreate[n]);
469
470 requiredTileCount -= tilesToCreateCount;
471
472 // Paint the content of the newly created tiles.
473 if (tilesToCreateCount || didResizeTiles)
474 updateTileBuffers();
475
476 // Keep creating tiles until the whole coverRect is covered.
477 if (requiredTileCount)
478 m_tileCreationTimer.startOneShot(m_tileCreationDelay);
479 }
480
resizeEdgeTiles()481 bool TiledDrawingAreaProxy::resizeEdgeTiles()
482 {
483 IntRect contentsRect = this->contentsRect();
484 bool wasResized = false;
485
486 Vector<TiledDrawingAreaTile::Coordinate> tilesToRemove;
487 TileMap::iterator end = m_tiles.end();
488 for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
489 TiledDrawingAreaTile::Coordinate tileCoordinate = it->second->coordinate();
490 IntRect tileRect = it->second->rect();
491 IntRect expectedTileRect = tileRectForCoordinate(tileCoordinate);
492 if (!contentsRect.contains(tileRect))
493 tilesToRemove.append(tileCoordinate);
494 else if (expectedTileRect != tileRect) {
495 it->second->resize(expectedTileRect.size());
496 wasResized = true;
497 }
498 }
499 unsigned removeCount = tilesToRemove.size();
500 for (unsigned n = 0; n < removeCount; ++n)
501 removeTile(tilesToRemove[n]);
502 return wasResized;
503 }
504
dropTilesOutsideRect(const IntRect & keepRect)505 void TiledDrawingAreaProxy::dropTilesOutsideRect(const IntRect& keepRect)
506 {
507 FloatRect keepRectF = keepRect;
508
509 Vector<TiledDrawingAreaTile::Coordinate> toRemove;
510 TileMap::iterator end = m_tiles.end();
511 for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
512 TiledDrawingAreaTile::Coordinate coordinate = it->second->coordinate();
513 FloatRect tileRect = it->second->rect();
514 if (!tileRect.intersects(keepRectF))
515 toRemove.append(coordinate);
516 }
517 unsigned removeCount = toRemove.size();
518 for (unsigned n = 0; n < removeCount; ++n)
519 removeTile(toRemove[n]);
520 }
521
tileAt(const TiledDrawingAreaTile::Coordinate & coordinate) const522 PassRefPtr<TiledDrawingAreaTile> TiledDrawingAreaProxy::tileAt(const TiledDrawingAreaTile::Coordinate& coordinate) const
523 {
524 return m_tiles.get(coordinate);
525 }
526
setTile(const TiledDrawingAreaTile::Coordinate & coordinate,RefPtr<TiledDrawingAreaTile> tile)527 void TiledDrawingAreaProxy::setTile(const TiledDrawingAreaTile::Coordinate& coordinate, RefPtr<TiledDrawingAreaTile> tile)
528 {
529 m_tiles.set(coordinate, tile);
530 m_tilesByID.set(tile->ID(), tile.get());
531 }
532
removeTile(const TiledDrawingAreaTile::Coordinate & coordinate)533 void TiledDrawingAreaProxy::removeTile(const TiledDrawingAreaTile::Coordinate& coordinate)
534 {
535 RefPtr<TiledDrawingAreaTile> tile = m_tiles.take(coordinate);
536
537 m_tilesByID.remove(tile->ID());
538
539 if (!tile->hasBackBufferUpdatePending())
540 return;
541 WebPageProxy* page = this->page();
542 page->process()->deprecatedSend(DrawingAreaLegacyMessage::CancelTileUpdate, page->pageID(), CoreIPC::In(tile->ID()));
543 }
544
mapToContents(const IntRect & rect) const545 IntRect TiledDrawingAreaProxy::mapToContents(const IntRect& rect) const
546 {
547 return enclosingIntRect(FloatRect(rect.x() / m_contentsScale,
548 rect.y() / m_contentsScale,
549 rect.width() / m_contentsScale,
550 rect.height() / m_contentsScale));
551 }
552
mapFromContents(const IntRect & rect) const553 IntRect TiledDrawingAreaProxy::mapFromContents(const IntRect& rect) const
554 {
555 return enclosingIntRect(FloatRect(rect.x() * m_contentsScale,
556 rect.y() * m_contentsScale,
557 rect.width() * m_contentsScale,
558 rect.height() * m_contentsScale));
559 }
560
contentsRect() const561 IntRect TiledDrawingAreaProxy::contentsRect() const
562 {
563 return mapFromContents(IntRect(IntPoint(0, 0), m_viewSize));
564 }
565
tileRectForCoordinate(const TiledDrawingAreaTile::Coordinate & coordinate) const566 IntRect TiledDrawingAreaProxy::tileRectForCoordinate(const TiledDrawingAreaTile::Coordinate& coordinate) const
567 {
568 IntRect rect(coordinate.x() * m_tileSize.width(),
569 coordinate.y() * m_tileSize.height(),
570 m_tileSize.width(),
571 m_tileSize.height());
572
573 rect.intersect(contentsRect());
574 return rect;
575 }
576
tileCoordinateForPoint(const IntPoint & point) const577 TiledDrawingAreaTile::Coordinate TiledDrawingAreaProxy::tileCoordinateForPoint(const IntPoint& point) const
578 {
579 int x = point.x() / m_tileSize.width();
580 int y = point.y() / m_tileSize.height();
581 return TiledDrawingAreaTile::Coordinate(std::max(x, 0), std::max(y, 0));
582 }
583
584
startTileBufferUpdateTimer()585 void TiledDrawingAreaProxy::startTileBufferUpdateTimer()
586 {
587 if (m_tileBufferUpdateTimer.isActive())
588 return;
589 m_tileBufferUpdateTimer.startOneShot(0);
590 }
591
tileBufferUpdateTimerFired()592 void TiledDrawingAreaProxy::tileBufferUpdateTimerFired()
593 {
594 updateTileBuffers();
595 }
596
startTileCreationTimer()597 void TiledDrawingAreaProxy::startTileCreationTimer()
598 {
599 if (m_tileCreationTimer.isActive())
600 return;
601 m_tileCreationTimer.startOneShot(0);
602 }
603
tileCreationTimerFired()604 void TiledDrawingAreaProxy::tileCreationTimerFired()
605 {
606 createTiles();
607 }
608
hasPendingUpdates() const609 bool TiledDrawingAreaProxy::hasPendingUpdates() const
610 {
611 TileMap::const_iterator end = m_tiles.end();
612 for (TileMap::const_iterator it = m_tiles.begin(); it != end; ++it) {
613 const RefPtr<TiledDrawingAreaTile>& current = it->second;
614 if (current->hasBackBufferUpdatePending())
615 return true;
616 }
617 return false;
618 }
619
620 } // namespace WebKit
621
622 #endif
623