Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp

Issue 2627113005: Factor PropertyTreeManager out of PaintArtifactCompositor. (Closed)
Patch Set: Sync to head. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/compositing_display_item.h" 10 #include "cc/playback/compositing_display_item.h"
11 #include "cc/playback/display_item_list.h" 11 #include "cc/playback/display_item_list.h"
12 #include "cc/playback/display_item_list_settings.h" 12 #include "cc/playback/display_item_list_settings.h"
13 #include "cc/playback/drawing_display_item.h" 13 #include "cc/playback/drawing_display_item.h"
14 #include "cc/playback/filter_display_item.h" 14 #include "cc/playback/filter_display_item.h"
15 #include "cc/playback/float_clip_display_item.h" 15 #include "cc/playback/float_clip_display_item.h"
16 #include "cc/playback/transform_display_item.h" 16 #include "cc/playback/transform_display_item.h"
17 #include "cc/trees/clip_node.h"
18 #include "cc/trees/effect_node.h"
19 #include "cc/trees/layer_tree_host.h"
20 #include "cc/trees/property_tree.h"
21 #include "cc/trees/scroll_node.h"
22 #include "cc/trees/transform_node.h"
23 #include "platform/RuntimeEnabledFeatures.h" 17 #include "platform/RuntimeEnabledFeatures.h"
18 #include "platform/graphics/compositing/PropertyTreeManager.h"
24 #include "platform/graphics/paint/ClipPaintPropertyNode.h" 19 #include "platform/graphics/paint/ClipPaintPropertyNode.h"
25 #include "platform/graphics/paint/DisplayItem.h" 20 #include "platform/graphics/paint/DisplayItem.h"
26 #include "platform/graphics/paint/DrawingDisplayItem.h" 21 #include "platform/graphics/paint/DrawingDisplayItem.h"
27 #include "platform/graphics/paint/ForeignLayerDisplayItem.h" 22 #include "platform/graphics/paint/ForeignLayerDisplayItem.h"
28 #include "platform/graphics/paint/GeometryMapper.h" 23 #include "platform/graphics/paint/GeometryMapper.h"
29 #include "platform/graphics/paint/PaintArtifact.h" 24 #include "platform/graphics/paint/PaintArtifact.h"
30 #include "platform/graphics/paint/PropertyTreeState.h" 25 #include "platform/graphics/paint/PropertyTreeState.h"
31 #include "platform/graphics/paint/RasterInvalidationTracking.h" 26 #include "platform/graphics/paint/RasterInvalidationTracking.h"
32 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" 27 #include "platform/graphics/paint/ScrollPaintPropertyNode.h"
33 #include "platform/graphics/paint/TransformPaintPropertyNode.h" 28 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 const auto& foreignLayerDisplayItem = 251 const auto& foreignLayerDisplayItem =
257 static_cast<const ForeignLayerDisplayItem&>(displayItem); 252 static_cast<const ForeignLayerDisplayItem&>(displayItem);
258 layerOffset = gfx::Vector2dF(foreignLayerDisplayItem.location().x(), 253 layerOffset = gfx::Vector2dF(foreignLayerDisplayItem.location().x(),
259 foreignLayerDisplayItem.location().y()); 254 foreignLayerDisplayItem.location().y());
260 scoped_refptr<cc::Layer> layer = foreignLayerDisplayItem.layer(); 255 scoped_refptr<cc::Layer> layer = foreignLayerDisplayItem.layer();
261 layer->SetBounds(foreignLayerDisplayItem.bounds()); 256 layer->SetBounds(foreignLayerDisplayItem.bounds());
262 layer->SetIsDrawable(true); 257 layer->SetIsDrawable(true);
263 return layer; 258 return layer;
264 } 259 }
265 260
266 constexpr int kInvalidNodeId = -1;
267 // cc's property trees use 0 for the root node (always non-null).
268 constexpr int kRealRootNodeId = 0;
269 // cc allocates special nodes for root effects such as the device scale.
270 constexpr int kSecondaryRootNodeId = 1;
271 constexpr int kPropertyTreeSequenceNumber = 1;
272
273 enum EndDisplayItemType { EndTransform, EndClip, EndEffect }; 261 enum EndDisplayItemType { EndTransform, EndClip, EndEffect };
274 262
275 // Applies the clips between |localState| and |ancestorState| into a single 263 // Applies the clips between |localState| and |ancestorState| into a single
276 // combined cc::FloatClipDisplayItem on |ccList|. 264 // combined cc::FloatClipDisplayItem on |ccList|.
277 static void applyClipsBetweenStates(const PropertyTreeState& localState, 265 static void applyClipsBetweenStates(const PropertyTreeState& localState,
278 const PropertyTreeState& ancestorState, 266 const PropertyTreeState& ancestorState,
279 cc::DisplayItemList& ccList, 267 cc::DisplayItemList& ccList,
280 Vector<EndDisplayItemType>& endDisplayItems, 268 Vector<EndDisplayItemType>& endDisplayItems,
281 GeometryMapper& geometryMapper) { 269 GeometryMapper& geometryMapper) {
282 DCHECK(localState.transform() == ancestorState.transform()); 270 DCHECK(localState.transform() == ancestorState.transform());
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 ccInvalidationRect, 556 ccInvalidationRect,
569 rasterTracking ? &rasterTracking->trackedRasterInvalidations[index] 557 rasterTracking ? &rasterTracking->trackedRasterInvalidations[index]
570 : nullptr); 558 : nullptr);
571 } 559 }
572 } 560 }
573 561
574 newContentLayerClients.push_back(std::move(contentLayerClient)); 562 newContentLayerClients.push_back(std::move(contentLayerClient));
575 return ccPictureLayer; 563 return ccPictureLayer;
576 } 564 }
577 565
578 namespace {
579
580 class PropertyTreeManager {
581 WTF_MAKE_NONCOPYABLE(PropertyTreeManager);
582
583 public:
584 PropertyTreeManager(cc::PropertyTrees& propertyTrees, cc::Layer* rootLayer)
585 : m_propertyTrees(propertyTrees),
586 m_rootLayer(rootLayer)
587 {
588 setupRootTransformNode();
589 setupRootClipNode();
590 setupRootEffectNode();
591 setupRootScrollNode();
592 }
593
594 void setupRootTransformNode();
595 void setupRootClipNode();
596 void setupRootEffectNode();
597 void setupRootScrollNode();
598
599 // A brief discourse on cc property tree nodes, identifiers, and current and
600 // future design evolution envisioned:
601 //
602 // cc property trees identify nodes by their |id|, which implementation-wise
603 // is actually its index in the property tree's vector of its node type. More
604 // recent cc code now refers to these as 'node indices', or 'property tree
605 // indices'. |parent_id| is the same sort of 'node index' of that node's
606 // parent.
607 //
608 // Note there are two other primary types of 'ids' referenced in cc property
609 // tree related logic: (1) ElementId, also known Blink-side as
610 // CompositorElementId, used by the animation system to allow tying an element
611 // to its respective layer, and (2) layer ids. There are other ancillary ids
612 // not relevant to any of the above, such as
613 // cc::TransformNode::sorting_context_id
614 // (a.k.a. blink::TransformPaintPropertyNode::renderingContextId()).
615 //
616 // There is a vision to move toward a world where cc property nodes have no
617 // association with layers and instead have a |stable_id|. The id could come
618 // from an ElementId in turn derived from the layout object responsible for
619 // creating the property node.
620 //
621 // We would also like to explore moving to use a single shared property tree
622 // representation across both cc and Blink. See
623 // platform/graphics/paint/README.md for more.
624 //
625 // With the above as background, we can now state more clearly a description
626 // of the below set of compositor node methods: they take Blink paint property
627 // tree nodes as input, create a corresponding compositor property tree node
628 // if none yet exists, and return the compositor node's 'node id', a.k.a.,
629 // 'node index'.
630
631 int ensureCompositorTransformNode(const TransformPaintPropertyNode*);
632 int ensureCompositorClipNode(const ClipPaintPropertyNode*);
633 int ensureCompositorScrollNode(const ScrollPaintPropertyNode*);
634
635 int switchToEffectNode(const EffectPaintPropertyNode& nextEffect);
636 int getCurrentCompositorEffectNodeIndex() const {
637 return m_effectStack.back().id;
638 }
639
640 // Scroll offset has special treatment in the transform and scroll trees.
641 void updateScrollOffset(int layerId, int scrollId);
642
643 private:
644 void buildEffectNodesRecursively(const EffectPaintPropertyNode* nextEffect);
645
646 cc::TransformTree& transformTree() { return m_propertyTrees.transform_tree; }
647 cc::ClipTree& clipTree() { return m_propertyTrees.clip_tree; }
648 cc::EffectTree& effectTree() { return m_propertyTrees.effect_tree; }
649 cc::ScrollTree& scrollTree() { return m_propertyTrees.scroll_tree; }
650
651 const EffectPaintPropertyNode* currentEffectNode() const {
652 return m_effectStack.back().effect;
653 }
654
655 // Property trees which should be updated by the manager.
656 cc::PropertyTrees& m_propertyTrees;
657
658 // Layer to which transform "owner" layers should be added. These will not
659 // have any actual children, but at present must exist in the tree.
660 cc::Layer* m_rootLayer;
661
662 // Maps from Blink-side property tree nodes to cc property node indices.
663 HashMap<const TransformPaintPropertyNode*, int> m_transformNodeMap;
664 HashMap<const ClipPaintPropertyNode*, int> m_clipNodeMap;
665 HashMap<const ScrollPaintPropertyNode*, int> m_scrollNodeMap;
666
667 struct BlinkEffectAndCcIdPair {
668 const EffectPaintPropertyNode* effect;
669 // The cc property tree effect node id, or 'node index', for the cc effect
670 // node corresponding to the above Blink effect paint property node.
671 int id;
672 };
673 Vector<BlinkEffectAndCcIdPair> m_effectStack;
674
675 #if DCHECK_IS_ON()
676 HashSet<const EffectPaintPropertyNode*> m_effectNodesConverted;
677 #endif
678 };
679
680 void PropertyTreeManager::setupRootTransformNode() {
681 // cc is hardcoded to use transform node index 1 for device scale and
682 // transform.
683 cc::TransformTree& transformTree = m_propertyTrees.transform_tree;
684 transformTree.clear();
685 cc::TransformNode& transformNode = *transformTree.Node(
686 transformTree.Insert(cc::TransformNode(), kRealRootNodeId));
687 DCHECK_EQ(transformNode.id, kSecondaryRootNodeId);
688 transformNode.source_node_id = transformNode.parent_id;
689 transformTree.SetTargetId(transformNode.id, kRealRootNodeId);
690 transformTree.SetContentTargetId(transformNode.id, kRealRootNodeId);
691
692 // TODO(jaydasika): We shouldn't set ToScreen and FromScreen of root
693 // transform node here. They should be set while updating transform tree in
694 // cc.
695 float deviceScaleFactor = m_rootLayer->GetLayerTree()->device_scale_factor();
696 gfx::Transform toScreen;
697 toScreen.Scale(deviceScaleFactor, deviceScaleFactor);
698 transformTree.SetToScreen(kRealRootNodeId, toScreen);
699 gfx::Transform fromScreen;
700 bool invertible = toScreen.GetInverse(&fromScreen);
701 DCHECK(invertible);
702 transformTree.SetFromScreen(kRealRootNodeId, fromScreen);
703 transformTree.set_needs_update(true);
704
705 m_transformNodeMap.set(TransformPaintPropertyNode::root(), transformNode.id);
706 m_rootLayer->SetTransformTreeIndex(transformNode.id);
707 }
708
709 void PropertyTreeManager::setupRootClipNode() {
710 // cc is hardcoded to use clip node index 1 for viewport clip.
711 cc::ClipTree& clipTree = m_propertyTrees.clip_tree;
712 clipTree.clear();
713 m_propertyTrees.layer_id_to_clip_node_index.clear();
714 cc::ClipNode& clipNode =
715 *clipTree.Node(clipTree.Insert(cc::ClipNode(), kRealRootNodeId));
716 DCHECK_EQ(clipNode.id, kSecondaryRootNodeId);
717
718 clipNode.resets_clip = true;
719 clipNode.owning_layer_id = m_rootLayer->id();
720 clipNode.clip_type = cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP;
721 clipNode.clip = gfx::RectF(
722 gfx::SizeF(m_rootLayer->GetLayerTree()->device_viewport_size()));
723 clipNode.transform_id = kRealRootNodeId;
724 clipNode.target_transform_id = kRealRootNodeId;
725 clipNode.target_effect_id = kSecondaryRootNodeId;
726 m_propertyTrees.layer_id_to_clip_node_index[clipNode.owning_layer_id] =
727 clipNode.id;
728
729 m_clipNodeMap.set(ClipPaintPropertyNode::root(), clipNode.id);
730 m_rootLayer->SetClipTreeIndex(clipNode.id);
731 }
732
733 void PropertyTreeManager::setupRootEffectNode() {
734 // cc is hardcoded to use effect node index 1 for root render surface.
735 cc::EffectTree& effectTree = m_propertyTrees.effect_tree;
736 effectTree.clear();
737 m_propertyTrees.layer_id_to_effect_node_index.clear();
738 cc::EffectNode& effectNode =
739 *effectTree.Node(effectTree.Insert(cc::EffectNode(), kInvalidNodeId));
740 DCHECK_EQ(effectNode.id, kSecondaryRootNodeId);
741 effectNode.owning_layer_id = m_rootLayer->id();
742 effectNode.transform_id = kRealRootNodeId;
743 effectNode.clip_id = kSecondaryRootNodeId;
744 effectNode.has_render_surface = true;
745 m_propertyTrees.layer_id_to_effect_node_index[effectNode.owning_layer_id] =
746 effectNode.id;
747
748 m_effectStack.push_back(
749 BlinkEffectAndCcIdPair{EffectPaintPropertyNode::root(), effectNode.id});
750 m_rootLayer->SetEffectTreeIndex(effectNode.id);
751 }
752
753 void PropertyTreeManager::setupRootScrollNode() {
754 cc::ScrollTree& scrollTree = m_propertyTrees.scroll_tree;
755 scrollTree.clear();
756 m_propertyTrees.layer_id_to_scroll_node_index.clear();
757 cc::ScrollNode& scrollNode =
758 *scrollTree.Node(scrollTree.Insert(cc::ScrollNode(), kRealRootNodeId));
759 DCHECK_EQ(scrollNode.id, kSecondaryRootNodeId);
760 scrollNode.owning_layer_id = m_rootLayer->id();
761 scrollNode.transform_id = kSecondaryRootNodeId;
762 m_propertyTrees.layer_id_to_scroll_node_index[scrollNode.owning_layer_id] =
763 scrollNode.id;
764
765 m_scrollNodeMap.set(ScrollPaintPropertyNode::root(), scrollNode.id);
766 m_rootLayer->SetScrollTreeIndex(scrollNode.id);
767 }
768
769 int PropertyTreeManager::ensureCompositorTransformNode(
770 const TransformPaintPropertyNode* transformNode) {
771 DCHECK(transformNode);
772 // TODO(crbug.com/645615): Remove the failsafe here.
773 if (!transformNode)
774 return kSecondaryRootNodeId;
775
776 auto it = m_transformNodeMap.find(transformNode);
777 if (it != m_transformNodeMap.end())
778 return it->value;
779
780 scoped_refptr<cc::Layer> dummyLayer = cc::Layer::Create();
781 int parentId = ensureCompositorTransformNode(transformNode->parent());
782 int id = transformTree().Insert(cc::TransformNode(), parentId);
783
784 cc::TransformNode& compositorNode = *transformTree().Node(id);
785 transformTree().SetTargetId(id, kRealRootNodeId);
786 transformTree().SetContentTargetId(id, kRealRootNodeId);
787 compositorNode.source_node_id = parentId;
788
789 FloatPoint3D origin = transformNode->origin();
790 compositorNode.pre_local.matrix().setTranslate(-origin.x(), -origin.y(),
791 -origin.z());
792 compositorNode.local.matrix() =
793 TransformationMatrix::toSkMatrix44(transformNode->matrix());
794 compositorNode.post_local.matrix().setTranslate(origin.x(), origin.y(),
795 origin.z());
796 compositorNode.needs_local_transform_update = true;
797 compositorNode.flattens_inherited_transform =
798 transformNode->flattensInheritedTransform();
799 compositorNode.sorting_context_id = transformNode->renderingContextId();
800
801 m_rootLayer->AddChild(dummyLayer);
802 dummyLayer->SetTransformTreeIndex(id);
803 dummyLayer->SetClipTreeIndex(kSecondaryRootNodeId);
804 dummyLayer->SetEffectTreeIndex(kSecondaryRootNodeId);
805 dummyLayer->SetScrollTreeIndex(kRealRootNodeId);
806 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber);
807
808 auto result = m_transformNodeMap.set(transformNode, id);
809 DCHECK(result.isNewEntry);
810 transformTree().set_needs_update(true);
811 return id;
812 }
813
814 int PropertyTreeManager::ensureCompositorClipNode(
815 const ClipPaintPropertyNode* clipNode) {
816 DCHECK(clipNode);
817 // TODO(crbug.com/645615): Remove the failsafe here.
818 if (!clipNode)
819 return kSecondaryRootNodeId;
820
821 auto it = m_clipNodeMap.find(clipNode);
822 if (it != m_clipNodeMap.end())
823 return it->value;
824
825 scoped_refptr<cc::Layer> dummyLayer = cc::Layer::Create();
826 int parentId = ensureCompositorClipNode(clipNode->parent());
827 int id = clipTree().Insert(cc::ClipNode(), parentId);
828
829 cc::ClipNode& compositorNode = *clipTree().Node(id);
830 compositorNode.owning_layer_id = dummyLayer->id();
831 m_propertyTrees.layer_id_to_clip_node_index[compositorNode.owning_layer_id] =
832 id;
833
834 // TODO(jbroman): Don't discard rounded corners.
835 compositorNode.clip = clipNode->clipRect().rect();
836 compositorNode.transform_id =
837 ensureCompositorTransformNode(clipNode->localTransformSpace());
838 compositorNode.target_transform_id = kRealRootNodeId;
839 compositorNode.target_effect_id = kSecondaryRootNodeId;
840 compositorNode.clip_type = cc::ClipNode::ClipType::APPLIES_LOCAL_CLIP;
841 compositorNode.layers_are_clipped = true;
842 compositorNode.layers_are_clipped_when_surfaces_disabled = true;
843
844 m_rootLayer->AddChild(dummyLayer);
845 dummyLayer->SetTransformTreeIndex(compositorNode.transform_id);
846 dummyLayer->SetClipTreeIndex(id);
847 dummyLayer->SetEffectTreeIndex(kSecondaryRootNodeId);
848 dummyLayer->SetScrollTreeIndex(kRealRootNodeId);
849 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber);
850
851 auto result = m_clipNodeMap.set(clipNode, id);
852 DCHECK(result.isNewEntry);
853 clipTree().set_needs_update(true);
854 return id;
855 }
856
857 int PropertyTreeManager::ensureCompositorScrollNode(
858 const ScrollPaintPropertyNode* scrollNode) {
859 DCHECK(scrollNode);
860 // TODO(crbug.com/645615): Remove the failsafe here.
861 if (!scrollNode)
862 return kSecondaryRootNodeId;
863
864 auto it = m_scrollNodeMap.find(scrollNode);
865 if (it != m_scrollNodeMap.end())
866 return it->value;
867
868 int parentId = ensureCompositorScrollNode(scrollNode->parent());
869 int id = scrollTree().Insert(cc::ScrollNode(), parentId);
870
871 cc::ScrollNode& compositorNode = *scrollTree().Node(id);
872 compositorNode.owning_layer_id = parentId;
873 m_propertyTrees
874 .layer_id_to_scroll_node_index[compositorNode.owning_layer_id] = id;
875
876 compositorNode.scrollable = true;
877
878 compositorNode.scroll_clip_layer_bounds.SetSize(scrollNode->clip().width(),
879 scrollNode->clip().height());
880 compositorNode.bounds.SetSize(scrollNode->bounds().width(),
881 scrollNode->bounds().height());
882 compositorNode.user_scrollable_horizontal =
883 scrollNode->userScrollableHorizontal();
884 compositorNode.user_scrollable_vertical =
885 scrollNode->userScrollableVertical();
886 compositorNode.transform_id =
887 ensureCompositorTransformNode(scrollNode->scrollOffsetTranslation());
888 compositorNode.main_thread_scrolling_reasons =
889 scrollNode->mainThreadScrollingReasons();
890
891 auto result = m_scrollNodeMap.set(scrollNode, id);
892 DCHECK(result.isNewEntry);
893 scrollTree().set_needs_update(true);
894
895 return id;
896 }
897
898 void PropertyTreeManager::updateScrollOffset(int layerId, int scrollId) {
899 cc::ScrollNode& scrollNode = *scrollTree().Node(scrollId);
900 cc::TransformNode& transformNode =
901 *transformTree().Node(scrollNode.transform_id);
902
903 transformNode.scrolls = true;
904
905 // Blink creates a 2d transform node just for scroll offset whereas cc's
906 // transform node has a special scroll offset field. To handle this we
907 // adjust cc's transform node to remove the 2d scroll translation and
908 // let the cc scroll tree update the cc scroll offset.
909 DCHECK(transformNode.local.IsIdentityOr2DTranslation());
910 auto offset = transformNode.local.To2dTranslation();
911 transformNode.local.MakeIdentity();
912 scrollTree().SetScrollOffset(layerId,
913 gfx::ScrollOffset(-offset.x(), -offset.y()));
914 scrollTree().set_needs_update(true);
915 }
916
917 unsigned depth(const EffectPaintPropertyNode* node) {
918 unsigned result = 0;
919 for (; node; node = node->parent())
920 result++;
921 return result;
922 }
923
924 // TODO(chrishtr): templatize this to avoid duplication of
925 // GeometryMapper::leastCommonAncestor.
926 const EffectPaintPropertyNode* lowestCommonAncestor(
927 const EffectPaintPropertyNode* nodeA,
928 const EffectPaintPropertyNode* nodeB) {
929 // Optimized common case.
930 if (nodeA == nodeB)
931 return nodeA;
932
933 unsigned depthA = depth(nodeA), depthB = depth(nodeB);
934 while (depthA > depthB) {
935 nodeA = nodeA->parent();
936 depthA--;
937 }
938 while (depthB > depthA) {
939 nodeB = nodeB->parent();
940 depthB--;
941 }
942 DCHECK_EQ(depthA, depthB);
943 while (nodeA != nodeB) {
944 nodeA = nodeA->parent();
945 nodeB = nodeB->parent();
946 }
947 return nodeA;
948 }
949
950 int PropertyTreeManager::switchToEffectNode(
951 const EffectPaintPropertyNode& nextEffect) {
952 const EffectPaintPropertyNode* ancestor =
953 lowestCommonAncestor(currentEffectNode(), &nextEffect);
954 DCHECK(ancestor) << "Malformed effect tree. All nodes must be descendant of "
955 "EffectPaintPropertyNode::root().";
956 while (currentEffectNode() != ancestor)
957 m_effectStack.pop_back();
958
959 // Now the current effect is the lowest common ancestor of previous effect
960 // and the next effect. That implies it is an existing node that already has
961 // at least one paint chunk or child effect, and we are going to either attach
962 // another paint chunk or child effect to it. We can no longer omit render
963 // surface for it even for opacity-only nodes.
964 // See comments in PropertyTreeManager::buildEffectNodesRecursively().
965 // TODO(crbug.com/504464): Remove premature optimization here.
966 if (currentEffectNode() && currentEffectNode()->opacity() != 1.f) {
967 effectTree()
968 .Node(getCurrentCompositorEffectNodeIndex())
969 ->has_render_surface = true;
970 }
971
972 buildEffectNodesRecursively(&nextEffect);
973
974 return getCurrentCompositorEffectNodeIndex();
975 }
976
977 void PropertyTreeManager::buildEffectNodesRecursively(
978 const EffectPaintPropertyNode* nextEffect) {
979 if (nextEffect == currentEffectNode())
980 return;
981 DCHECK(nextEffect);
982
983 buildEffectNodesRecursively(nextEffect->parent());
984 DCHECK_EQ(nextEffect->parent(), currentEffectNode());
985
986 #if DCHECK_IS_ON()
987 DCHECK(!m_effectNodesConverted.contains(nextEffect))
988 << "Malformed paint artifact. Paint chunks under the same effect should "
989 "be contiguous.";
990 m_effectNodesConverted.add(nextEffect);
991 #endif
992
993 // An effect node can't omit render surface if it has child with exotic
994 // blending mode. See comments below for more detail.
995 // TODO(crbug.com/504464): Remove premature optimization here.
996 if (nextEffect->blendMode() != SkBlendMode::kSrcOver) {
997 effectTree()
998 .Node(getCurrentCompositorEffectNodeIndex())
999 ->has_render_surface = true;
1000 }
1001
1002 // We currently create dummy layers to host effect nodes and corresponding
1003 // render surfaces. This should be removed once cc implements better support
1004 // for freestanding property trees.
1005 scoped_refptr<cc::Layer> dummyLayer = nextEffect->ensureDummyLayer();
1006 m_rootLayer->AddChild(dummyLayer);
1007
1008 int outputClipId = ensureCompositorClipNode(nextEffect->outputClip());
1009
1010 cc::EffectNode& effectNode = *effectTree().Node(effectTree().Insert(
1011 cc::EffectNode(), getCurrentCompositorEffectNodeIndex()));
1012 effectNode.owning_layer_id = dummyLayer->id();
1013 effectNode.clip_id = outputClipId;
1014 // Every effect is supposed to have render surface enabled for grouping,
1015 // but we can get away without one if the effect is opacity-only and has only
1016 // one compositing child with kSrcOver blend mode. This is both for
1017 // optimization and not introducing sub-pixel differences in layout tests.
1018 // See PropertyTreeManager::switchToEffectNode() and above where we
1019 // retrospectively enable render surface when more than one compositing child
1020 // or a child with exotic blend mode is detected.
1021 // TODO(crbug.com/504464): There is ongoing work in cc to delay render surface
1022 // decision until later phase of the pipeline. Remove premature optimization
1023 // here once the work is ready.
1024 if (!nextEffect->filter().isEmpty() ||
1025 nextEffect->blendMode() != SkBlendMode::kSrcOver)
1026 effectNode.has_render_surface = true;
1027 effectNode.opacity = nextEffect->opacity();
1028 effectNode.filters = nextEffect->filter().asCcFilterOperations();
1029 effectNode.blend_mode = nextEffect->blendMode();
1030 m_propertyTrees.layer_id_to_effect_node_index[effectNode.owning_layer_id] =
1031 effectNode.id;
1032 m_effectStack.push_back(BlinkEffectAndCcIdPair{nextEffect, effectNode.id});
1033
1034 dummyLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber);
1035 dummyLayer->SetTransformTreeIndex(kSecondaryRootNodeId);
1036 dummyLayer->SetClipTreeIndex(outputClipId);
1037 dummyLayer->SetEffectTreeIndex(effectNode.id);
1038 dummyLayer->SetScrollTreeIndex(kRealRootNodeId);
1039 }
1040
1041 } // namespace
1042
1043 bool PaintArtifactCompositor::canMergeInto( 566 bool PaintArtifactCompositor::canMergeInto(
1044 const PaintArtifact& paintArtifact, 567 const PaintArtifact& paintArtifact,
1045 const PaintChunk& newChunk, 568 const PaintChunk& newChunk,
1046 const PendingLayer& candidatePendingLayer) { 569 const PendingLayer& candidatePendingLayer) {
1047 const PaintChunk& pendingLayerFirstChunk = 570 const PaintChunk& pendingLayerFirstChunk =
1048 *candidatePendingLayer.paintChunks[0]; 571 *candidatePendingLayer.paintChunks[0];
1049 if (paintArtifact.getDisplayItemList()[newChunk.beginIndex].isForeignLayer()) 572 if (paintArtifact.getDisplayItemList()[newChunk.beginIndex].isForeignLayer())
1050 return false; 573 return false;
1051 574
1052 if (paintArtifact.getDisplayItemList()[pendingLayerFirstChunk.beginIndex] 575 if (paintArtifact.getDisplayItemList()[pendingLayerFirstChunk.beginIndex]
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 683
1161 // The tree will be null after detaching and this update can be ignored. 684 // The tree will be null after detaching and this update can be ignored.
1162 // See: WebViewImpl::detachPaintArtifactCompositor(). 685 // See: WebViewImpl::detachPaintArtifactCompositor().
1163 if (!layerTree) 686 if (!layerTree)
1164 return; 687 return;
1165 688
1166 if (m_extraDataForTestingEnabled) 689 if (m_extraDataForTestingEnabled)
1167 m_extraDataForTesting = WTF::wrapUnique(new ExtraDataForTesting); 690 m_extraDataForTesting = WTF::wrapUnique(new ExtraDataForTesting);
1168 691
1169 m_rootLayer->RemoveAllChildren(); 692 m_rootLayer->RemoveAllChildren();
1170 m_rootLayer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); 693 m_rootLayer->set_property_tree_sequence_number(
694 PropertyTreeManager::kPropertyTreeSequenceNumber);
1171 695
1172 PropertyTreeManager propertyTreeManager(*layerTree->property_trees(), 696 PropertyTreeManager propertyTreeManager(*layerTree->property_trees(),
1173 m_rootLayer.get()); 697 m_rootLayer.get());
1174 698
1175 Vector<PendingLayer, 0> pendingLayers; 699 Vector<PendingLayer, 0> pendingLayers;
1176 GeometryMapper geometryMapper; 700 GeometryMapper geometryMapper;
1177 collectPendingLayers(paintArtifact, pendingLayers, geometryMapper); 701 collectPendingLayers(paintArtifact, pendingLayers, geometryMapper);
1178 702
1179 Vector<std::unique_ptr<ContentLayerClientImpl>> newContentLayerClients; 703 Vector<std::unique_ptr<ContentLayerClientImpl>> newContentLayerClients;
1180 newContentLayerClients.reserveCapacity(paintArtifact.paintChunks().size()); 704 newContentLayerClients.reserveCapacity(paintArtifact.paintChunks().size());
(...skipping 10 matching lines...) Expand all
1191 int clipId = propertyTreeManager.ensureCompositorClipNode( 715 int clipId = propertyTreeManager.ensureCompositorClipNode(
1192 pendingLayer.propertyTreeState.clip()); 716 pendingLayer.propertyTreeState.clip());
1193 int effectId = propertyTreeManager.switchToEffectNode( 717 int effectId = propertyTreeManager.switchToEffectNode(
1194 *pendingLayer.propertyTreeState.effect()); 718 *pendingLayer.propertyTreeState.effect());
1195 719
1196 propertyTreeManager.updateScrollOffset(layer->id(), scrollId); 720 propertyTreeManager.updateScrollOffset(layer->id(), scrollId);
1197 721
1198 layer->set_offset_to_transform_parent(layerOffset); 722 layer->set_offset_to_transform_parent(layerOffset);
1199 723
1200 m_rootLayer->AddChild(layer); 724 m_rootLayer->AddChild(layer);
1201 layer->set_property_tree_sequence_number(kPropertyTreeSequenceNumber); 725 layer->set_property_tree_sequence_number(
726 PropertyTreeManager::kPropertyTreeSequenceNumber);
1202 layer->SetTransformTreeIndex(transformId); 727 layer->SetTransformTreeIndex(transformId);
1203 layer->SetClipTreeIndex(clipId); 728 layer->SetClipTreeIndex(clipId);
1204 layer->SetEffectTreeIndex(effectId); 729 layer->SetEffectTreeIndex(effectId);
1205 layer->SetScrollTreeIndex(scrollId); 730 layer->SetScrollTreeIndex(scrollId);
1206 731
1207 layer->SetShouldCheckBackfaceVisibility(pendingLayer.backfaceHidden); 732 layer->SetShouldCheckBackfaceVisibility(pendingLayer.backfaceHidden);
1208 733
1209 if (m_extraDataForTestingEnabled) 734 if (m_extraDataForTestingEnabled)
1210 m_extraDataForTesting->contentLayers.push_back(layer); 735 m_extraDataForTesting->contentLayers.push_back(layer);
1211 } 736 }
1212 m_contentLayerClients.clear(); 737 m_contentLayerClients.clear();
1213 m_contentLayerClients.swap(newContentLayerClients); 738 m_contentLayerClients.swap(newContentLayerClients);
1214 739
1215 // Mark the property trees as having been rebuilt. 740 // Mark the property trees as having been rebuilt.
1216 layerTree->property_trees()->sequence_number = kPropertyTreeSequenceNumber; 741 layerTree->property_trees()->sequence_number =
742 PropertyTreeManager::kPropertyTreeSequenceNumber;
1217 layerTree->property_trees()->needs_rebuild = false; 743 layerTree->property_trees()->needs_rebuild = false;
1218 layerTree->property_trees()->ResetCachedData(); 744 layerTree->property_trees()->ResetCachedData();
1219 } 745 }
1220 746
1221 #ifndef NDEBUG 747 #ifndef NDEBUG
1222 void PaintArtifactCompositor::showDebugData() { 748 void PaintArtifactCompositor::showDebugData() {
1223 LOG(ERROR) << layersAsJSON(LayerTreeIncludesDebugInfo) 749 LOG(ERROR) << layersAsJSON(LayerTreeIncludesDebugInfo)
1224 ->toPrettyJSONString() 750 ->toPrettyJSONString()
1225 .utf8() 751 .utf8()
1226 .data(); 752 .data();
1227 } 753 }
1228 #endif 754 #endif
1229 755
1230 } // namespace blink 756 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698