OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/graphics/compositing/PaintArtifactCompositor.h" | 5 #include "platform/graphics/compositing/PaintArtifactCompositor.h" |
6 | 6 |
7 #include "cc/layers/content_layer_client.h" | 7 #include "cc/layers/content_layer_client.h" |
8 #include "cc/layers/layer.h" | 8 #include "cc/layers/layer.h" |
9 #include "cc/layers/picture_layer.h" | 9 #include "cc/layers/picture_layer.h" |
10 #include "cc/playback/display_item_list.h" | 10 #include "cc/playback/display_item_list.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 #include <algorithm> | 43 #include <algorithm> |
44 #include <memory> | 44 #include <memory> |
45 #include <utility> | 45 #include <utility> |
46 | 46 |
47 namespace blink { | 47 namespace blink { |
48 | 48 |
49 class PaintArtifactCompositor::ContentLayerClientImpl : public cc::ContentLayerC lient { | 49 class PaintArtifactCompositor::ContentLayerClientImpl : public cc::ContentLayerC lient { |
50 WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); | 50 WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); |
51 USING_FAST_MALLOC(ContentLayerClientImpl); | 51 USING_FAST_MALLOC(ContentLayerClientImpl); |
52 public: | 52 public: |
53 ContentLayerClientImpl(scoped_refptr<cc::DisplayItemList> list, const gfx::R ect& paintableRegion) | 53 ContentLayerClientImpl(Optional<DisplayItem::Id> paintChunkId) |
54 : m_ccDisplayItemList(std::move(list)), m_paintableRegion(paintableRegio n) { } | 54 : m_id(paintChunkId), m_ccPictureLayer(cc::PictureLayer::Create(this)) |
55 { | |
56 } | |
57 | |
58 void SetDisplayList(scoped_refptr<cc::DisplayItemList> ccDisplayItemList) { m_ccDisplayItemList = std::move(ccDisplayItemList); } | |
59 void SetPaintableRegion(gfx::Rect region) { m_paintableRegion = region; } | |
55 | 60 |
56 // cc::ContentLayerClient | 61 // cc::ContentLayerClient |
57 gfx::Rect PaintableRegion() override { return m_paintableRegion; } | 62 gfx::Rect PaintableRegion() override { return m_paintableRegion; } |
58 scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(PaintingContro lSetting) override | 63 scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(PaintingContro lSetting) override |
59 { | 64 { |
60 return m_ccDisplayItemList; | 65 return m_ccDisplayItemList; |
61 } | 66 } |
62 bool FillsBoundsCompletely() const override { return false; } | 67 bool FillsBoundsCompletely() const override { return false; } |
63 size_t GetApproximateUnsharedMemoryUsage() const override | 68 size_t GetApproximateUnsharedMemoryUsage() const override |
64 { | 69 { |
65 // TODO(jbroman): Actually calculate memory usage. | 70 // TODO(jbroman): Actually calculate memory usage. |
66 return 0; | 71 return 0; |
67 } | 72 } |
68 | 73 |
74 scoped_refptr<cc::PictureLayer> ccPictureLayer() { return m_ccPictureLayer; } | |
75 | |
76 bool matches(const PaintChunk& paintChunk) | |
77 { | |
78 return m_id && paintChunk.id && *m_id == *paintChunk.id; | |
79 } | |
80 | |
69 private: | 81 private: |
82 Optional<PaintChunk::Id> m_id; | |
83 scoped_refptr<cc::PictureLayer> m_ccPictureLayer; | |
70 scoped_refptr<cc::DisplayItemList> m_ccDisplayItemList; | 84 scoped_refptr<cc::DisplayItemList> m_ccDisplayItemList; |
71 gfx::Rect m_paintableRegion; | 85 gfx::Rect m_paintableRegion; |
72 }; | 86 }; |
73 | 87 |
74 PaintArtifactCompositor::PaintArtifactCompositor() | 88 PaintArtifactCompositor::PaintArtifactCompositor() |
75 { | 89 { |
76 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 90 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
77 return; | 91 return; |
78 m_rootLayer = cc::Layer::Create(); | 92 m_rootLayer = cc::Layer::Create(); |
79 m_webLayer = wrapUnique(Platform::current()->compositorSupport()->createLaye rFromCCLayer(m_rootLayer.get())); | 93 m_webLayer = wrapUnique(Platform::current()->compositorSupport()->createLaye rFromCCLayer(m_rootLayer.get())); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree; | 193 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree; |
180 scrollTree.clear(); | 194 scrollTree.clear(); |
181 cc::ScrollNode& scrollNode = *scrollTree.Node(scrollTree.Insert(cc::ScrollNo de(), kRealRootNodeId)); | 195 cc::ScrollNode& scrollNode = *scrollTree.Node(scrollTree.Insert(cc::ScrollNo de(), kRealRootNodeId)); |
182 DCHECK_EQ(scrollNode.id, kSecondaryRootNodeId); | 196 DCHECK_EQ(scrollNode.id, kSecondaryRootNodeId); |
183 scrollNode.owner_id = ownerId; | 197 scrollNode.owner_id = ownerId; |
184 scrollNode.transform_id = kRealRootNodeId; | 198 scrollNode.transform_id = kRealRootNodeId; |
185 } | 199 } |
186 | 200 |
187 } // namespace | 201 } // namespace |
188 | 202 |
189 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs et) | 203 std::unique_ptr<PaintArtifactCompositor::ContentLayerClientImpl> PaintArtifactCo mpositor::clientForPaintChunk(const PaintChunk& paintChunk) |
204 { | |
205 // TODO(chrishtr): for now, just using a linear walk. In the future we can o ptimize this by using the same techniques used in | |
pdr.
2016/09/21 22:45:12
Xianzhu, I think this looks good but can you tripl
chrishtr
2016/09/22 16:51:33
FYI he commented on this earlier in the code revie
| |
206 // PaintController for display lists. | |
207 for (auto& client : m_currentContentLayerClients) { | |
208 if (client && client->matches(paintChunk)) | |
209 return std::move(client); | |
210 } | |
211 return wrapUnique(new ContentLayerClientImpl(paintChunk.id)); | |
212 } | |
213 | |
214 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs et, | |
215 Vector<std::unique_ptr<ContentLayerClientImpl>>& newContentLayerClients) | |
190 { | 216 { |
191 DCHECK(paintChunk.size()); | 217 DCHECK(paintChunk.size()); |
192 | 218 |
193 // If the paint chunk is a foreign layer, just return that layer. | 219 // If the paint chunk is a foreign layer, just return that layer. |
194 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA rtifact, paintChunk, layerOffset)) | 220 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA rtifact, paintChunk, layerOffset)) |
195 return foreignLayer; | 221 return foreignLayer; |
196 | 222 |
197 // The common case: create a layer for painted content. | 223 // The common case: create or reuse a PictureLayer for painted content. |
224 std::unique_ptr<ContentLayerClientImpl> contentLayerClient = clientForPaintC hunk(paintChunk); | |
225 | |
198 gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds); | 226 gfx::Rect combinedBounds = enclosingIntRect(paintChunk.bounds); |
199 scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtif act, paintChunk, combinedBounds); | 227 scoped_refptr<cc::DisplayItemList> displayList = recordPaintChunk(paintArtif act, paintChunk, combinedBounds); |
200 std::unique_ptr<ContentLayerClientImpl> contentLayerClient = wrapUnique( | 228 contentLayerClient->SetDisplayList(std::move(displayList)); |
201 new ContentLayerClientImpl(std::move(displayList), gfx::Rect(combinedBou nds.size()))); | 229 contentLayerClient->SetPaintableRegion(gfx::Rect(combinedBounds.size())); |
202 | 230 |
203 layerOffset = combinedBounds.OffsetFromOrigin(); | 231 layerOffset = combinedBounds.OffsetFromOrigin(); |
204 scoped_refptr<cc::PictureLayer> layer = cc::PictureLayer::Create(contentLaye rClient.get()); | 232 scoped_refptr<cc::PictureLayer> ccPictureLayer = contentLayerClient->ccPictu reLayer(); |
205 layer->SetBounds(combinedBounds.size()); | 233 ccPictureLayer->SetBounds(combinedBounds.size()); |
206 layer->SetIsDrawable(true); | 234 ccPictureLayer->SetIsDrawable(true); |
207 if (paintChunk.knownToBeOpaque) | 235 if (paintChunk.knownToBeOpaque) |
208 layer->SetContentsOpaque(true); | 236 ccPictureLayer->SetContentsOpaque(true); |
209 m_contentLayerClients.append(std::move(contentLayerClient)); | 237 for (auto& invalidation : paintChunk.rasterInvalidationRects) { |
210 return layer; | 238 IntRect rect(enclosingIntRect(invalidation)); |
239 gfx::Rect ccInvalidationRect(rect.x(), rect.y(), std::max(0, rect.width( )), std::max(0, rect.height())); | |
240 // Raster paintChunk.rasterInvalidationRects is in the space of the cont aining transform node, so need to subtract off the layer offset. | |
241 ccInvalidationRect.Offset(-combinedBounds.OffsetFromOrigin()); | |
242 ccPictureLayer->SetNeedsDisplayRect(ccInvalidationRect); | |
243 } | |
244 | |
245 newContentLayerClients.append(std::move(contentLayerClient)); | |
246 return ccPictureLayer; | |
211 } | 247 } |
212 | 248 |
213 namespace { | 249 namespace { |
214 | 250 |
215 class PropertyTreeManager { | 251 class PropertyTreeManager { |
216 WTF_MAKE_NONCOPYABLE(PropertyTreeManager); | 252 WTF_MAKE_NONCOPYABLE(PropertyTreeManager); |
217 public: | 253 public: |
218 PropertyTreeManager(cc::PropertyTrees& propertyTrees, cc::Layer* rootLayer) | 254 PropertyTreeManager(cc::PropertyTrees& propertyTrees, cc::Layer* rootLayer) |
219 : m_propertyTrees(propertyTrees) | 255 : m_propertyTrees(propertyTrees) |
220 , m_rootLayer(rootLayer) | 256 , m_rootLayer(rootLayer) |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
509 m_rootLayer->RemoveAllChildren(); | 545 m_rootLayer->RemoveAllChildren(); |
510 m_rootLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); | 546 m_rootLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
511 m_rootLayer->SetTransformTreeIndex(kSecondaryRootNodeId); | 547 m_rootLayer->SetTransformTreeIndex(kSecondaryRootNodeId); |
512 m_rootLayer->SetClipTreeIndex(kSecondaryRootNodeId); | 548 m_rootLayer->SetClipTreeIndex(kSecondaryRootNodeId); |
513 m_rootLayer->SetEffectTreeIndex(kSecondaryRootNodeId); | 549 m_rootLayer->SetEffectTreeIndex(kSecondaryRootNodeId); |
514 m_rootLayer->SetScrollTreeIndex(kRealRootNodeId); | 550 m_rootLayer->SetScrollTreeIndex(kRealRootNodeId); |
515 | 551 |
516 PropertyTreeManager propertyTreeManager(*layerTree->property_trees(), m_root Layer.get()); | 552 PropertyTreeManager propertyTreeManager(*layerTree->property_trees(), m_root Layer.get()); |
517 propertyTreeManager.setDeviceScaleFactor(layerTree->device_scale_factor()); | 553 propertyTreeManager.setDeviceScaleFactor(layerTree->device_scale_factor()); |
518 | 554 |
519 m_contentLayerClients.clear(); | 555 Vector<std::unique_ptr<ContentLayerClientImpl>> newContentLayerClients; |
520 m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); | 556 newContentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); |
521 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { | 557 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { |
522 gfx::Vector2dF layerOffset; | 558 gfx::Vector2dF layerOffset; |
523 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint Chunk, layerOffset); | 559 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint Chunk, layerOffset, newContentLayerClients); |
524 | 560 |
525 int transformId = propertyTreeManager.compositorIdForTransformNode(paint Chunk.properties.transform.get()); | 561 int transformId = propertyTreeManager.compositorIdForTransformNode(paint Chunk.properties.transform.get()); |
526 int scrollId = propertyTreeManager.compositorIdForScrollNode(paintChunk. properties.scroll.get()); | 562 int scrollId = propertyTreeManager.compositorIdForScrollNode(paintChunk. properties.scroll.get()); |
527 int clipId = propertyTreeManager.compositorIdForClipNode(paintChunk.prop erties.clip.get()); | 563 int clipId = propertyTreeManager.compositorIdForClipNode(paintChunk.prop erties.clip.get()); |
528 int effectId = propertyTreeManager.switchToEffectNode(*paintChunk.proper ties.effect.get()); | 564 int effectId = propertyTreeManager.switchToEffectNode(*paintChunk.proper ties.effect.get()); |
529 | 565 |
530 propertyTreeManager.updateScrollOffset(layer->id(), scrollId); | 566 propertyTreeManager.updateScrollOffset(layer->id(), scrollId); |
531 | 567 |
532 layer->set_offset_to_transform_parent(layerOffset); | 568 layer->set_offset_to_transform_parent(layerOffset); |
533 | 569 |
534 m_rootLayer->AddChild(layer); | 570 m_rootLayer->AddChild(layer); |
535 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); | 571 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
536 layer->SetTransformTreeIndex(transformId); | 572 layer->SetTransformTreeIndex(transformId); |
537 layer->SetClipTreeIndex(clipId); | 573 layer->SetClipTreeIndex(clipId); |
538 layer->SetEffectTreeIndex(effectId); | 574 layer->SetEffectTreeIndex(effectId); |
539 layer->SetScrollTreeIndex(scrollId); | 575 layer->SetScrollTreeIndex(scrollId); |
540 | 576 |
541 // TODO(jbroman): This probably shouldn't be necessary, but it is still | 577 // TODO(jbroman): This probably shouldn't be necessary, but it is still |
542 // queried by RenderSurfaceImpl. | 578 // queried by RenderSurfaceImpl. |
543 layer->Set3dSortingContextId(layerTree->property_trees()->transform_tree .Node(transformId)->sorting_context_id); | 579 layer->Set3dSortingContextId(layerTree->property_trees()->transform_tree .Node(transformId)->sorting_context_id); |
544 | 580 |
545 layer->SetShouldCheckBackfaceVisibility(paintChunk.properties.backfaceHi dden); | 581 layer->SetShouldCheckBackfaceVisibility(paintChunk.properties.backfaceHi dden); |
546 | 582 |
547 if (m_extraDataForTestingEnabled) | 583 if (m_extraDataForTestingEnabled) |
548 m_extraDataForTesting->contentLayers.append(layer); | 584 m_extraDataForTesting->contentLayers.append(layer); |
549 } | 585 } |
586 m_currentContentLayerClients.clear(); | |
587 m_currentContentLayerClients.swap(newContentLayerClients); | |
550 | 588 |
551 // Mark the property trees as having been rebuilt. | 589 // Mark the property trees as having been rebuilt. |
552 layerTree->property_trees()->sequence_number = kPropertyTreeSequenceNumber; | 590 layerTree->property_trees()->sequence_number = kPropertyTreeSequenceNumber; |
553 layerTree->property_trees()->needs_rebuild = false; | 591 layerTree->property_trees()->needs_rebuild = false; |
554 } | 592 } |
555 | 593 |
556 } // namespace blink | 594 } // namespace blink |
OLD | NEW |