void TiledBackingStore::createTiles() { // Guard here as as these can change before the timer fires. if (isBackingStoreUpdatesSuspended()) return; // Update our backing store geometry. const IntRect previousRect = m_rect; m_rect = mapFromContents(m_client->tiledBackingStoreContentsRect()); const IntRect visibleRect = this->visibleRect(); m_visibleRect = visibleRect; if (visibleRect.isEmpty()) return; IntRect keepRect; IntRect coverRect; computeCoverAndKeepRect(visibleRect, coverRect, keepRect); setKeepRect(keepRect); // Resize tiles at the edge in case the contents size has changed, but only do so // after having dropped tiles outside the keep rect. bool didResizeTiles = false; if (previousRect != m_rect) didResizeTiles = resizeEdgeTiles(); // 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<Tile::Coordinate> tilesToCreate; unsigned requiredTileCount = 0; // Cover areas (in tiles) with minimum distance from the visible rect. If the visible rect is // not covered already it will be covered first in one go, due to the distance being 0 for tiles // inside the visible rect. Tile::Coordinate topLeft = tileCoordinateForPoint(coverRect.location()); Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(coverRect)); for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) { for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) { Tile::Coordinate currentCoordinate(xCoordinate, yCoordinate); if (tileAt(currentCoordinate)) continue; ++requiredTileCount; double distance = tileDistance(visibleRect, currentCoordinate); if (distance > shortestDistance) continue; if (distance < shortestDistance) { tilesToCreate.clear(); shortestDistance = distance; } tilesToCreate.append(currentCoordinate); } } // Now construct the tile(s) within the shortest distance. unsigned tilesToCreateCount = tilesToCreate.size(); for (unsigned n = 0; n < tilesToCreateCount; ++n) { Tile::Coordinate coordinate = tilesToCreate[n]; setTile(coordinate, m_backend->createTile(this, coordinate)); } requiredTileCount -= tilesToCreateCount; // Paint the content of the newly created tiles or resized tiles. if (tilesToCreateCount || didResizeTiles) updateTileBuffers(); // Re-call createTiles on a timer to cover the visible area with the newest shortest distance. if (requiredTileCount) m_backingStoreUpdateTimer.startOneShot(m_tileCreationDelay); }
void TiledBackingStore::createTiles() { if (m_contentsFrozen) return; IntRect visibleRect = visibleContentsRect(); m_previousVisibleRect = visibleRect; if (visibleRect.isEmpty()) return; // Resize tiles on edges in case the contents size has changed. bool didResizeTiles = resizeEdgeTiles(); IntRect keepRect; IntRect coverRect; computeCoverAndKeepRect(visibleRect, coverRect, keepRect); dropTilesOutsideRect(keepRect); // 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<Tile::Coordinate> tilesToCreate; unsigned requiredTileCount = 0; Tile::Coordinate topLeft = tileCoordinateForPoint(coverRect.location()); Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(coverRect)); for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) { for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) { Tile::Coordinate currentCoordinate(xCoordinate, yCoordinate); if (tileAt(currentCoordinate)) continue; ++requiredTileCount; // Distance is 0 for all tiles inside the visibleRect. double distance = tileDistance(visibleRect, currentCoordinate); if (distance > shortestDistance) continue; if (distance < shortestDistance) { tilesToCreate.clear(); shortestDistance = distance; } tilesToCreate.append(currentCoordinate); } } // Now construct the tile(s) within the shortest distance. unsigned tilesToCreateCount = tilesToCreate.size(); for (unsigned n = 0; n < tilesToCreateCount; ++n) { Tile::Coordinate coordinate = tilesToCreate[n]; setTile(coordinate, m_backend->createTile(this, coordinate)); } requiredTileCount -= tilesToCreateCount; // Paint the content of the newly created tiles. if (tilesToCreateCount || didResizeTiles) updateTileBuffers(); // Re-call createTiles on a timer to cover the visible area with the newest shortest distance. if (requiredTileCount) m_tileCreationTimer->startOneShot(m_tileCreationDelay); }
void TiledBackingStore::createTiles() { // Guard here as as these can change before the timer fires. if (isBackingStoreUpdatesSuspended()) return; // Update our backing store geometry. const IntRect previousRect = m_rect; m_rect = mapFromContents(m_client->tiledBackingStoreContentsRect()); m_trajectoryVector = m_pendingTrajectoryVector; m_visibleRect = visibleRect(); if (m_rect.isEmpty()) { setCoverRect(IntRect()); setKeepRect(IntRect()); return; } /* We must compute cover and keep rects using the visibleRect, instead of the rect intersecting the visibleRect with m_rect, * because TBS can be used as a backing store of GraphicsLayer and the visible rect usually does not intersect with m_rect. * In the below case, the intersecting rect is an empty. * * +---------------+ * | | * | m_rect | * | +-------|-----------------------+ * | | HERE | cover or keep | * +---------------+ rect | * | +---------+ | * | | visible | | * | | rect | | * | +---------+ | * | | * | | * +-------------------------------+ * * We must create or keep the tiles in the HERE region. */ IntRect coverRect; IntRect keepRect; computeCoverAndKeepRect(m_visibleRect, coverRect, keepRect); setCoverRect(coverRect); setKeepRect(keepRect); if (coverRect.isEmpty()) return; // Resize tiles at the edge in case the contents size has changed, but only do so // after having dropped tiles outside the keep rect. bool didResizeTiles = false; if (previousRect != m_rect) didResizeTiles = resizeEdgeTiles(); // 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<Tile::Coordinate> tilesToCreate; unsigned requiredTileCount = 0; // Cover areas (in tiles) with minimum distance from the visible rect. If the visible rect is // not covered already it will be covered first in one go, due to the distance being 0 for tiles // inside the visible rect. Tile::Coordinate topLeft = tileCoordinateForPoint(coverRect.location()); Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(coverRect)); for (int yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) { for (int xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) { Tile::Coordinate currentCoordinate(xCoordinate, yCoordinate); if (tileAt(currentCoordinate)) continue; ++requiredTileCount; double distance = tileDistance(m_visibleRect, currentCoordinate); if (distance > shortestDistance) continue; if (distance < shortestDistance) { tilesToCreate.clear(); shortestDistance = distance; } tilesToCreate.append(currentCoordinate); } } // Now construct the tile(s) within the shortest distance. unsigned tilesToCreateCount = tilesToCreate.size(); for (unsigned n = 0; n < tilesToCreateCount; ++n) { Tile::Coordinate coordinate = tilesToCreate[n]; setTile(coordinate, m_backend->createTile(this, coordinate)); } requiredTileCount -= tilesToCreateCount; // Paint the content of the newly created tiles or resized tiles. if (tilesToCreateCount || didResizeTiles) updateTileBuffers(); // Re-call createTiles on a timer to cover the visible area with the newest shortest distance. m_pendingTileCreation = requiredTileCount; if (m_pendingTileCreation) { if (!m_commitTileUpdatesOnIdleEventLoop) { m_client->tiledBackingStoreHasPendingTileCreation(); return; } static const double tileCreationDelay = 0.01; startBackingStoreUpdateTimer(tileCreationDelay); } }