void TiledLayerChromium::pushPropertiesTo(CCLayerImpl* layer) { LayerChromium::pushPropertiesTo(layer); CCTiledLayerImpl* tiledLayer = static_cast<CCTiledLayerImpl*>(layer); tiledLayer->setSkipsDraw(m_skipsDraw); tiledLayer->setContentsSwizzled(m_sampledTexelFormat != LayerTextureUpdater::SampledTexelFormatRGBA); tiledLayer->setTilingData(*m_tiler); Vector<UpdatableTile*> invalidTiles; for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin(); iter != m_tiler->tiles().end(); ++iter) { int i = iter->first.first; int j = iter->first.second; UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second.get()); if (!tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat)) { invalidTiles.append(tile); continue; } if (tile->isDirty()) continue; tiledLayer->pushTileProperties(i, j, tile->managedTexture()->textureId(), tile->m_opaqueRect); } for (Vector<UpdatableTile*>::const_iterator iter = invalidTiles.begin(); iter != invalidTiles.end(); ++iter) m_tiler->takeTile((*iter)->i(), (*iter)->j()); }
bool TiledLayerChromium::needsIdlePaint(const IntRect& layerRect) { if (m_skipsIdlePaint) return false; IntRect idlePaintLayerRect = idlePaintRect(layerRect); int left, top, right, bottom; m_tiler->layerRectToTileIndices(idlePaintLayerRect, left, top, right, bottom); for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { if (m_requestedUpdateTilesRect.contains(IntPoint(i, j))) continue; UpdatableTile* tile = tileAt(i, j); if (!tile || !tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat) || tile->isDirty()) return true; } } return false; }
void TiledLayerChromium::prepareToUpdateTiles(bool idle, int left, int top, int right, int bottom) { // Reset m_updateRect for all tiles. for (CCLayerTilingData::TileMap::const_iterator iter = m_tiler->tiles().begin(); iter != m_tiler->tiles().end(); ++iter) { UpdatableTile* tile = static_cast<UpdatableTile*>(iter->second.get()); tile->m_updateRect = IntRect(); } // Create tiles as needed, expanding a dirty rect to contain all // the dirty regions currently being drawn. All dirty tiles that are to be painted // get their m_updateRect set to m_dirtyRect and m_dirtyRect cleared. This way if // invalidateRect is invoked during prepareToUpdate we don't lose the request. IntRect dirtyLayerRect; for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { UpdatableTile* tile = tileAt(i, j); if (!tile) tile = createTile(i, j); // Do post commit deletion of current texture when partial texture // updates are not used. if (tile->isDirty() && layerTreeHost() && !layerTreeHost()->settings().partialTextureUpdates) layerTreeHost()->deleteTextureAfterCommit(tile->managedTexture()->steal()); if (!tile->managedTexture()->isValid(m_tiler->tileSize(), m_textureFormat)) tile->m_dirtyRect = m_tiler->tileRect(tile); if (!tile->managedTexture()->reserve(m_tiler->tileSize(), m_textureFormat)) { m_skipsIdlePaint = true; if (!idle) { m_skipsDraw = true; cleanupResources(); } return; } dirtyLayerRect.unite(tile->m_dirtyRect); tile->copyAndClearDirty(); } } m_paintRect = dirtyLayerRect; if (dirtyLayerRect.isEmpty()) return; // Due to borders, when the paint rect is extended to tile boundaries, it // may end up overlapping more tiles than the original content rect. Record // the original tiles so we don't upload more tiles than necessary. if (!m_paintRect.isEmpty()) m_requestedUpdateTilesRect = IntRect(left, top, right - left + 1, bottom - top + 1); // Calling prepareToUpdate() calls into WebKit to paint, which may have the side // effect of disabling compositing, which causes our reference to the texture updater to be deleted. // However, we can't free the memory backing the GraphicsContext until the paint finishes, // so we grab a local reference here to hold the updater alive until the paint completes. RefPtr<LayerTextureUpdater> protector(textureUpdater()); IntRect opaqueRect; // FIXME: unused. remove this and store in the layer to pass to impl for draw culling textureUpdater()->prepareToUpdate(m_paintRect, m_tiler->tileSize(), m_tiler->hasBorderTexels(), contentsScale(), &opaqueRect); for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { UpdatableTile* tile = tileAt(i, j); // Tiles are created before prepareToUpdate() is called. if (!tile) CRASH(); // Use m_updateRect as copyAndClearDirty above moved the existing dirty rect to m_updateRect. const IntRect& dirtyRect = tile->m_updateRect; if (dirtyRect.isEmpty()) continue; IntRect sourceRect = m_tiler->tileRect(tile); sourceRect.intersect(dirtyRect); // Paint rect not guaranteed to line up on tile boundaries, so // make sure that sourceRect doesn't extend outside of it. sourceRect.intersect(m_paintRect); tile->m_updateRect = sourceRect; if (sourceRect.isEmpty()) continue; tile->texture()->prepareRect(sourceRect); } } }