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" |
11 #include "cc/playback/display_item_list_settings.h" | 11 #include "cc/playback/display_item_list_settings.h" |
12 #include "cc/playback/drawing_display_item.h" | 12 #include "cc/playback/drawing_display_item.h" |
13 #include "cc/playback/transform_display_item.h" | 13 #include "cc/playback/transform_display_item.h" |
14 #include "cc/trees/clip_node.h" | 14 #include "cc/trees/clip_node.h" |
15 #include "cc/trees/effect_node.h" | 15 #include "cc/trees/effect_node.h" |
16 #include "cc/trees/layer_tree_host.h" | 16 #include "cc/trees/layer_tree_host.h" |
17 #include "cc/trees/property_tree.h" | 17 #include "cc/trees/property_tree.h" |
| 18 #include "cc/trees/scroll_node.h" |
18 #include "cc/trees/transform_node.h" | 19 #include "cc/trees/transform_node.h" |
19 #include "platform/RuntimeEnabledFeatures.h" | 20 #include "platform/RuntimeEnabledFeatures.h" |
20 #include "platform/graphics/paint/ClipPaintPropertyNode.h" | 21 #include "platform/graphics/paint/ClipPaintPropertyNode.h" |
21 #include "platform/graphics/paint/DisplayItem.h" | 22 #include "platform/graphics/paint/DisplayItem.h" |
22 #include "platform/graphics/paint/DrawingDisplayItem.h" | 23 #include "platform/graphics/paint/DrawingDisplayItem.h" |
23 #include "platform/graphics/paint/ForeignLayerDisplayItem.h" | 24 #include "platform/graphics/paint/ForeignLayerDisplayItem.h" |
24 #include "platform/graphics/paint/PaintArtifact.h" | 25 #include "platform/graphics/paint/PaintArtifact.h" |
25 #include "platform/graphics/paint/PropertyTreeState.h" | 26 #include "platform/graphics/paint/PropertyTreeState.h" |
| 27 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" |
26 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | 28 #include "platform/graphics/paint/TransformPaintPropertyNode.h" |
27 #include "public/platform/Platform.h" | 29 #include "public/platform/Platform.h" |
28 #include "public/platform/WebCompositorSupport.h" | 30 #include "public/platform/WebCompositorSupport.h" |
29 #include "public/platform/WebLayer.h" | 31 #include "public/platform/WebLayer.h" |
30 #include "ui/gfx/geometry/point.h" | 32 #include "ui/gfx/geometry/point.h" |
31 #include "ui/gfx/geometry/point_f.h" | 33 #include "ui/gfx/geometry/point_f.h" |
32 #include "ui/gfx/geometry/rect.h" | 34 #include "ui/gfx/geometry/rect.h" |
33 #include "ui/gfx/geometry/rect_f.h" | 35 #include "ui/gfx/geometry/rect_f.h" |
34 #include "ui/gfx/geometry/size.h" | 36 #include "ui/gfx/geometry/size.h" |
35 #include "ui/gfx/geometry/size_conversions.h" | 37 #include "ui/gfx/geometry/size_conversions.h" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 cc::EffectTree& effectTree = propertyTrees->effect_tree; | 170 cc::EffectTree& effectTree = propertyTrees->effect_tree; |
169 effectTree.clear(); | 171 effectTree.clear(); |
170 cc::EffectNode& effectNode = *effectTree.Node(effectTree.Insert(cc::EffectNo
de(), kRealRootNodeId)); | 172 cc::EffectNode& effectNode = *effectTree.Node(effectTree.Insert(cc::EffectNo
de(), kRealRootNodeId)); |
171 DCHECK_EQ(effectNode.id, kSecondaryRootNodeId); | 173 DCHECK_EQ(effectNode.id, kSecondaryRootNodeId); |
172 effectNode.owner_id = ownerId; | 174 effectNode.owner_id = ownerId; |
173 effectNode.clip_id = clipNode.id; | 175 effectNode.clip_id = clipNode.id; |
174 effectNode.has_render_surface = true; | 176 effectNode.has_render_surface = true; |
175 | 177 |
176 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree; | 178 cc::ScrollTree& scrollTree = propertyTrees->scroll_tree; |
177 scrollTree.clear(); | 179 scrollTree.clear(); |
| 180 cc::ScrollNode& scrollNode = *scrollTree.Node(scrollTree.Insert(cc::ScrollNo
de(), kRealRootNodeId)); |
| 181 DCHECK_EQ(scrollNode.id, kSecondaryRootNodeId); |
| 182 scrollNode.owner_id = ownerId; |
| 183 scrollNode.transform_id = kRealRootNodeId; |
178 } | 184 } |
179 | 185 |
180 } // namespace | 186 } // namespace |
181 | 187 |
182 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint
Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs
et) | 188 scoped_refptr<cc::Layer> PaintArtifactCompositor::layerForPaintChunk(const Paint
Artifact& paintArtifact, const PaintChunk& paintChunk, gfx::Vector2dF& layerOffs
et) |
183 { | 189 { |
184 DCHECK(paintChunk.size()); | 190 DCHECK(paintChunk.size()); |
185 | 191 |
186 // If the paint chunk is a foreign layer, just return that layer. | 192 // If the paint chunk is a foreign layer, just return that layer. |
187 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA
rtifact, paintChunk, layerOffset)) | 193 if (scoped_refptr<cc::Layer> foreignLayer = foreignLayerForPaintChunk(paintA
rtifact, paintChunk, layerOffset)) |
(...skipping 27 matching lines...) Expand all Loading... |
215 , m_isFirstEffectEver(true) | 221 , m_isFirstEffectEver(true) |
216 #endif | 222 #endif |
217 { | 223 { |
218 m_effectStack.append(BlinkEffectAndCcIdPair{nullptr, kSecondaryRootNodeI
d}); | 224 m_effectStack.append(BlinkEffectAndCcIdPair{nullptr, kSecondaryRootNodeI
d}); |
219 } | 225 } |
220 | 226 |
221 int compositorIdForTransformNode(const TransformPaintPropertyNode*); | 227 int compositorIdForTransformNode(const TransformPaintPropertyNode*); |
222 int compositorIdForClipNode(const ClipPaintPropertyNode*); | 228 int compositorIdForClipNode(const ClipPaintPropertyNode*); |
223 int switchToEffectNode(const EffectPaintPropertyNode& nextEffect); | 229 int switchToEffectNode(const EffectPaintPropertyNode& nextEffect); |
224 int compositorIdForCurrentEffectNode() const { return m_effectStack.last().i
d; } | 230 int compositorIdForCurrentEffectNode() const { return m_effectStack.last().i
d; } |
| 231 int compositorIdForScrollNode(const ScrollPaintPropertyNode*); |
| 232 bool compositorIdExistsForScrollNode(const ScrollPaintPropertyNode* scrollNo
de) |
| 233 { |
| 234 return m_scrollNodeMap.contains(scrollNode); |
| 235 } |
| 236 |
| 237 // Scroll offset has special treatment in the compositor and needs an |
| 238 // adjustment to the transform node (to switch from a transform to a scroll |
| 239 // offset) as well as an update to the ScrollTree scroll offset. |
| 240 void updateScrollOffset(int layerId, int scrollId); |
225 | 241 |
226 private: | 242 private: |
227 void buildEffectNodesRecursively(const EffectPaintPropertyNode* nextEffect); | 243 void buildEffectNodesRecursively(const EffectPaintPropertyNode* nextEffect); |
228 | 244 |
229 cc::TransformTree& transformTree() { return m_propertyTrees.transform_tree;
} | 245 cc::TransformTree& transformTree() { return m_propertyTrees.transform_tree;
} |
230 cc::ClipTree& clipTree() { return m_propertyTrees.clip_tree; } | 246 cc::ClipTree& clipTree() { return m_propertyTrees.clip_tree; } |
231 cc::EffectTree& effectTree() { return m_propertyTrees.effect_tree; } | 247 cc::EffectTree& effectTree() { return m_propertyTrees.effect_tree; } |
| 248 cc::ScrollTree& scrollTree() { return m_propertyTrees.scroll_tree; } |
232 | 249 |
233 const EffectPaintPropertyNode* currentEffectNode() const { return m_effectSt
ack.last().effect; } | 250 const EffectPaintPropertyNode* currentEffectNode() const { return m_effectSt
ack.last().effect; } |
234 | 251 |
235 // Property trees which should be updated by the manager. | 252 // Property trees which should be updated by the manager. |
236 cc::PropertyTrees& m_propertyTrees; | 253 cc::PropertyTrees& m_propertyTrees; |
237 | 254 |
238 // Layer to which transform "owner" layers should be added. These will not | 255 // Layer to which transform "owner" layers should be added. These will not |
239 // have any actual children, but at present must exist in the tree. | 256 // have any actual children, but at present must exist in the tree. |
240 cc::Layer* m_rootLayer; | 257 cc::Layer* m_rootLayer; |
241 | 258 |
242 // Maps from Blink-side property tree nodes to cc property node indices. | 259 // Maps from Blink-side property tree nodes to cc property node indices. |
243 HashMap<const TransformPaintPropertyNode*, int> m_transformNodeMap; | 260 HashMap<const TransformPaintPropertyNode*, int> m_transformNodeMap; |
244 HashMap<const ClipPaintPropertyNode*, int> m_clipNodeMap; | 261 HashMap<const ClipPaintPropertyNode*, int> m_clipNodeMap; |
| 262 HashMap<const ScrollPaintPropertyNode*, int> m_scrollNodeMap; |
245 | 263 |
246 struct BlinkEffectAndCcIdPair { | 264 struct BlinkEffectAndCcIdPair { |
247 const EffectPaintPropertyNode* effect; | 265 const EffectPaintPropertyNode* effect; |
248 int id; | 266 int id; |
249 }; | 267 }; |
250 Vector<BlinkEffectAndCcIdPair> m_effectStack; | 268 Vector<BlinkEffectAndCcIdPair> m_effectStack; |
251 | 269 |
252 #if DCHECK_IS_ON() | 270 #if DCHECK_IS_ON() |
253 HashSet<const EffectPaintPropertyNode*> m_effectNodesConverted; | 271 HashSet<const EffectPaintPropertyNode*> m_effectNodesConverted; |
254 bool m_isFirstEffectEver; | 272 bool m_isFirstEffectEver; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 dummyLayer->SetEffectTreeIndex(kSecondaryRootNodeId); | 344 dummyLayer->SetEffectTreeIndex(kSecondaryRootNodeId); |
327 dummyLayer->SetScrollTreeIndex(kRealRootNodeId); | 345 dummyLayer->SetScrollTreeIndex(kRealRootNodeId); |
328 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); | 346 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
329 | 347 |
330 auto result = m_clipNodeMap.set(clipNode, id); | 348 auto result = m_clipNodeMap.set(clipNode, id); |
331 DCHECK(result.isNewEntry); | 349 DCHECK(result.isNewEntry); |
332 clipTree().set_needs_update(true); | 350 clipTree().set_needs_update(true); |
333 return id; | 351 return id; |
334 } | 352 } |
335 | 353 |
| 354 int PropertyTreeManager::compositorIdForScrollNode(const ScrollPaintPropertyNode
* scrollNode) |
| 355 { |
| 356 if (!scrollNode) |
| 357 return kSecondaryRootNodeId; |
| 358 |
| 359 auto it = m_scrollNodeMap.find(scrollNode); |
| 360 if (it != m_scrollNodeMap.end()) |
| 361 return it->value; |
| 362 |
| 363 int parentId = compositorIdForScrollNode(scrollNode->parent()); |
| 364 int id = scrollTree().Insert(cc::ScrollNode(), parentId); |
| 365 |
| 366 cc::ScrollNode& compositorNode = *scrollTree().Node(id); |
| 367 compositorNode.owner_id = parentId; |
| 368 |
| 369 // TODO(pdr): Set scrollable properly. |
| 370 compositorNode.scrollable = true; |
| 371 |
| 372 // TODO(pdr): Set main thread scrolling reasons. |
| 373 IntSize snappedClip = roundedIntSize(scrollNode->clip()); |
| 374 compositorNode.scroll_clip_layer_bounds.SetSize(snappedClip.width(), snapped
Clip.height()); |
| 375 IntSize snappedBounds = roundedIntSize(scrollNode->bounds()); |
| 376 compositorNode.scroll_clip_layer_bounds.SetSize(snappedBounds.width(), snapp
edBounds.height()); |
| 377 compositorNode.user_scrollable_horizontal = scrollNode->userScrollableHorizo
ntal(); |
| 378 compositorNode.user_scrollable_vertical = scrollNode->userScrollableVertical
(); |
| 379 compositorNode.transform_id = compositorIdForTransformNode(scrollNode->scrol
lOffsetTranslation()); |
| 380 |
| 381 auto result = m_scrollNodeMap.set(scrollNode, id); |
| 382 DCHECK(result.isNewEntry); |
| 383 scrollTree().set_needs_update(true); |
| 384 |
| 385 return id; |
| 386 } |
| 387 |
| 388 void PropertyTreeManager::updateScrollOffset(int layerId, int scrollId) |
| 389 { |
| 390 cc::ScrollNode& scrollNode = *scrollTree().Node(scrollId); |
| 391 cc::TransformNode& transformNode = *transformTree().Node(scrollNode.transfor
m_id); |
| 392 |
| 393 // The transform associated with a scroll should only contain a 2d scroll of
fset. |
| 394 DCHECK(transformNode.local.IsIdentityOr2DTranslation()); |
| 395 |
| 396 // TODO(pdr): Set the transform node's scrollable bit from scrollNode. |
| 397 |
| 398 auto scrollOffsetVector = transformNode.local.To2dTranslation(); |
| 399 |
| 400 // Remove the 2d scroll translation set from blink's transform paint propert
y |
| 401 // node. |
| 402 transformNode.local.MakeIdentity(); |
| 403 |
| 404 gfx::ScrollOffset scrollOffset(scrollOffsetVector.x(), -scrollOffsetVector.y
()); |
| 405 scrollTree().SetScrollOffset(layerId, scrollOffset); |
| 406 |
| 407 // TODO(pdr): Is this needed or can we rely on SetScrollOffset handling it? |
| 408 transformNode.scroll_offset = scrollOffset; |
| 409 } |
| 410 |
336 unsigned depth(const EffectPaintPropertyNode* node) | 411 unsigned depth(const EffectPaintPropertyNode* node) |
337 { | 412 { |
338 unsigned result = 0; | 413 unsigned result = 0; |
339 for (; node; node = node->parent()) | 414 for (; node; node = node->parent()) |
340 result++; | 415 result++; |
341 return result; | 416 return result; |
342 } | 417 } |
343 | 418 |
344 const EffectPaintPropertyNode* lowestCommonAncestor(const EffectPaintPropertyNod
e* nodeA, const EffectPaintPropertyNode* nodeB) | 419 const EffectPaintPropertyNode* lowestCommonAncestor(const EffectPaintPropertyNod
e* nodeA, const EffectPaintPropertyNode* nodeB) |
345 { | 420 { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 m_rootLayer->SetScrollTreeIndex(kRealRootNodeId); | 517 m_rootLayer->SetScrollTreeIndex(kRealRootNodeId); |
443 | 518 |
444 PropertyTreeManager propertyTreeManager(*host->GetLayerTree()->property_tree
s(), m_rootLayer.get()); | 519 PropertyTreeManager propertyTreeManager(*host->GetLayerTree()->property_tree
s(), m_rootLayer.get()); |
445 m_contentLayerClients.clear(); | 520 m_contentLayerClients.clear(); |
446 m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); | 521 m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); |
447 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { | 522 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { |
448 gfx::Vector2dF layerOffset; | 523 gfx::Vector2dF layerOffset; |
449 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint
Chunk, layerOffset); | 524 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint
Chunk, layerOffset); |
450 | 525 |
451 int transformId = propertyTreeManager.compositorIdForTransformNode(paint
Chunk.properties.transform.get()); | 526 int transformId = propertyTreeManager.compositorIdForTransformNode(paint
Chunk.properties.transform.get()); |
| 527 int scrollId = propertyTreeManager.compositorIdForScrollNode(paintChunk.
properties.scroll.get()); |
452 int clipId = propertyTreeManager.compositorIdForClipNode(paintChunk.prop
erties.clip.get()); | 528 int clipId = propertyTreeManager.compositorIdForClipNode(paintChunk.prop
erties.clip.get()); |
453 int effectId = propertyTreeManager.switchToEffectNode(*paintChunk.proper
ties.effect.get()); | 529 int effectId = propertyTreeManager.switchToEffectNode(*paintChunk.proper
ties.effect.get()); |
454 | 530 |
| 531 propertyTreeManager.updateScrollOffset(layer->id(), scrollId); |
| 532 |
455 layer->set_offset_to_transform_parent(layerOffset); | 533 layer->set_offset_to_transform_parent(layerOffset); |
456 | 534 |
457 m_rootLayer->AddChild(layer); | 535 m_rootLayer->AddChild(layer); |
458 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); | 536 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
459 layer->SetTransformTreeIndex(transformId); | 537 layer->SetTransformTreeIndex(transformId); |
460 layer->SetClipTreeIndex(clipId); | 538 layer->SetClipTreeIndex(clipId); |
461 layer->SetEffectTreeIndex(effectId); | 539 layer->SetEffectTreeIndex(effectId); |
462 layer->SetScrollTreeIndex(kRealRootNodeId); | 540 layer->SetScrollTreeIndex(scrollId); |
463 | 541 |
464 // TODO(jbroman): This probably shouldn't be necessary, but it is still | 542 // TODO(jbroman): This probably shouldn't be necessary, but it is still |
465 // queried by RenderSurfaceImpl. | 543 // queried by RenderSurfaceImpl. |
466 layer->Set3dSortingContextId(host->GetLayerTree()->property_trees()->tra
nsform_tree.Node(transformId)->sorting_context_id); | 544 layer->Set3dSortingContextId(host->GetLayerTree()->property_trees()->tra
nsform_tree.Node(transformId)->sorting_context_id); |
467 | 545 |
468 layer->SetShouldCheckBackfaceVisibility(paintChunk.properties.backfaceHi
dden); | 546 layer->SetShouldCheckBackfaceVisibility(paintChunk.properties.backfaceHi
dden); |
469 | 547 |
470 if (m_extraDataForTestingEnabled) | 548 if (m_extraDataForTestingEnabled) |
471 m_extraDataForTesting->contentLayers.append(layer); | 549 m_extraDataForTesting->contentLayers.append(layer); |
472 } | 550 } |
473 | 551 |
474 // Mark the property trees as having been rebuilt. | 552 // Mark the property trees as having been rebuilt. |
475 host->GetLayerTree()->property_trees()->sequence_number = kPropertyTreeSeque
nceNumber; | 553 host->GetLayerTree()->property_trees()->sequence_number = kPropertyTreeSeque
nceNumber; |
476 host->GetLayerTree()->property_trees()->needs_rebuild = false; | 554 host->GetLayerTree()->property_trees()->needs_rebuild = false; |
477 } | 555 } |
478 | 556 |
479 } // namespace blink | 557 } // namespace blink |
OLD | NEW |