| 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 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 return layer; | 338 return layer; |
| 339 } | 339 } |
| 340 | 340 |
| 341 namespace { | 341 namespace { |
| 342 | 342 |
| 343 class PropertyTreeManager { | 343 class PropertyTreeManager { |
| 344 WTF_MAKE_NONCOPYABLE(PropertyTreeManager); | 344 WTF_MAKE_NONCOPYABLE(PropertyTreeManager); |
| 345 public: | 345 public: |
| 346 PropertyTreeManager(cc::PropertyTrees& propertyTrees, cc::Layer* rootLayer) | 346 PropertyTreeManager(cc::PropertyTrees& propertyTrees, cc::Layer* rootLayer) |
| 347 : m_propertyTrees(propertyTrees) | 347 : m_propertyTrees(propertyTrees) |
| 348 , m_rootLayer(rootLayer) {} | 348 , m_rootLayer(rootLayer) |
| 349 #if DCHECK_IS_ON() |
| 350 , m_isFirstEffectEver(true) |
| 351 #endif |
| 352 { |
| 353 m_effectStack.append(BlinkEffectAndCcIdPair{nullptr, kSecondaryRootNodeI
d}); |
| 354 } |
| 349 | 355 |
| 350 int compositorIdForTransformNode(const TransformPaintPropertyNode*); | 356 int compositorIdForTransformNode(const TransformPaintPropertyNode*); |
| 351 int compositorIdForClipNode(const ClipPaintPropertyNode*); | 357 int compositorIdForClipNode(const ClipPaintPropertyNode*); |
| 358 int switchToEffectNode(const EffectPaintPropertyNode& nextEffect); |
| 359 int compositorIdForCurrentEffectNode() const { return m_effectStack.last().i
d; } |
| 352 | 360 |
| 353 private: | 361 private: |
| 362 void buildEffectNodesRecursively(const EffectPaintPropertyNode* nextEffect); |
| 363 |
| 354 cc::TransformTree& transformTree() { return m_propertyTrees.transform_tree;
} | 364 cc::TransformTree& transformTree() { return m_propertyTrees.transform_tree;
} |
| 355 cc::ClipTree& clipTree() { return m_propertyTrees.clip_tree; } | 365 cc::ClipTree& clipTree() { return m_propertyTrees.clip_tree; } |
| 366 cc::EffectTree& effectTree() { return m_propertyTrees.effect_tree; } |
| 367 |
| 368 const EffectPaintPropertyNode* currentEffectNode() const { return m_effectSt
ack.last().effect; } |
| 356 | 369 |
| 357 // Property trees which should be updated by the manager. | 370 // Property trees which should be updated by the manager. |
| 358 cc::PropertyTrees& m_propertyTrees; | 371 cc::PropertyTrees& m_propertyTrees; |
| 359 | 372 |
| 360 // Layer to which transform "owner" layers should be added. These will not | 373 // Layer to which transform "owner" layers should be added. These will not |
| 361 // have any actual children, but at present must exist in the tree. | 374 // have any actual children, but at present must exist in the tree. |
| 362 cc::Layer* m_rootLayer; | 375 cc::Layer* m_rootLayer; |
| 363 | 376 |
| 364 // Maps from Blink-side property tree nodes to cc property node indices. | 377 // Maps from Blink-side property tree nodes to cc property node indices. |
| 365 HashMap<const TransformPaintPropertyNode*, int> m_transformNodeMap; | 378 HashMap<const TransformPaintPropertyNode*, int> m_transformNodeMap; |
| 366 HashMap<const ClipPaintPropertyNode*, int> m_clipNodeMap; | 379 HashMap<const ClipPaintPropertyNode*, int> m_clipNodeMap; |
| 380 |
| 381 struct BlinkEffectAndCcIdPair { |
| 382 const EffectPaintPropertyNode* effect; |
| 383 int id; |
| 384 }; |
| 385 Vector<BlinkEffectAndCcIdPair> m_effectStack; |
| 386 |
| 387 #if DCHECK_IS_ON() |
| 388 HashSet<const EffectPaintPropertyNode*> m_effectNodesConverted; |
| 389 bool m_isFirstEffectEver; |
| 390 #endif |
| 367 }; | 391 }; |
| 368 | 392 |
| 369 int PropertyTreeManager::compositorIdForTransformNode(const TransformPaintProper
tyNode* transformNode) | 393 int PropertyTreeManager::compositorIdForTransformNode(const TransformPaintProper
tyNode* transformNode) |
| 370 { | 394 { |
| 371 if (!transformNode) | 395 if (!transformNode) |
| 372 return kSecondaryRootNodeId; | 396 return kSecondaryRootNodeId; |
| 373 | 397 |
| 374 auto it = m_transformNodeMap.find(transformNode); | 398 auto it = m_transformNodeMap.find(transformNode); |
| 375 if (it != m_transformNodeMap.end()) | 399 if (it != m_transformNodeMap.end()) |
| 376 return it->value; | 400 return it->value; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 dummyLayer->SetEffectTreeIndex(kSecondaryRootNodeId); | 459 dummyLayer->SetEffectTreeIndex(kSecondaryRootNodeId); |
| 436 dummyLayer->SetScrollTreeIndex(kRealRootNodeId); | 460 dummyLayer->SetScrollTreeIndex(kRealRootNodeId); |
| 437 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); | 461 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
| 438 | 462 |
| 439 auto result = m_clipNodeMap.set(clipNode, id); | 463 auto result = m_clipNodeMap.set(clipNode, id); |
| 440 DCHECK(result.isNewEntry); | 464 DCHECK(result.isNewEntry); |
| 441 clipTree().set_needs_update(true); | 465 clipTree().set_needs_update(true); |
| 442 return id; | 466 return id; |
| 443 } | 467 } |
| 444 | 468 |
| 469 unsigned depth(const EffectPaintPropertyNode* node) |
| 470 { |
| 471 unsigned result = 0; |
| 472 for (; node; node = node->parent()) |
| 473 result++; |
| 474 return result; |
| 475 } |
| 476 |
| 477 const EffectPaintPropertyNode* lowestCommonAncestor(const EffectPaintPropertyNod
e* nodeA, const EffectPaintPropertyNode* nodeB) |
| 478 { |
| 479 // Optimized common case. |
| 480 if (nodeA == nodeB) |
| 481 return nodeA; |
| 482 |
| 483 unsigned depthA = depth(nodeA), depthB = depth(nodeB); |
| 484 while (depthA > depthB) { |
| 485 nodeA = nodeA->parent(); |
| 486 depthA--; |
| 487 } |
| 488 while (depthB > depthA) { |
| 489 nodeB = nodeB->parent(); |
| 490 depthB--; |
| 491 } |
| 492 DCHECK_EQ(depthA, depthB); |
| 493 while (nodeA != nodeB) { |
| 494 nodeA = nodeA->parent(); |
| 495 nodeB = nodeB->parent(); |
| 496 } |
| 497 return nodeA; |
| 498 } |
| 499 |
| 500 int PropertyTreeManager::switchToEffectNode(const EffectPaintPropertyNode& nextE
ffect) |
| 501 { |
| 502 const EffectPaintPropertyNode* ancestor = lowestCommonAncestor(currentEffect
Node(), &nextEffect); |
| 503 while (currentEffectNode() != ancestor) |
| 504 m_effectStack.removeLast(); |
| 505 |
| 506 #if DCHECK_IS_ON() |
| 507 DCHECK(m_isFirstEffectEver || currentEffectNode()) << "Malformed effect tree
. Nodes in the same property tree should have common root."; |
| 508 m_isFirstEffectEver = false; |
| 509 #endif |
| 510 buildEffectNodesRecursively(&nextEffect); |
| 511 |
| 512 return compositorIdForCurrentEffectNode(); |
| 513 } |
| 514 |
| 515 void PropertyTreeManager::buildEffectNodesRecursively(const EffectPaintPropertyN
ode* nextEffect) |
| 516 { |
| 517 if (nextEffect == currentEffectNode()) |
| 518 return; |
| 519 DCHECK(nextEffect); |
| 520 |
| 521 buildEffectNodesRecursively(nextEffect->parent()); |
| 522 DCHECK_EQ(nextEffect->parent(), currentEffectNode()); |
| 523 |
| 524 #if DCHECK_IS_ON() |
| 525 DCHECK(!m_effectNodesConverted.contains(nextEffect)) << "Malformed paint art
ifact. Paint chunks under the same effect should be contiguous."; |
| 526 m_effectNodesConverted.add(nextEffect); |
| 527 #endif |
| 528 |
| 529 // We currently create dummy layers to host effect nodes and corresponding r
ender surface. |
| 530 // This should be removed once cc implements better support for freestanding
property trees. |
| 531 scoped_refptr<cc::Layer> dummyLayer = cc::Layer::Create(); |
| 532 m_rootLayer->AddChild(dummyLayer); |
| 533 |
| 534 // Also cc assumes a clip node is always created by a layer that creates ren
der surface. |
| 535 cc::ClipNode& dummyClip = *clipTree().Node(clipTree().Insert(cc::ClipNode(),
kSecondaryRootNodeId)); |
| 536 dummyClip.owner_id = dummyLayer->id(); |
| 537 dummyClip.transform_id = kRealRootNodeId; |
| 538 dummyClip.target_transform_id = kRealRootNodeId; |
| 539 |
| 540 cc::EffectNode& effectNode = *effectTree().Node(effectTree().Insert(cc::Effe
ctNode(), compositorIdForCurrentEffectNode())); |
| 541 effectNode.owner_id = dummyLayer->id(); |
| 542 effectNode.clip_id = dummyClip.id; |
| 543 effectNode.has_render_surface = true; |
| 544 effectNode.opacity = nextEffect->opacity(); |
| 545 m_effectStack.append(BlinkEffectAndCcIdPair{nextEffect, effectNode.id}); |
| 546 |
| 547 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
| 548 dummyLayer->SetTransformTreeIndex(kSecondaryRootNodeId); |
| 549 dummyLayer->SetClipTreeIndex(dummyClip.id); |
| 550 dummyLayer->SetEffectTreeIndex(effectNode.id); |
| 551 dummyLayer->SetScrollTreeIndex(kRealRootNodeId); |
| 552 } |
| 553 |
| 445 } // namespace | 554 } // namespace |
| 446 | 555 |
| 447 void PaintArtifactCompositor::updateInLayerListMode(const PaintArtifact& paintAr
tifact) | 556 void PaintArtifactCompositor::updateInLayerListMode(const PaintArtifact& paintAr
tifact) |
| 448 { | 557 { |
| 449 cc::LayerTreeHost* host = m_rootLayer->layer_tree_host(); | 558 cc::LayerTreeHost* host = m_rootLayer->layer_tree_host(); |
| 450 | 559 |
| 451 setMinimalPropertyTrees(host->property_trees(), m_rootLayer->id()); | 560 setMinimalPropertyTrees(host->property_trees(), m_rootLayer->id()); |
| 452 m_rootLayer->RemoveAllChildren(); | 561 m_rootLayer->RemoveAllChildren(); |
| 453 m_rootLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); | 562 m_rootLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
| 454 m_rootLayer->SetTransformTreeIndex(kSecondaryRootNodeId); | 563 m_rootLayer->SetTransformTreeIndex(kSecondaryRootNodeId); |
| 455 m_rootLayer->SetClipTreeIndex(kSecondaryRootNodeId); | 564 m_rootLayer->SetClipTreeIndex(kSecondaryRootNodeId); |
| 456 m_rootLayer->SetEffectTreeIndex(kSecondaryRootNodeId); | 565 m_rootLayer->SetEffectTreeIndex(kSecondaryRootNodeId); |
| 457 m_rootLayer->SetScrollTreeIndex(kRealRootNodeId); | 566 m_rootLayer->SetScrollTreeIndex(kRealRootNodeId); |
| 458 | 567 |
| 459 PropertyTreeManager propertyTreeManager(*host->property_trees(), m_rootLayer
.get()); | 568 PropertyTreeManager propertyTreeManager(*host->property_trees(), m_rootLayer
.get()); |
| 460 m_contentLayerClients.clear(); | 569 m_contentLayerClients.clear(); |
| 461 m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); | 570 m_contentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); |
| 462 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { | 571 for (const PaintChunk& paintChunk : paintArtifact.paintChunks()) { |
| 463 gfx::Vector2dF layerOffset; | 572 gfx::Vector2dF layerOffset; |
| 464 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint
Chunk, layerOffset); | 573 scoped_refptr<cc::Layer> layer = layerForPaintChunk(paintArtifact, paint
Chunk, layerOffset); |
| 465 | 574 |
| 466 int transformId = propertyTreeManager.compositorIdForTransformNode(paint
Chunk.properties.transform.get()); | 575 int transformId = propertyTreeManager.compositorIdForTransformNode(paint
Chunk.properties.transform.get()); |
| 467 int clipId = propertyTreeManager.compositorIdForClipNode(paintChunk.prop
erties.clip.get()); | 576 int clipId = propertyTreeManager.compositorIdForClipNode(paintChunk.prop
erties.clip.get()); |
| 577 int effectId = propertyTreeManager.switchToEffectNode(*paintChunk.proper
ties.effect.get()); |
| 468 | 578 |
| 469 layer->set_offset_to_transform_parent(layerOffset); | 579 layer->set_offset_to_transform_parent(layerOffset); |
| 470 | 580 |
| 471 m_rootLayer->AddChild(layer); | 581 m_rootLayer->AddChild(layer); |
| 472 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); | 582 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); |
| 473 layer->SetTransformTreeIndex(transformId); | 583 layer->SetTransformTreeIndex(transformId); |
| 474 layer->SetClipTreeIndex(clipId); | 584 layer->SetClipTreeIndex(clipId); |
| 475 layer->SetEffectTreeIndex(kSecondaryRootNodeId); | 585 layer->SetEffectTreeIndex(effectId); |
| 476 layer->SetScrollTreeIndex(kRealRootNodeId); | 586 layer->SetScrollTreeIndex(kRealRootNodeId); |
| 477 | 587 |
| 478 if (m_extraDataForTestingEnabled) | 588 if (m_extraDataForTestingEnabled) |
| 479 m_extraDataForTesting->contentLayers.append(layer); | 589 m_extraDataForTesting->contentLayers.append(layer); |
| 480 } | 590 } |
| 481 | 591 |
| 482 // Mark the property trees as having been rebuilt. | 592 // Mark the property trees as having been rebuilt. |
| 483 host->property_trees()->sequence_number = kPropertyTreeSequenceNumber; | 593 host->property_trees()->sequence_number = kPropertyTreeSequenceNumber; |
| 484 host->property_trees()->needs_rebuild = false; | 594 host->property_trees()->needs_rebuild = false; |
| 485 } | 595 } |
| 486 | 596 |
| 487 } // namespace blink | 597 } // namespace blink |
| OLD | NEW |