void TiledBackingStore::invalidate(const IntRect& contentsDirtyRect) { IntRect dirtyRect(mapFromContents(contentsDirtyRect)); IntRect keepRectFitToTileSize = tileRectForCoordinate(tileCoordinateForPoint(m_keepRect.location())); keepRectFitToTileSize.unite(tileRectForCoordinate(tileCoordinateForPoint(innerBottomRight(m_keepRect)))); // Only iterate on the part of the rect that we know we might have tiles. IntRect coveredDirtyRect = intersection(dirtyRect, keepRectFitToTileSize); Tile::Coordinate topLeft = tileCoordinateForPoint(coveredDirtyRect.location()); Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(coveredDirtyRect)); for (int yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) { for (int xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) { RefPtr<Tile> currentTile = tileAt(Tile::Coordinate(xCoordinate, yCoordinate)); if (!currentTile) continue; // Pass the full rect to each tile as coveredDirtyRect might not // contain them completely and we don't want partial tile redraws. #if PLATFORM(JS) fprintf(stderr, "WebKit: TiledBackingStore: invalidate: invalidating currentTile (x,y,w,h): %i %i %i %i\n",dirtyRect.x(),dirtyRect.y(),dirtyRect.width(),dirtyRect.height()); #endif currentTile->invalidate(dirtyRect); } } startTileBufferUpdateTimer(); }
void TiledBackingStore::paint(GraphicsContext* context, const IntRect& rect) { context->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. context->scale(FloatSize(1.f / m_contentsScale, 1.f / m_contentsScale)); IntRect dirtyRect = mapFromContents(rect); Tile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.location()); Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(dirtyRect)); for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) { for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) { Tile::Coordinate currentCoordinate(xCoordinate, yCoordinate); RefPtr<Tile> currentTile = tileAt(currentCoordinate); if (currentTile && currentTile->isReadyToPaint()) currentTile->paint(context, dirtyRect); else { IntRect tileRect = tileRectForCoordinate(currentCoordinate); IntRect target = intersection(tileRect, dirtyRect); if (target.isEmpty()) continue; m_backend->paintCheckerPattern(context, FloatRect(target)); } } } context->restore(); }
double TiledBackingStore::tileDistance(const IntRect& viewport, const Tile::Coordinate& tileCoordinate) const { if (viewport.intersects(tileRectForCoordinate(tileCoordinate))) return 0; IntPoint viewCenter = viewport.location() + IntSize(viewport.width() / 2, viewport.height() / 2); Tile::Coordinate centerCoordinate = tileCoordinateForPoint(viewCenter); return std::max(abs(centerCoordinate.y() - tileCoordinate.y()), abs(centerCoordinate.x() - tileCoordinate.x())); }
double TiledBackingStore::tileDistance(const IntRect& viewport, const Tile::Coordinate& tileCoordinate) const { if (viewport.intersects(tileRectForCoordinate(tileCoordinate))) return 0; IntPoint viewCenter = viewport.location() + IntSize(viewport.width() / 2, viewport.height() / 2); Tile::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()); }
void TiledBackingStore::dropOverhangingTiles() { IntRect contentsRect = this->contentsRect(); Vector<Tile::Coordinate> tilesToRemove; TileMap::iterator end = m_tiles.end(); for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) { Tile::Coordinate tileCoordinate = it->second->coordinate(); IntRect tileRect = it->second->rect(); IntRect expectedTileRect = tileRectForCoordinate(tileCoordinate); if (expectedTileRect != tileRect || !contentsRect.contains(tileRect)) tilesToRemove.append(tileCoordinate); } unsigned removeCount = tilesToRemove.size(); for (unsigned n = 0; n < removeCount; ++n) removeTile(tilesToRemove[n]); }
void TiledDrawingAreaProxy::paint(const IntRect& rect, PlatformDrawingContext context) { if (m_isWaitingForDidSetFrameNotification) { WebPageProxy* page = this->page(); if (!page->isValid()) return; if (page->process()->isLaunching()) return; } 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); else { IntRect tileRect = tileRectForCoordinate(currentCoordinate); IntRect target = intersection(tileRect, dirtyRect); if (target.isEmpty()) continue; TiledDrawingAreaTile::paintCheckerPattern(&gc, FloatRect(target)); } } } gc.restore(); }
bool TiledBackingStore::resizeEdgeTiles() { bool wasResized = false; Vector<Tile::Coordinate> tilesToRemove; TileMap::iterator end = m_tiles.end(); for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) { Tile::Coordinate tileCoordinate = it->second->coordinate(); IntRect tileRect = it->second->rect(); IntRect expectedTileRect = tileRectForCoordinate(tileCoordinate); if (expectedTileRect.isEmpty()) 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; }