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; |