Commit f9e56701 authored by vollick@chromium.org's avatar vollick@chromium.org

Do not skip subtrees with wheel or touch handlers

When calculating draw properties, we attempt to skip subtrees whenever
we can, but we missed a corner case: even though we don't necessarily
draw a layer with a wheel or touch handler, it will participate in hit
testing and must therefore have up-to-date transforms, targets, etc.
In the same way that we've added logic to prevent skipping subtrees
containing layers with copy requests, this CL prevents skipping subtrees
with handlers.

R=danakj@chromium.org
BUG=377738

Review URL: https://codereview.chromium.org/335633003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276877 0039d316-1c4b-4281-b951-d872f2087c98
parent 03febad9
...@@ -29,6 +29,7 @@ struct CC_EXPORT DrawProperties { ...@@ -29,6 +29,7 @@ struct CC_EXPORT DrawProperties {
num_descendants_that_draw_content(0), num_descendants_that_draw_content(0),
num_unclipped_descendants(0), num_unclipped_descendants(0),
layer_or_descendant_has_copy_request(false), layer_or_descendant_has_copy_request(false),
layer_or_descendant_has_input_handler(false),
has_child_with_a_scroll_parent(false), has_child_with_a_scroll_parent(false),
sorted_for_recursion(false), sorted_for_recursion(false),
index_of_first_descendants_addition(0), index_of_first_descendants_addition(0),
...@@ -102,6 +103,9 @@ struct CC_EXPORT DrawProperties { ...@@ -102,6 +103,9 @@ struct CC_EXPORT DrawProperties {
// present on it. // present on it.
bool layer_or_descendant_has_copy_request; bool layer_or_descendant_has_copy_request;
// If true, the layer or one of its descendants has a wheel or touch handler.
bool layer_or_descendant_has_input_handler;
// This is true if the layer has any direct child that has a scroll parent. // This is true if the layer has any direct child that has a scroll parent.
// This layer will not be the scroll parent in this case. This information // This layer will not be the scroll parent in this case. This information
// lets us avoid work in CalculateDrawPropertiesInternal -- if none of our // lets us avoid work in CalculateDrawPropertiesInternal -- if none of our
......
...@@ -487,6 +487,11 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer, ...@@ -487,6 +487,11 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer,
if (layer->draw_properties().layer_or_descendant_has_copy_request) if (layer->draw_properties().layer_or_descendant_has_copy_request)
return false; return false;
// We cannot skip the the subtree if a descendant has a wheel or touch handler
// or the hit testing code will break (it requires fresh transforms, etc).
if (layer->draw_properties().layer_or_descendant_has_input_handler)
return false;
// If the layer is not drawn, then skip it and its subtree. // If the layer is not drawn, then skip it and its subtree.
if (!layer_is_drawn) if (!layer_is_drawn)
return true; return true;
...@@ -513,6 +518,11 @@ static inline bool SubtreeShouldBeSkipped(Layer* layer, bool layer_is_drawn) { ...@@ -513,6 +518,11 @@ static inline bool SubtreeShouldBeSkipped(Layer* layer, bool layer_is_drawn) {
if (layer->draw_properties().layer_or_descendant_has_copy_request) if (layer->draw_properties().layer_or_descendant_has_copy_request)
return false; return false;
// We cannot skip the the subtree if a descendant has a wheel or touch handler
// or the hit testing code will break (it requires fresh transforms, etc).
if (layer->draw_properties().layer_or_descendant_has_input_handler)
return false;
// If the layer is not drawn, then skip it and its subtree. // If the layer is not drawn, then skip it and its subtree.
if (!layer_is_drawn) if (!layer_is_drawn)
return true; return true;
...@@ -1184,15 +1194,19 @@ static inline void RemoveSurfaceForEarlyExit( ...@@ -1184,15 +1194,19 @@ static inline void RemoveSurfaceForEarlyExit(
struct PreCalculateMetaInformationRecursiveData { struct PreCalculateMetaInformationRecursiveData {
bool layer_or_descendant_has_copy_request; bool layer_or_descendant_has_copy_request;
bool layer_or_descendant_has_input_handler;
int num_unclipped_descendants; int num_unclipped_descendants;
PreCalculateMetaInformationRecursiveData() PreCalculateMetaInformationRecursiveData()
: layer_or_descendant_has_copy_request(false), : layer_or_descendant_has_copy_request(false),
layer_or_descendant_has_input_handler(false),
num_unclipped_descendants(0) {} num_unclipped_descendants(0) {}
void Merge(const PreCalculateMetaInformationRecursiveData& data) { void Merge(const PreCalculateMetaInformationRecursiveData& data) {
layer_or_descendant_has_copy_request |= layer_or_descendant_has_copy_request |=
data.layer_or_descendant_has_copy_request; data.layer_or_descendant_has_copy_request;
layer_or_descendant_has_input_handler |=
data.layer_or_descendant_has_input_handler;
num_unclipped_descendants += num_unclipped_descendants +=
data.num_unclipped_descendants; data.num_unclipped_descendants;
} }
...@@ -1252,12 +1266,18 @@ static void PreCalculateMetaInformation( ...@@ -1252,12 +1266,18 @@ static void PreCalculateMetaInformation(
if (layer->HasCopyRequest()) if (layer->HasCopyRequest())
recursive_data->layer_or_descendant_has_copy_request = true; recursive_data->layer_or_descendant_has_copy_request = true;
if (!layer->touch_event_handler_region().IsEmpty() ||
layer->have_wheel_event_handlers())
recursive_data->layer_or_descendant_has_input_handler = true;
layer->draw_properties().num_descendants_that_draw_content = layer->draw_properties().num_descendants_that_draw_content =
num_descendants_that_draw_content; num_descendants_that_draw_content;
layer->draw_properties().num_unclipped_descendants = layer->draw_properties().num_unclipped_descendants =
recursive_data->num_unclipped_descendants; recursive_data->num_unclipped_descendants;
layer->draw_properties().layer_or_descendant_has_copy_request = layer->draw_properties().layer_or_descendant_has_copy_request =
recursive_data->layer_or_descendant_has_copy_request; recursive_data->layer_or_descendant_has_copy_request;
layer->draw_properties().layer_or_descendant_has_input_handler =
recursive_data->layer_or_descendant_has_input_handler;
} }
static void RoundTranslationComponents(gfx::Transform* transform) { static void RoundTranslationComponents(gfx::Transform* transform) {
......
...@@ -156,6 +156,52 @@ TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { ...@@ -156,6 +156,52 @@ TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) {
grand_child->screen_space_transform()); grand_child->screen_space_transform());
} }
TEST_F(LayerTreeHostCommonTest, DoNotSkipLayersWithHandlers) {
scoped_refptr<Layer> parent = Layer::Create();
scoped_refptr<Layer> child = Layer::Create();
scoped_refptr<Layer> grand_child = Layer::Create();
parent->AddChild(child);
child->AddChild(grand_child);
scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
host->SetRootLayer(parent);
gfx::Transform identity_matrix;
SetLayerPropertiesForTesting(parent.get(),
identity_matrix,
gfx::Point3F(),
gfx::PointF(),
gfx::Size(100, 100),
true,
false);
SetLayerPropertiesForTesting(child.get(),
identity_matrix,
gfx::Point3F(),
gfx::PointF(10, 10),
gfx::Size(100, 100),
true,
false);
// This would have previously caused us to skip our subtree, but this would be
// wrong; we need up-to-date draw properties to do hit testing on the layers
// with handlers.
child->SetOpacity(0.f);
SetLayerPropertiesForTesting(grand_child.get(),
identity_matrix,
gfx::Point3F(),
gfx::PointF(10, 10),
gfx::Size(100, 100),
true,
false);
grand_child->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));
ExecuteCalculateDrawProperties(parent.get());
// Check that we've computed draw properties for the subtree rooted at
// |child|.
EXPECT_FALSE(child->draw_transform().IsIdentity());
EXPECT_FALSE(grand_child->draw_transform().IsIdentity());
}
TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
gfx::Transform identity_matrix; gfx::Transform identity_matrix;
scoped_refptr<Layer> layer = Layer::Create(); scoped_refptr<Layer> layer = Layer::Create();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment