Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
| index d503ab78d171498ea369f6223c85306be250f9db..cad2d5cb07554a7db260a03645ba7c32a1c491e7 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp |
| @@ -50,8 +50,13 @@ class PaintArtifactCompositor::ContentLayerClientImpl : public cc::ContentLayerC |
| WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); |
| USING_FAST_MALLOC(ContentLayerClientImpl); |
| public: |
| - ContentLayerClientImpl(scoped_refptr<cc::DisplayItemList> list, const gfx::Rect& paintableRegion) |
| - : m_ccDisplayItemList(std::move(list)), m_paintableRegion(paintableRegion) { } |
| + ContentLayerClientImpl(Optional<DisplayItem::Id> paintChunkId) |
| + : m_id(paintChunkId), m_ccPictureLayer(cc::PictureLayer::Create(this)) |
| + { |
| + } |
| + |
| + void SetDisplayList(scoped_refptr<cc::DisplayItemList> ccDisplayItemList) { m_ccDisplayItemList = std::move(ccDisplayItemList); } |
| + void SetPaintableRegion(gfx::Rect region) { m_paintableRegion = region; } |
| // cc::ContentLayerClient |
| gfx::Rect PaintableRegion() override { return m_paintableRegion; } |
| @@ -66,7 +71,16 @@ public: |
| return 0; |
| } |
| + scoped_refptr<cc::PictureLayer> ccPictureLayer() { return m_ccPictureLayer; } |
| + |
| + bool matches(const PaintChunk& paintChunk) |
| + { |
| + return m_id && paintChunk.id && *m_id == *paintChunk.id; |
| + } |
| + |
| private: |
| + Optional<PaintChunk::Id> m_id; |
| + scoped_refptr<cc::PictureLayer> m_ccPictureLayer; |
| scoped_refptr<cc::DisplayItemList> m_ccDisplayItemList; |
| gfx::Rect m_paintableRegion; |
| }; |
| @@ -186,6 +200,15 @@ void setMinimalPropertyTrees(cc::PropertyTrees* propertyTrees, int ownerId) |
| } // namespace |
| +std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> PaintArtifactCompositor::clientForPaintChunk(const PaintChunk& paintChunk) |
| +{ |
| + for (auto& client : m_currentContentLayerClients) { |
| + if (client && client->matches(paintChunk)) |
| + return std::move(client); |
| + } |
|
Xianzhu
2016/09/20 23:13:41
I'm a bit concerned about performance here. Perhap
chrishtr
2016/09/20 23:43:59
Oh, forgot to add a TODO about this. I agree.
|
| + return wrapUnique(new ContentLayerClientImpl(paintChunk.id)); |
| +} |
| + |
| scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const PaintArtifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffset) |
| { |
| DCHECK(paintChunk.size()); |
| @@ -194,20 +217,30 @@ scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint |
| if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintArtifact, paintChunk, layerOffset)) |
| return foreignLayer; |
| - // The common case: create a layer for painted content. |
| + // The common case: create or reuse a PictureLayer for painted content. |
| + std::unique_ptr<ContentLayerClientImpl> contentLayerClient = clientForPaintChunk(paintChunk); |
| + |
| gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds); |
| scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtifact, paintChunk, combinedBounds); |
| - std::unique_ptr<ContentLayerClientImpl> contentLayerClient = wrapUnique( |
| - new ContentLayerClientImpl(std::move(displayList), gfx::Rect(combinedBounds.size()))); |
| + contentLayerClient->SetDisplayList(std::move(displayList)); |
| + contentLayerClient->SetPaintableRegion(gfx::Rect(combinedBounds.size())); |
| layerOffset = combinedBounds.OffsetFromOrigin(); |
| - scoped_refptr<cc::PictureLayer> layer = cc::PictureLayer::Create(contentLayerClient.get()); |
| - layer->SetBounds(combinedBounds.size()); |
| - layer->SetIsDrawable(true); |
| + scoped_refptr<cc::PictureLayer> ccPictureLayer = contentLayerClient->ccPictureLayer(); |
| + ccPictureLayer->SetBounds(combinedBounds.size()); |
| + ccPictureLayer->SetIsDrawable(true); |
| if (paintChunk.knownToBeOpaque) |
| - layer->SetContentsOpaque(true); |
| - m_contentLayerClients.append(std::move(contentLayerClient)); |
| - return layer; |
| + ccPictureLayer->SetContentsOpaque(true); |
| + for (auto& invalidation : paintChunk.rasterInvalidationRects) { |
| + IntRect rect(enclosingIntRect(invalidation)); |
| + gfx::Rect ccInvalidationRect(rect.x(), rect.y(), std::max(0, rect.width()), std::max(0, rect.height())); |
| + // Raster paintChunk.rasterInvalidationRects is in the space of the containing transform node, so need to subtract off the layer offset. |
| + ccInvalidationRect.Offset(-combinedBounds.OffsetFromOrigin()); |
| + ccPictureLayer->SetNeedsDisplayRect(ccInvalidationRect); |
| + } |
| + |
| + m_newContentLayerClients.append(std::move(contentLayerClient)); |
| + return ccPictureLayer; |
| } |
| namespace { |
| @@ -516,8 +549,7 @@ void PaintArtifactCompositor::update(const PaintArtifact& paintArtifact) |
| PropertyTreeManager propertyTreeManager(*layerTree->property_trees(), m_rootLayer.get()); |
| propertyTreeManager.setDeviceScaleFactor(layerTree->device_scale_factor()); |
| - m_contentLayerClients.clear(); |
| - m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); |
| + m_newContentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); |
| for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { |
| gfx::Vector2dF layerOffset; |
| scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paintChunk, layerOffset); |
| @@ -547,6 +579,8 @@ void PaintArtifactCompositor::update(const PaintArtifact& paintArtifact) |
| if (m_extraDataForTestingEnabled) |
| m_extraDataForTesting->contentLayers.append(layer); |
| } |
| + m_currentContentLayerClients.clear(); |
| + m_currentContentLayerClients.swap(m_newContentLayerClients); |
| // Mark the property trees as having been rebuilt. |
| layerTree->property_trees()->sequence_number = kPropertyTreeSequenceNumber; |