diff options
author | phoglund@chromium.org <phoglund@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-01 14:56:43 +0000 |
---|---|---|
committer | phoglund@chromium.org <phoglund@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-01 14:56:43 +0000 |
commit | afb7209d9af300ed5f9f578737d28848243edf9c (patch) | |
tree | e9cd7cabeaa8b3100d37d7653f19d121ca888874 /cc | |
parent | 373209b54f6e5627529912c7f37cad8b05d4d53f (diff) | |
download | chromium_src-afb7209d9af300ed5f9f578737d28848243edf9c.zip chromium_src-afb7209d9af300ed5f9f578737d28848243edf9c.tar.gz chromium_src-afb7209d9af300ed5f9f578737d28848243edf9c.tar.bz2 |
Revert 226219 "Allow clipping by scroll parents."
Likely broke unit tests on Android:
http://build.chromium.org/p/chromium.linux/builders/Android%20Tests/builds/8345
> Allow clipping by scroll parents.
>
> Previously, we had required that we inherit our clip from our direct ancestor or
> our clip parent (which has to be an ancestor). This CL loosens that restriction
> and allows clipping by our scroll parent, which will not be our ancestor.
>
> In order for this to work, we must ensure that the scroll parent's clip is
> computed before we compute the clip children's. This is accomplished by changing
> the order in which we recur through the layer tree and sorting layer lists
> afterward to ensure that we ultimately stack correctly.
>
> NB: I have taken care to only sort the newly added layers, and to only sort when
> the child order has actually changed, which should happen rarely.
>
> Tests:
> 1. LayerTreeHostCommonTest.ClippedByScrollParent
> - Checks that the simple case (where the scroll parent is naturally processed
> before the scroll child) results in the correct clips.
> 2. LayerTreeHostCommonTest.ClippedByOutOfOrderScrollParent
> - Identical to (1) but checks that clips are still correct when the scroll
> parent needs to be visited out of order.
> 3. LayerTreeHostCommonTest.ClippedByOutOfOrderScrollGrandparent
> - Similar to (2), but also checks that clips are set up correctly if the
> scroll parent has yet another scroll parent (sorting for recursion is a bit
> tougher in this case).
> - Also checks that despite visiting layers out of order, that the layer list
> ends up in paint order.
> 4. LayerTreeHostCommonTest.OutOfOrderClippingRequiresRSLLSorting
> - Similar to (3), but includes several render surfaces in the tree and checks
> that the resulting render surface layer list is ordered correctly.
> 5. LayerTreeHostCommonTest.DoNotClobberSorting
> - Ensures that if we have to reorder layer list contributions that we do not break 3d sorting.
>
> BUG=291413
> R=danakj@chromium.org, enne@chromium.org, hartmanng@chromium.org
>
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=225858
>
> Review URL: https://codereview.chromium.org/23536049
TBR=vollick@chromium.org
Review URL: https://codereview.chromium.org/25542002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226231 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/draw_properties.h | 19 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common.cc | 206 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common_unittest.cc | 562 |
3 files changed, 14 insertions, 773 deletions
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h index 9c1fcbd..181d900 100644 --- a/cc/layers/draw_properties.h +++ b/cc/layers/draw_properties.h @@ -30,12 +30,7 @@ struct CC_EXPORT DrawProperties { num_unclipped_descendants(0), descendants_can_clip_selves(false), can_draw_directly_to_backbuffer(false), - layer_or_descendant_has_copy_request(false), - sorted_for_recursion(false), - index_of_first_descendants_addition(0), - num_descendants_added(0), - index_of_first_render_surface_layer_list_addition(0), - num_render_surfaces_added(0) {} + layer_or_descendant_has_copy_request(false) {} // Transforms objects from content space to target surface space, where // this layer would be drawn. @@ -107,18 +102,6 @@ struct CC_EXPORT DrawProperties { // If true, the layer or some layer in its sub-tree has a CopyOutputRequest // present on it. bool layer_or_descendant_has_copy_request; - - // This is true if the order (wrt to its siblings in the tree) in which the - // layer will be visited while computing draw properties has been determined. - bool sorted_for_recursion; - - // If this layer is visited out of order, its contribution to the descendant - // and render surface layer lists will be put aside in a temporary list. - // These values will allow for an efficient reordering of these additions. - size_t index_of_first_descendants_addition; - size_t num_descendants_added; - size_t index_of_first_render_surface_layer_list_addition; - size_t num_render_surfaces_added; }; } // namespace cc diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index 50a57d3..c2b77bd 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc @@ -170,11 +170,7 @@ static void UpdateClipRectsForClipChild( // If the layer has no clip_parent, or the ancestor is the same as its actual // parent, then we don't need special clip rects. Bail now and leave the out // parameters untouched. - const LayerType* clip_parent = layer->scroll_parent(); - - if (!clip_parent) - clip_parent = layer->clip_parent(); - + const LayerType* clip_parent = layer->clip_parent(); if (!clip_parent || clip_parent == layer->parent()) return; @@ -191,25 +187,12 @@ static void UpdateClipRectsForClipChild( // wanted to. But more importantly, this matches the expectations of // CalculateDrawPropertiesInternal. If we, say, create a render surface, these // clip rects will want to be in its target space, not ours. - if (clip_parent == layer->clip_parent()) { - *clip_rect_in_parent_target_space = - TranslateRectToTargetSpace<LayerType, RenderSurfaceType>( - *clip_parent, - *layer->parent(), - *clip_rect_in_parent_target_space, - TranslateRectDirectionToDescendant); - } else { - // If we're being clipped by our scroll parent, we must translate through - // our common ancestor. This happens to be our parent, so it is sufficent to - // translate from our clip parent's space to the space of its ancestor (our - // parent). - *clip_rect_in_parent_target_space = - TranslateRectToTargetSpace<LayerType, RenderSurfaceType>( - *layer->parent(), - *clip_parent, - *clip_rect_in_parent_target_space, - TranslateRectDirectionToAncestor); - } + *clip_rect_in_parent_target_space = + TranslateRectToTargetSpace<LayerType, RenderSurfaceType>( + *clip_parent, + *layer->parent(), + *clip_rect_in_parent_target_space, + TranslateRectDirectionToDescendant); } // We collect an accumulated drawable content rect per render surface. @@ -1045,8 +1028,6 @@ static void PreCalculateMetaInformation( descendants_can_clip_selves = false; } - layer->draw_properties().sorted_for_recursion = false; - if (layer->clip_parent()) recursive_data->num_unclipped_descendants++; @@ -1149,116 +1130,6 @@ struct DataForRecursion { bool subtree_is_visible_from_ancestor; }; -template <typename LayerType> -static LayerType* GetChildContainingLayer(const LayerType& parent, - LayerType* layer) { - for (LayerType* ancestor = layer; ancestor; ancestor = ancestor->parent()) { - if (ancestor->parent() == &parent) - return ancestor; - } - NOTREACHED(); - return 0; -} - -template <typename LayerType> -static void AddScrollParentChain(std::vector<LayerType*>* out, - const LayerType& parent, - LayerType* layer) { - // At a high level, this function walks up the chain of scroll parents - // recursively, and once we reach the end of the chain, we add the child - // of |parent| containing each scroll ancestor as we unwind. The result is - // an ordering of parent's children that ensures that scroll parents are - // visited before their descendants. - // Take for example this layer tree: - // - // + stacking_context - // + scroll_child (1) - // + scroll_parent_graphics_layer (*) - // | + scroll_parent_scrolling_layer - // | + scroll_parent_scrolling_content_layer (2) - // + scroll_grandparent_graphics_layer (**) - // + scroll_grandparent_scrolling_layer - // + scroll_grandparent_scrolling_content_layer (3) - // - // The scroll child is (1), its scroll parent is (2) and its scroll - // grandparent is (3). Note, this doesn't mean that (2)'s scroll parent is - // (3), it means that (*)'s scroll parent is (3). We don't want our list to - // look like [ (3), (2), (1) ], even though that does have the ancestor chain - // in the right order. Instead, we want [ (**), (*), (1) ]. That is, only want - // (1)'s siblings in the list, but we want them to appear in such an order - // that the scroll ancestors get visited in the correct order. - // - // So our first task at this step of the recursion is to determine the layer - // that we will potentionally add to the list. That is, the child of parent - // containing |layer|. - LayerType* child = GetChildContainingLayer(parent, layer); - if (child->draw_properties().sorted_for_recursion) - return; - - if (LayerType* scroll_parent = child->scroll_parent()) - AddScrollParentChain(out, parent, scroll_parent); - - out->push_back(child); - child->draw_properties().sorted_for_recursion = true; -} - -template <typename LayerType> -static bool SortChildrenForRecursion(std::vector<LayerType*>* out, - const LayerType& parent) { - bool order_changed = false; - for (size_t i = 0; i < parent.children().size(); ++i) { - LayerType* current = - LayerTreeHostCommon::get_child_as_raw_ptr(parent.children(), i); - - if (current->draw_properties().sorted_for_recursion) { - order_changed = true; - continue; - } - - AddScrollParentChain(out, parent, current); - } - - DCHECK_EQ(parent.children().size(), out->size()); - return order_changed; -} - -template <typename LayerType> -static void GetNewDescendantsStartIndexAndCount(LayerType* layer, - size_t* start_index, - size_t* count) { - *start_index = layer->draw_properties().index_of_first_descendants_addition; - *count = layer->draw_properties().num_descendants_added; -} - -template <typename LayerType> -static void GetNewRenderSurfacesStartIndexAndCount(LayerType* layer, - size_t* start_index, - size_t* count) { - *start_index = layer->draw_properties() - .index_of_first_render_surface_layer_list_addition; - *count = layer->draw_properties().num_render_surfaces_added; -} - -template <typename LayerType, - typename LayerListType, - typename GetIndexAndCountType> -static void AddUnsortedLayerListContributions( - const LayerType& parent, - const LayerListType& source, - LayerListType* target, - GetIndexAndCountType get_index_and_count) { - for (size_t i = 0; i < parent.children().size(); ++i) { - LayerType* child = - LayerTreeHostCommon::get_child_as_raw_ptr(parent.children(), i); - - size_t start_index = 0; - size_t count = 0; - get_index_and_count(child, &start_index, &count); - for (size_t j = start_index; j < start_index + count; ++j) - target->push_back(source.at(j)); - } -} - // Recursively walks the layer tree starting at the given node and computes all // the necessary transformations, clip rects, render surfaces, etc. template <typename LayerType, @@ -1885,75 +1756,24 @@ static void CalculateDrawPropertiesInternal( data_for_children.subtree_is_visible_from_ancestor = layer_is_visible; } - // These are the layer lists that will be passed to our children to populate. - LayerListType* render_surface_layer_list_for_children = - render_surface_layer_list; - LayerListType* descendants_for_children = &descendants; - - // If we visit our children out of order, we will put their contributions to - // descendants and render_surface_layer_list aside during recursion and add - // them to the real lists afterwards in the correct order. - scoped_ptr<LayerListType> unsorted_render_surface_layer_list; - scoped_ptr<LayerListType> unsorted_descendants; - - std::vector<LayerType*> sorted_children; - bool child_order_changed = SortChildrenForRecursion(&sorted_children, *layer); - if (child_order_changed) { - // We'll be visiting our children out of order; use the temporary lists. - unsorted_render_surface_layer_list.reset(new LayerListType); - unsorted_descendants.reset(new LayerListType); - render_surface_layer_list_for_children = - unsorted_render_surface_layer_list.get(); - descendants_for_children = unsorted_descendants.get(); - } - - for (size_t i = 0; i < sorted_children.size(); ++i) { - LayerType* child = sorted_children[i]; + for (size_t i = 0; i < layer->children().size(); ++i) { + LayerType* child = + LayerTreeHostCommon::get_child_as_raw_ptr(layer->children(), i); gfx::Rect drawable_content_rect_of_child_subtree; gfx::Transform identity_matrix; - - child->draw_properties().index_of_first_descendants_addition = - descendants_for_children->size(); - child->draw_properties().index_of_first_render_surface_layer_list_addition = - render_surface_layer_list_for_children->size(); - CalculateDrawPropertiesInternal<LayerType, LayerListType, RenderSurfaceType>( child, globals, data_for_children, - render_surface_layer_list_for_children, - descendants_for_children, + render_surface_layer_list, + &descendants, accumulated_surface_state); - if (child->render_surface() && !child->render_surface()->content_rect().IsEmpty()) { - descendants_for_children->push_back(child); + descendants.push_back(child); } - - child->draw_properties().num_descendants_added = - descendants_for_children->size() - - child->draw_properties().index_of_first_descendants_addition; - child->draw_properties().num_render_surfaces_added = - render_surface_layer_list_for_children->size() - - child->draw_properties() - .index_of_first_render_surface_layer_list_addition; - } - - // Add the unsorted layer list contributions, if necessary. - if (child_order_changed) { - AddUnsortedLayerListContributions( - *layer, - *unsorted_render_surface_layer_list, - render_surface_layer_list, - &GetNewRenderSurfacesStartIndexAndCount<LayerType>); - - AddUnsortedLayerListContributions( - *layer, - *unsorted_descendants, - &descendants, - &GetNewDescendantsStartIndexAndCount<LayerType>); } // Compute the total drawable_content_rect for this subtree (the rect is in diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 7bb179e..04ffc32 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc @@ -4,15 +4,12 @@ #include "cc/trees/layer_tree_host_common.h" -#include <set> - #include "cc/animation/layer_animation_controller.h" #include "cc/base/math_util.h" #include "cc/layers/content_layer.h" #include "cc/layers/content_layer_client.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer.h" -#include "cc/layers/layer_client.h" #include "cc/layers/layer_impl.h" #include "cc/layers/render_surface.h" #include "cc/layers/render_surface_impl.h" @@ -9026,564 +9023,5 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { ->render_surface()->layer_list().size()); } -TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) { - // Checks that the simple case (being clipped by a scroll parent that would - // have been processed before you anyhow) results in the right clips. - // - // + root - // + scroll_parent_border - // | + scroll_parent_clip - // | + scroll_parent - // + scroll_child - // - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> scroll_parent_border = Layer::Create(); - scoped_refptr<Layer> scroll_parent_clip = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> scroll_parent = - make_scoped_refptr(new LayerWithForcedDrawsContent); - scoped_refptr<LayerWithForcedDrawsContent> scroll_child = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - root->AddChild(scroll_child); - - root->AddChild(scroll_parent_border); - scroll_parent_border->AddChild(scroll_parent_clip); - scroll_parent_clip->AddChild(scroll_parent); - - scroll_parent_clip->SetMasksToBounds(true); - - scroll_child->SetScrollParent(scroll_parent.get()); - - gfx::Transform identity_transform; - SetLayerPropertiesForTesting(root.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_parent_border.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(40, 40), - false); - SetLayerPropertiesForTesting(scroll_parent_clip.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(30, 30), - false); - SetLayerPropertiesForTesting(scroll_parent.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_child.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); - host->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); - - EXPECT_TRUE(root->render_surface()); - - EXPECT_EQ(gfx::Rect(0, 0, 30, 30).ToString(), - scroll_child->clip_rect().ToString()); - EXPECT_TRUE(scroll_child->is_clipped()); -} - -TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) { - // Checks that clipping by a scroll parent that follows you in paint order - // still results in correct clipping. - // - // + root - // + scroll_child - // + scroll_parent_border - // + scroll_parent_clip - // + scroll_parent - // - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> scroll_parent_border = Layer::Create(); - scoped_refptr<Layer> scroll_parent_clip = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> scroll_parent = - make_scoped_refptr(new LayerWithForcedDrawsContent); - scoped_refptr<LayerWithForcedDrawsContent> scroll_child = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - root->AddChild(scroll_parent_border); - scroll_parent_border->AddChild(scroll_parent_clip); - scroll_parent_clip->AddChild(scroll_parent); - - root->AddChild(scroll_child); - - scroll_parent_clip->SetMasksToBounds(true); - - scroll_child->SetScrollParent(scroll_parent.get()); - - gfx::Transform identity_transform; - SetLayerPropertiesForTesting(root.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_parent_border.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(40, 40), - false); - SetLayerPropertiesForTesting(scroll_parent_clip.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(30, 30), - false); - SetLayerPropertiesForTesting(scroll_parent.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_child.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); - host->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); - - EXPECT_TRUE(root->render_surface()); - - EXPECT_EQ(gfx::Rect(0, 0, 30, 30).ToString(), - scroll_child->clip_rect().ToString()); - EXPECT_TRUE(scroll_child->is_clipped()); -} - -TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) { - // Checks that clipping by a scroll parent and scroll grandparent that follow - // you in paint order still results in correct clipping. - // - // + root - // + scroll_child - // + scroll_parent_border - // | + scroll_parent_clip - // | + scroll_parent - // + scroll_grandparent_border - // + scroll_grandparent_clip - // + scroll_grandparent - // - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> scroll_parent_border = Layer::Create(); - scoped_refptr<Layer> scroll_parent_clip = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> scroll_parent = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - scoped_refptr<Layer> scroll_grandparent_border = Layer::Create(); - scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - scoped_refptr<LayerWithForcedDrawsContent> scroll_child = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - root->AddChild(scroll_child); - - root->AddChild(scroll_parent_border); - scroll_parent_border->AddChild(scroll_parent_clip); - scroll_parent_clip->AddChild(scroll_parent); - - root->AddChild(scroll_grandparent_border); - scroll_grandparent_border->AddChild(scroll_grandparent_clip); - scroll_grandparent_clip->AddChild(scroll_grandparent); - - scroll_parent_clip->SetMasksToBounds(true); - scroll_grandparent_clip->SetMasksToBounds(true); - - scroll_child->SetScrollParent(scroll_parent.get()); - scroll_parent_border->SetScrollParent(scroll_grandparent.get()); - - gfx::Transform identity_transform; - SetLayerPropertiesForTesting(root.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_grandparent_border.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(40, 40), - false); - SetLayerPropertiesForTesting(scroll_grandparent_clip.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(20, 20), - false); - SetLayerPropertiesForTesting(scroll_grandparent.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_parent_border.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(40, 40), - false); - SetLayerPropertiesForTesting(scroll_parent_clip.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(30, 30), - false); - SetLayerPropertiesForTesting(scroll_parent.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_child.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); - host->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); - - EXPECT_TRUE(root->render_surface()); - - EXPECT_EQ(gfx::Rect(0, 0, 20, 20).ToString(), - scroll_child->clip_rect().ToString()); - EXPECT_TRUE(scroll_child->is_clipped()); - - // Despite the fact that we visited the above layers out of order to get the - // correct clip, the layer lists should be unaffected. - EXPECT_EQ(3u, root->render_surface()->layer_list().size()); - EXPECT_EQ(scroll_child.get(), - root->render_surface()->layer_list().at(0)); - EXPECT_EQ(scroll_parent.get(), - root->render_surface()->layer_list().at(1)); - EXPECT_EQ(scroll_grandparent.get(), - root->render_surface()->layer_list().at(2)); -} - -TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) { - // Ensures that even if we visit layers out of order, we still produce a - // correctly order render surface layer list. - // + root - // + scroll_child - // + scroll_parent_border - // + scroll_parent_clip - // + scroll_parent - // + render_surface1 - // + scroll_grandparent_border - // + scroll_grandparent_clip - // + scroll_grandparent - // + render_surface2 - // - scoped_refptr<Layer> root = Layer::Create(); - - scoped_refptr<Layer> scroll_parent_border = Layer::Create(); - scoped_refptr<Layer> scroll_parent_clip = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> scroll_parent = - make_scoped_refptr(new LayerWithForcedDrawsContent); - scoped_refptr<LayerWithForcedDrawsContent> render_surface1 = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - scoped_refptr<Layer> scroll_grandparent_border = Layer::Create(); - scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create(); - scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent = - make_scoped_refptr(new LayerWithForcedDrawsContent); - scoped_refptr<LayerWithForcedDrawsContent> render_surface2 = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - scoped_refptr<LayerWithForcedDrawsContent> scroll_child = - make_scoped_refptr(new LayerWithForcedDrawsContent); - - root->AddChild(scroll_child); - - root->AddChild(scroll_parent_border); - scroll_parent_border->AddChild(scroll_parent_clip); - scroll_parent_clip->AddChild(scroll_parent); - scroll_parent->AddChild(render_surface2); - - root->AddChild(scroll_grandparent_border); - scroll_grandparent_border->AddChild(scroll_grandparent_clip); - scroll_grandparent_clip->AddChild(scroll_grandparent); - scroll_grandparent->AddChild(render_surface1); - - scroll_parent_clip->SetMasksToBounds(true); - scroll_grandparent_clip->SetMasksToBounds(true); - - scroll_child->SetScrollParent(scroll_parent.get()); - scroll_parent_border->SetScrollParent(scroll_grandparent.get()); - - render_surface1->SetForceRenderSurface(true); - render_surface2->SetForceRenderSurface(true); - - gfx::Transform identity_transform; - SetLayerPropertiesForTesting(root.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_grandparent_border.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(40, 40), - false); - SetLayerPropertiesForTesting(scroll_grandparent_clip.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(20, 20), - false); - SetLayerPropertiesForTesting(scroll_grandparent.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(render_surface1.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_parent_border.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(40, 40), - false); - SetLayerPropertiesForTesting(scroll_parent_clip.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(30, 30), - false); - SetLayerPropertiesForTesting(scroll_parent.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(render_surface2.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_child.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - - scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(); - host->SetRootLayer(root); - - RenderSurfaceLayerList render_surface_layer_list; - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - root.get(), - root->bounds(), - identity_transform, - &render_surface_layer_list); - - LayerTreeHostCommon::CalculateDrawProperties(&inputs); - - EXPECT_TRUE(root->render_surface()); - - EXPECT_EQ(gfx::Rect(0, 0, 20, 20).ToString(), - scroll_child->clip_rect().ToString()); - EXPECT_TRUE(scroll_child->is_clipped()); - - // Despite the fact that we had to process the layers out of order to get the - // right clip, our render_surface_layer_list's order should be unaffected. - EXPECT_EQ(3u, render_surface_layer_list.size()); - EXPECT_EQ(root.get(), render_surface_layer_list.at(0)); - EXPECT_EQ(render_surface2.get(), render_surface_layer_list.at(1)); - EXPECT_EQ(render_surface1.get(), render_surface_layer_list.at(2)); -} - -TEST_F(LayerTreeHostCommonTest, DoNotClobberSorting) { - // We rearrange layer list contributions if we have to visit children out of - // order, but it should be a 'stable' rearrangement. That is, the layer list - // additions for a single layer should not be reordered, though their position - // wrt to the contributions due to a sibling may vary. - // - // + root - // + scroll_child - // + top_content - // + bottom_content - // + scroll_parent_border - // + scroll_parent_clip - // + scroll_parent - // - FakeImplProxy proxy; - FakeLayerTreeHostImpl host_impl(&proxy); - host_impl.CreatePendingTree(); - scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); - scoped_ptr<LayerImpl> scroll_parent_border = - LayerImpl::Create(host_impl.active_tree(), 2); - scoped_ptr<LayerImpl> scroll_parent_clip = - LayerImpl::Create(host_impl.active_tree(), 3); - scoped_ptr<LayerImpl> scroll_parent = - LayerImpl::Create(host_impl.active_tree(), 4); - scoped_ptr<LayerImpl> scroll_child = - LayerImpl::Create(host_impl.active_tree(), 5); - scoped_ptr<LayerImpl> bottom_content = - LayerImpl::Create(host_impl.active_tree(), 6); - scoped_ptr<LayerImpl> top_content = - LayerImpl::Create(host_impl.active_tree(), 7); - - scroll_parent_clip->SetMasksToBounds(true); - - scroll_child->SetScrollParent(scroll_parent.get()); - scoped_ptr<std::set<LayerImpl*> > scroll_children(new std::set<LayerImpl*>); - scroll_children->insert(scroll_child.get()); - scroll_parent->SetScrollChildren(scroll_children.release()); - - scroll_child->SetDrawsContent(true); - scroll_parent->SetDrawsContent(true); - top_content->SetDrawsContent(true); - bottom_content->SetDrawsContent(true); - - gfx::Transform identity_transform; - gfx::Transform top_transform; - top_transform.Translate3d(0.0, 0.0, 5.0); - gfx::Transform bottom_transform; - bottom_transform.Translate3d(0.0, 0.0, 3.0); - - SetLayerPropertiesForTesting(root.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_parent_border.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(40, 40), - false); - SetLayerPropertiesForTesting(scroll_parent_clip.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(30, 30), - false); - SetLayerPropertiesForTesting(scroll_parent.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(scroll_child.get(), - identity_transform, - identity_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(top_content.get(), - top_transform, - top_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - SetLayerPropertiesForTesting(bottom_content.get(), - bottom_transform, - bottom_transform, - gfx::PointF(), - gfx::PointF(), - gfx::Size(50, 50), - false); - - scroll_child->SetPreserves3d(true); - - scroll_child->AddChild(top_content.Pass()); - scroll_child->AddChild(bottom_content.Pass()); - root->AddChild(scroll_child.Pass()); - - scroll_parent_clip->AddChild(scroll_parent.Pass()); - scroll_parent_border->AddChild(scroll_parent_clip.Pass()); - root->AddChild(scroll_parent_border.Pass()); - - LayerImplList render_surface_layer_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root.get(), root->bounds(), &render_surface_layer_list); - - LayerTreeHostCommon::CalculateDrawProperties(&inputs); - - EXPECT_TRUE(root->render_surface()); - - // If we don't sort by depth and let the layers get added in the order they - // would normally be visited in, then layers 6 and 7 will be out of order. In - // other words, although we've had to shift 5, 6, and 7 to appear before 4 - // in the list (because of the scroll parent relationship), this should not - // have an effect on the the order of 5, 6, and 7 (which had been reordered - // due to layer sorting). - EXPECT_EQ(4u, root->render_surface()->layer_list().size()); - EXPECT_EQ(5, root->render_surface()->layer_list().at(0)->id()); - EXPECT_EQ(6, root->render_surface()->layer_list().at(1)->id()); - EXPECT_EQ(7, root->render_surface()->layer_list().at(2)->id()); - EXPECT_EQ(4, root->render_surface()->layer_list().at(3)->id()); -} - } // namespace } // namespace cc |