summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 17:14:40 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 17:14:40 +0000
commit390bb1ffa2850198c18caf7e49a75a908c3312c5 (patch)
tree092d86a0ac481ee2f3f37c3bc7e7cfdc7867c8c1 /cc
parentf043dba82ee9959084637d1f0ee68dace1f72cf8 (diff)
downloadchromium_src-390bb1ffa2850198c18caf7e49a75a908c3312c5.zip
chromium_src-390bb1ffa2850198c18caf7e49a75a908c3312c5.tar.gz
chromium_src-390bb1ffa2850198c18caf7e49a75a908c3312c5.tar.bz2
cc: Add a flag to layers that returns true if the layer is in RSLL.
This patch adds a flag that says whether the layer is currently in RSLL. Used to remove layers that previously were in RSLL and are no longer there. R=enne, danakj Review URL: https://codereview.chromium.org/265883013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269353 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/layers/draw_properties.h12
-rw-r--r--cc/layers/layer_impl.cc5
-rw-r--r--cc/layers/layer_impl.h2
-rw-r--r--cc/trees/layer_tree_host.cc7
-rw-r--r--cc/trees/layer_tree_host_common.cc99
-rw-r--r--cc/trees/layer_tree_host_common.h14
-rw-r--r--cc/trees/layer_tree_host_common_perftest.cc6
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc309
-rw-r--r--cc/trees/layer_tree_impl.cc9
-rw-r--r--cc/trees/layer_tree_impl.h6
10 files changed, 436 insertions, 33 deletions
diff --git a/cc/layers/draw_properties.h b/cc/layers/draw_properties.h
index 5fd42a4..3f167b9 100644
--- a/cc/layers/draw_properties.h
+++ b/cc/layers/draw_properties.h
@@ -34,7 +34,8 @@ struct CC_EXPORT DrawProperties {
index_of_first_descendants_addition(0),
num_descendants_added(0),
index_of_first_render_surface_layer_list_addition(0),
- num_render_surfaces_added(0) {}
+ num_render_surfaces_added(0),
+ last_drawn_render_surface_layer_list_id(0) {}
// Transforms objects from content space to target surface space, where
// this layer would be drawn.
@@ -118,6 +119,15 @@ struct CC_EXPORT DrawProperties {
size_t num_descendants_added;
size_t index_of_first_render_surface_layer_list_addition;
size_t num_render_surfaces_added;
+
+ // Each time we generate a new render surface layer list, an ID is used to
+ // identify it. |last_drawn_render_surface_layer_list_id| is set to the ID
+ // that marked the render surface layer list generation which last updated
+ // these draw properties and determined that this layer will draw itself.
+ // If these draw properties are not a part of the render surface layer list,
+ // or the layer doesn't contribute anything, then this ID will be either out
+ // of date or 0.
+ int last_drawn_render_surface_layer_list_id;
};
} // namespace cc
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index fd5ea31..a6738cc 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -1500,6 +1500,11 @@ void LayerImpl::AsValueInto(base::DictionaryValue* state) const {
}
}
+bool LayerImpl::IsDrawnRenderSurfaceLayerListMember() const {
+ return draw_properties_.last_drawn_render_surface_layer_list_id ==
+ layer_tree_impl_->current_render_surface_list_id();
+}
+
size_t LayerImpl::GPUMemoryUsageInBytes() const { return 0; }
scoped_ptr<base::Value> LayerImpl::AsValue() const {
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index e84c669..16747aa 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -534,6 +534,8 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
virtual void SetDebugInfo(
scoped_refptr<base::debug::ConvertableToTraceFormat> other);
+ bool IsDrawnRenderSurfaceLayerListMember() const;
+
protected:
LayerImpl(LayerTreeImpl* layer_impl, int id);
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 7df3186..a532baf1 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -788,6 +788,10 @@ bool LayerTreeHost::UpdateLayers(Layer* root_layer,
TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::CalcDrawProps");
bool can_render_to_separate_surface = true;
+ // TODO(vmpstr): Passing 0 as the current render surface layer list id means
+ // that we won't be able to detect if a layer is part of |update_list|.
+ // Change this if this information is required.
+ int render_surface_layer_list_id = 0;
LayerTreeHostCommon::CalcDrawPropsMainInputs inputs(
root_layer,
device_viewport_size(),
@@ -799,7 +803,8 @@ bool LayerTreeHost::UpdateLayers(Layer* root_layer,
settings_.can_use_lcd_text,
can_render_to_separate_surface,
settings_.layer_transforms_should_scale_layer_contents,
- &update_list);
+ &update_list,
+ render_surface_layer_list_id);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
if (total_frames_used_for_lcd_text_metrics_ <=
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index ba92d8d..8a5a552 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -1129,6 +1129,42 @@ static inline typename LayerType::RenderSurfaceType* CreateOrReuseRenderSurface(
return layer->render_surface();
}
+template <typename LayerTypePtr>
+static inline void MarkLayerWithRenderSurfaceLayerListId(
+ LayerTypePtr layer,
+ int current_render_surface_layer_list_id) {
+ layer->draw_properties().last_drawn_render_surface_layer_list_id =
+ current_render_surface_layer_list_id;
+}
+
+template <typename LayerTypePtr>
+static inline void MarkMasksWithRenderSurfaceLayerListId(
+ LayerTypePtr layer,
+ int current_render_surface_layer_list_id) {
+ if (layer->mask_layer()) {
+ MarkLayerWithRenderSurfaceLayerListId(layer->mask_layer(),
+ current_render_surface_layer_list_id);
+ }
+ if (layer->replica_layer() && layer->replica_layer()->mask_layer()) {
+ MarkLayerWithRenderSurfaceLayerListId(layer->replica_layer()->mask_layer(),
+ current_render_surface_layer_list_id);
+ }
+}
+
+template <typename LayerListType>
+static inline void MarkLayerListWithRenderSurfaceLayerListId(
+ LayerListType* layer_list,
+ int current_render_surface_layer_list_id) {
+ for (typename LayerListType::iterator it = layer_list->begin();
+ it != layer_list->end();
+ ++it) {
+ MarkLayerWithRenderSurfaceLayerListId(*it,
+ current_render_surface_layer_list_id);
+ MarkMasksWithRenderSurfaceLayerListId(*it,
+ current_render_surface_layer_list_id);
+ }
+}
+
template <typename LayerType>
static inline void RemoveSurfaceForEarlyExit(
LayerType* layer_to_remove,
@@ -1141,10 +1177,17 @@ static inline void RemoveSurfaceForEarlyExit(
// things to crash. So here we proactively remove any additional
// layers from the end of the list.
while (render_surface_layer_list->back() != layer_to_remove) {
+ MarkLayerListWithRenderSurfaceLayerListId(
+ &render_surface_layer_list->back()->render_surface()->layer_list(), 0);
+ MarkLayerWithRenderSurfaceLayerListId(render_surface_layer_list->back(), 0);
+
render_surface_layer_list->back()->ClearRenderSurfaceLayerList();
render_surface_layer_list->pop_back();
}
DCHECK_EQ(render_surface_layer_list->back(), layer_to_remove);
+ MarkLayerListWithRenderSurfaceLayerListId(
+ &layer_to_remove->render_surface()->layer_list(), 0);
+ MarkLayerWithRenderSurfaceLayerListId(layer_to_remove, 0);
render_surface_layer_list->pop_back();
layer_to_remove->ClearRenderSurfaceLayerList();
}
@@ -1423,8 +1466,8 @@ static void CalculateDrawPropertiesInternal(
const DataForRecursion<LayerType>& data_from_ancestor,
typename LayerType::RenderSurfaceListType* render_surface_layer_list,
typename LayerType::LayerListType* layer_list,
- std::vector<AccumulatedSurfaceState<LayerType> >*
- accumulated_surface_state) {
+ std::vector<AccumulatedSurfaceState<LayerType> >* accumulated_surface_state,
+ int current_render_surface_layer_list_id) {
// This function computes the new matrix transformations recursively for this
// layer and all its descendants. It also computes the appropriate render
// surfaces.
@@ -2011,8 +2054,11 @@ static void CalculateDrawPropertiesInternal(
// and should be included in the sorting process.
size_t sorting_start_index = descendants.size();
- if (!LayerShouldBeSkipped(layer, layer_is_drawn))
+ if (!LayerShouldBeSkipped(layer, layer_is_drawn)) {
+ MarkLayerWithRenderSurfaceLayerListId(layer,
+ current_render_surface_layer_list_id);
descendants.push_back(layer);
+ }
// Any layers that are appended after this point may need to be sorted if we
// visit the children out of order.
@@ -2072,15 +2118,22 @@ static void CalculateDrawPropertiesInternal(
child->draw_properties().index_of_first_render_surface_layer_list_addition =
render_surface_layer_list->size();
- CalculateDrawPropertiesInternal<LayerType>(child,
- globals,
- data_for_children,
- render_surface_layer_list,
- &descendants,
- accumulated_surface_state);
+ CalculateDrawPropertiesInternal<LayerType>(
+ child,
+ globals,
+ data_for_children,
+ render_surface_layer_list,
+ &descendants,
+ accumulated_surface_state,
+ current_render_surface_layer_list_id);
if (child->render_surface() &&
!child->render_surface()->layer_list().empty() &&
!child->render_surface()->content_rect().IsEmpty()) {
+ // This child will contribute its render surface, which means
+ // we need to mark just the mask layer (and replica mask layer)
+ // with the id.
+ MarkMasksWithRenderSurfaceLayerListId(
+ child, current_render_surface_layer_list_id);
descendants.push_back(child);
}
@@ -2328,12 +2381,14 @@ void LayerTreeHostCommon::CalculateDrawProperties(
PreCalculateMetaInformationRecursiveData recursive_data;
PreCalculateMetaInformation(inputs->root_layer, &recursive_data);
std::vector<AccumulatedSurfaceState<Layer> > accumulated_surface_state;
- CalculateDrawPropertiesInternal<Layer>(inputs->root_layer,
- globals,
- data_for_recursion,
- inputs->render_surface_layer_list,
- &dummy_layer_list,
- &accumulated_surface_state);
+ CalculateDrawPropertiesInternal<Layer>(
+ inputs->root_layer,
+ globals,
+ data_for_recursion,
+ inputs->render_surface_layer_list,
+ &dummy_layer_list,
+ &accumulated_surface_state,
+ inputs->current_render_surface_layer_list_id);
// The dummy layer list should not have been used.
DCHECK_EQ(0u, dummy_layer_list.size());
@@ -2356,12 +2411,14 @@ void LayerTreeHostCommon::CalculateDrawProperties(
PreCalculateMetaInformation(inputs->root_layer, &recursive_data);
std::vector<AccumulatedSurfaceState<LayerImpl> >
accumulated_surface_state;
- CalculateDrawPropertiesInternal<LayerImpl>(inputs->root_layer,
- globals,
- data_for_recursion,
- inputs->render_surface_layer_list,
- &dummy_layer_list,
- &accumulated_surface_state);
+ CalculateDrawPropertiesInternal<LayerImpl>(
+ inputs->root_layer,
+ globals,
+ data_for_recursion,
+ inputs->render_surface_layer_list,
+ &dummy_layer_list,
+ &accumulated_surface_state,
+ inputs->current_render_surface_layer_list_id);
// The dummy layer list should not have been used.
DCHECK_EQ(0u, dummy_layer_list.size());
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h
index de9a713..5090c69 100644
--- a/cc/trees/layer_tree_host_common.h
+++ b/cc/trees/layer_tree_host_common.h
@@ -41,7 +41,8 @@ class CC_EXPORT LayerTreeHostCommon {
bool can_use_lcd_text,
bool can_render_to_separate_surface,
bool can_adjust_raster_scales,
- RenderSurfaceLayerListType* render_surface_layer_list)
+ RenderSurfaceLayerListType* render_surface_layer_list,
+ int current_render_surface_layer_list_id)
: root_layer(root_layer),
device_viewport_size(device_viewport_size),
device_transform(device_transform),
@@ -52,7 +53,9 @@ class CC_EXPORT LayerTreeHostCommon {
can_use_lcd_text(can_use_lcd_text),
can_render_to_separate_surface(can_render_to_separate_surface),
can_adjust_raster_scales(can_adjust_raster_scales),
- render_surface_layer_list(render_surface_layer_list) {}
+ render_surface_layer_list(render_surface_layer_list),
+ current_render_surface_layer_list_id(
+ current_render_surface_layer_list_id) {}
LayerType* root_layer;
gfx::Size device_viewport_size;
@@ -65,6 +68,7 @@ class CC_EXPORT LayerTreeHostCommon {
bool can_render_to_separate_surface;
bool can_adjust_raster_scales;
RenderSurfaceLayerListType* render_surface_layer_list;
+ int current_render_surface_layer_list_id;
};
template <typename LayerType, typename RenderSurfaceLayerListType>
@@ -233,7 +237,8 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
false,
true,
false,
- render_surface_layer_list) {
+ render_surface_layer_list,
+ 0) {
DCHECK(root_layer);
DCHECK(render_surface_layer_list);
}
@@ -256,7 +261,8 @@ LayerTreeHostCommon::CalcDrawPropsInputsForTesting<LayerType,
false,
true,
false,
- render_surface_layer_list) {
+ render_surface_layer_list,
+ 0) {
DCHECK(root_layer);
DCHECK(render_surface_layer_list);
}
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index 7e50e36..758bb4c 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -97,7 +97,8 @@ class CalcDrawPropsMainTest : public LayerTreeHostCommonPerfTest {
layer_tree_host()
->settings()
.layer_transforms_should_scale_layer_contents,
- &update_list);
+ &update_list,
+ 0);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
timer_.NextLap();
@@ -136,7 +137,8 @@ class CalcDrawPropsImplTest : public LayerTreeHostCommonPerfTest {
host_impl->settings().can_use_lcd_text,
can_render_to_separate_surface,
host_impl->settings().layer_transforms_should_scale_layer_contents,
- &update_list);
+ &update_list,
+ 0);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
timer_.NextLap();
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index a1210c4f..48a665d 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -15,6 +15,7 @@
#include "cc/layers/layer.h"
#include "cc/layers/layer_client.h"
#include "cc/layers/layer_impl.h"
+#include "cc/layers/layer_iterator.h"
#include "cc/layers/render_surface.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/output/copy_output_request.h"
@@ -38,6 +39,8 @@ namespace {
class LayerTreeHostCommonTestBase {
protected:
+ LayerTreeHostCommonTestBase() : render_surface_layer_list_count_(0) {}
+
template <typename LayerType>
void SetLayerPropertiesForTestingInternal(
LayerType* layer,
@@ -120,21 +123,29 @@ class LayerTreeHostCommonTestBase {
LayerImpl* page_scale_application_layer,
bool can_use_lcd_text) {
gfx::Transform identity_matrix;
- LayerImplList dummy_render_surface_layer_list;
gfx::Size device_viewport_size =
gfx::Size(root_layer->bounds().width() * device_scale_factor,
root_layer->bounds().height() * device_scale_factor);
+ render_surface_layer_list_impl_.reset(new LayerImplList);
+
// We are probably not testing what is intended if the root_layer bounds are
// empty.
DCHECK(!root_layer->bounds().IsEmpty());
LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
- root_layer, device_viewport_size, &dummy_render_surface_layer_list);
+ root_layer,
+ device_viewport_size,
+ render_surface_layer_list_impl_.get());
inputs.device_scale_factor = device_scale_factor;
inputs.page_scale_factor = page_scale_factor;
inputs.page_scale_application_layer = page_scale_application_layer;
inputs.can_use_lcd_text = can_use_lcd_text;
inputs.can_adjust_raster_scales = true;
+
+ ++render_surface_layer_list_count_;
+ inputs.current_render_surface_layer_list_id =
+ render_surface_layer_list_count_;
+
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}
@@ -172,8 +183,19 @@ class LayerTreeHostCommonTestBase {
return render_surface_layer_list_.get();
}
+ LayerImplList* render_surface_layer_list_impl() const {
+ return render_surface_layer_list_impl_.get();
+ }
+
+ int render_surface_layer_list_count() const {
+ return render_surface_layer_list_count_;
+ }
+
private:
scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
+ scoped_ptr<LayerImplList> render_surface_layer_list_impl_;
+
+ int render_surface_layer_list_count_;
};
class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase,
@@ -10152,5 +10174,288 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) {
EXPECT_EQ(0.f, grand_child_raw->last_maximum_animation_contents_scale());
}
+static int membership_id(LayerImpl* layer) {
+ return layer->draw_properties().last_drawn_render_surface_layer_list_id;
+}
+
+static void GatherDrawnLayers(LayerImplList* rsll,
+ std::set<LayerImpl*>* drawn_layers) {
+ for (LayerIterator<LayerImpl> it = LayerIterator<LayerImpl>::Begin(rsll),
+ end = LayerIterator<LayerImpl>::End(rsll);
+ it != end;
+ ++it) {
+ LayerImpl* layer = *it;
+ if (it.represents_itself())
+ drawn_layers->insert(layer);
+
+ if (!it.represents_contributing_render_surface())
+ continue;
+
+ if (layer->mask_layer())
+ drawn_layers->insert(layer->mask_layer());
+ if (layer->replica_layer() && layer->replica_layer()->mask_layer())
+ drawn_layers->insert(layer->replica_layer()->mask_layer());
+ }
+}
+
+TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) {
+ FakeImplProxy proxy;
+ TestSharedBitmapManager shared_bitmap_manager;
+ FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
+ gfx::Transform identity_matrix;
+
+ scoped_ptr<LayerImpl> grand_parent =
+ LayerImpl::Create(host_impl.active_tree(), 1);
+ scoped_ptr<LayerImpl> parent = LayerImpl::Create(host_impl.active_tree(), 3);
+ scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.active_tree(), 5);
+ scoped_ptr<LayerImpl> grand_child1 =
+ LayerImpl::Create(host_impl.active_tree(), 7);
+ scoped_ptr<LayerImpl> grand_child2 =
+ LayerImpl::Create(host_impl.active_tree(), 9);
+
+ LayerImpl* grand_parent_raw = grand_parent.get();
+ LayerImpl* parent_raw = parent.get();
+ LayerImpl* child_raw = child.get();
+ LayerImpl* grand_child1_raw = grand_child1.get();
+ LayerImpl* grand_child2_raw = grand_child2.get();
+
+ child->AddChild(grand_child1.Pass());
+ child->AddChild(grand_child2.Pass());
+ parent->AddChild(child.Pass());
+ grand_parent->AddChild(parent.Pass());
+
+ SetLayerPropertiesForTesting(grand_parent_raw,
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(1, 2),
+ true,
+ false);
+ SetLayerPropertiesForTesting(parent_raw,
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(1, 2),
+ true,
+ false);
+ SetLayerPropertiesForTesting(child_raw,
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(1, 2),
+ true,
+ false);
+ SetLayerPropertiesForTesting(grand_child1_raw,
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(1, 2),
+ true,
+ false);
+ SetLayerPropertiesForTesting(grand_child2_raw,
+ identity_matrix,
+ gfx::PointF(),
+ gfx::PointF(),
+ gfx::Size(1, 2),
+ true,
+ false);
+
+ // Start with nothing being drawn.
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ int member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_NE(member_id, membership_id(child_raw));
+ EXPECT_NE(member_id, membership_id(grand_child1_raw));
+ EXPECT_NE(member_id, membership_id(grand_child2_raw));
+
+ std::set<LayerImpl*> expected;
+ std::set<LayerImpl*> actual;
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ // If we force render surface, but none of the layers are in the layer list,
+ // then this layer should not appear in RSLL.
+ grand_child1_raw->SetForceRenderSurface(true);
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_NE(member_id, membership_id(child_raw));
+ EXPECT_NE(member_id, membership_id(grand_child1_raw));
+ EXPECT_NE(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ // However, if we say that this layer also draws content, it will appear in
+ // RSLL.
+ grand_child1_raw->SetDrawsContent(true);
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_NE(member_id, membership_id(child_raw));
+ EXPECT_EQ(member_id, membership_id(grand_child1_raw));
+ EXPECT_NE(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ expected.insert(grand_child1_raw);
+
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ // Now child is forced to have a render surface, and one if its children draws
+ // content.
+ grand_child1_raw->SetDrawsContent(false);
+ grand_child1_raw->SetForceRenderSurface(false);
+ child_raw->SetForceRenderSurface(true);
+ grand_child2_raw->SetDrawsContent(true);
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_NE(member_id, membership_id(child_raw));
+ EXPECT_NE(member_id, membership_id(grand_child1_raw));
+ EXPECT_EQ(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ expected.insert(grand_child2_raw);
+
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ // Add a mask layer to child.
+ child_raw->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 6).Pass());
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_NE(member_id, membership_id(child_raw));
+ EXPECT_EQ(member_id, membership_id(child_raw->mask_layer()));
+ EXPECT_NE(member_id, membership_id(grand_child1_raw));
+ EXPECT_EQ(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ expected.insert(grand_child2_raw);
+ expected.insert(child_raw->mask_layer());
+
+ expected.clear();
+ expected.insert(grand_child2_raw);
+ expected.insert(child_raw->mask_layer());
+
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ // Add replica mask layer.
+ scoped_ptr<LayerImpl> replica_layer =
+ LayerImpl::Create(host_impl.active_tree(), 20);
+ replica_layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 21));
+ child_raw->SetReplicaLayer(replica_layer.Pass());
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_NE(member_id, membership_id(child_raw));
+ EXPECT_EQ(member_id, membership_id(child_raw->mask_layer()));
+ EXPECT_EQ(member_id, membership_id(child_raw->replica_layer()->mask_layer()));
+ EXPECT_NE(member_id, membership_id(grand_child1_raw));
+ EXPECT_EQ(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ expected.insert(grand_child2_raw);
+ expected.insert(child_raw->mask_layer());
+ expected.insert(child_raw->replica_layer()->mask_layer());
+
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ child_raw->TakeReplicaLayer();
+
+ // With nothing drawing, we should have no layers.
+ grand_child2_raw->SetDrawsContent(false);
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_NE(member_id, membership_id(child_raw));
+ EXPECT_NE(member_id, membership_id(child_raw->mask_layer()));
+ EXPECT_NE(member_id, membership_id(grand_child1_raw));
+ EXPECT_NE(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ // Child itself draws means that we should have the child and the mask in the
+ // list.
+ child_raw->SetDrawsContent(true);
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_NE(member_id, membership_id(grand_parent_raw));
+ EXPECT_NE(member_id, membership_id(parent_raw));
+ EXPECT_EQ(member_id, membership_id(child_raw));
+ EXPECT_EQ(member_id, membership_id(child_raw->mask_layer()));
+ EXPECT_NE(member_id, membership_id(grand_child1_raw));
+ EXPECT_NE(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ expected.insert(child_raw);
+ expected.insert(child_raw->mask_layer());
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+
+ child_raw->TakeMaskLayer();
+
+ // Now everyone's a member!
+ grand_parent_raw->SetDrawsContent(true);
+ parent_raw->SetDrawsContent(true);
+ child_raw->SetDrawsContent(true);
+ grand_child1_raw->SetDrawsContent(true);
+ grand_child2_raw->SetDrawsContent(true);
+
+ ExecuteCalculateDrawProperties(grand_parent_raw);
+ member_id = render_surface_layer_list_count();
+
+ EXPECT_EQ(member_id, membership_id(grand_parent_raw));
+ EXPECT_EQ(member_id, membership_id(parent_raw));
+ EXPECT_EQ(member_id, membership_id(child_raw));
+ EXPECT_EQ(member_id, membership_id(grand_child1_raw));
+ EXPECT_EQ(member_id, membership_id(grand_child2_raw));
+
+ expected.clear();
+ expected.insert(grand_parent_raw);
+ expected.insert(parent_raw);
+ expected.insert(child_raw);
+ expected.insert(grand_child1_raw);
+ expected.insert(grand_child2_raw);
+
+ actual.clear();
+ GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
+ EXPECT_EQ(expected, actual);
+}
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 465c9cc..962ce7d 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -97,7 +97,9 @@ LayerTreeImpl::LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl)
viewport_size_invalid_(false),
needs_update_draw_properties_(true),
needs_full_tree_sync_(true),
- next_activation_forces_redraw_(false) {}
+ next_activation_forces_redraw_(false),
+ render_surface_layer_list_id_(0) {
+}
LayerTreeImpl::~LayerTreeImpl() {
// Need to explicitly clear the tree prior to destroying this so that
@@ -457,6 +459,8 @@ void LayerTreeImpl::UpdateDrawProperties() {
page_scale_layer_ ? page_scale_layer_ : InnerViewportContainerLayer();
bool can_render_to_separate_surface =
!output_surface()->ForcedDrawToSoftwareDevice();
+
+ ++render_surface_layer_list_id_;
LayerTreeHostCommon::CalcDrawPropsImplInputs inputs(
root_layer(),
DrawViewportSize(),
@@ -468,7 +472,8 @@ void LayerTreeImpl::UpdateDrawProperties() {
settings().can_use_lcd_text,
can_render_to_separate_surface,
settings().layer_transforms_should_scale_layer_contents,
- &render_surface_layer_list_);
+ &render_surface_layer_list_,
+ render_surface_layer_list_id_);
LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index bc488db..be53d19 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -244,6 +244,10 @@ class CC_EXPORT LayerTreeImpl {
void RemoveLayerWithCopyOutputRequest(LayerImpl* layer);
const std::vector<LayerImpl*>& LayersWithCopyOutputRequest() const;
+ int current_render_surface_list_id() const {
+ return render_surface_layer_list_id_;
+ }
+
protected:
explicit LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl);
@@ -297,6 +301,8 @@ class CC_EXPORT LayerTreeImpl {
UIResourceRequestQueue ui_resource_request_queue_;
+ int render_surface_layer_list_id_;
+
private:
DISALLOW_COPY_AND_ASSIGN(LayerTreeImpl);
};