summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-05 01:14:10 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-05 01:14:10 +0000
commitafc4f26f51818368ae6d9ea3fbe643df2cba6d52 (patch)
treea09b4e00a231912eeb3de65eef5509f973e91489
parenta9588a1467dd8b214b6e85bbc5b35ce9824ea701 (diff)
downloadchromium_src-afc4f26f51818368ae6d9ea3fbe643df2cba6d52.zip
chromium_src-afc4f26f51818368ae6d9ea3fbe643df2cba6d52.tar.gz
chromium_src-afc4f26f51818368ae6d9ea3fbe643df2cba6d52.tar.bz2
cc: Fix hit-testing of empty layers.
The RenderSurfaceLayerList is supposed to contain any layers which are visible or that are eligible for hit testing. This change ensures that empty layers (those with drawsContent=false) are left in the RSSL when they have touch or wheel handlers, so that we can find them in hit testing. BUG=289766 R=danakj@chromium.org Review URL: https://codereview.chromium.org/25712004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227164 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/layers/texture_layer_unittest.cc13
-rw-r--r--cc/layers/tiled_layer_impl_unittest.cc2
-rw-r--r--cc/test/fake_content_layer_impl.cc10
-rw-r--r--cc/test/fake_content_layer_impl.h9
-rw-r--r--cc/trees/layer_tree_host.cc2
-rw-r--r--cc/trees/layer_tree_host_common.cc15
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc115
-rw-r--r--cc/trees/layer_tree_host_impl.cc2
-rw-r--r--cc/trees/layer_tree_host_unittest.cc39
-rw-r--r--cc/trees/layer_tree_impl.h4
-rw-r--r--cc/trees/occlusion_tracker.cc3
-rw-r--r--cc/trees/occlusion_tracker_unittest.cc45
-rw-r--r--cc/trees/quad_culler_unittest.cc1
13 files changed, 250 insertions, 10 deletions
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 7eefd9b..bdb1358 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -1168,6 +1168,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
@@ -1177,6 +1178,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
@@ -1186,6 +1188,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
// Software resource.
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox3_,
SingleReleaseCallback::Create(test_data_.release_mailbox3_));
@@ -1195,6 +1198,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
+ impl_layer->SetDrawsContent(true);
ContextProvider* context_provider =
host_impl_.output_surface()->context_provider();
unsigned texture =
@@ -1206,6 +1210,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
+ impl_layer->SetDrawsContent(true);
impl_layer->set_texture_id(0);
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE));
}
@@ -1214,6 +1219,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
@@ -1223,6 +1229,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(TextureMailbox(),
scoped_ptr<SingleReleaseCallback>());
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
@@ -1232,6 +1239,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
// Software resource.
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox3_,
SingleReleaseCallback::Create(test_data_.release_mailbox3_));
@@ -1241,6 +1249,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
+ impl_layer->SetDrawsContent(true);
ContextProvider* context_provider =
host_impl_.output_surface()->context_provider();
unsigned texture =
@@ -1252,6 +1261,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
+ impl_layer->SetDrawsContent(true);
impl_layer->set_texture_id(0);
EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE));
}
@@ -1260,6 +1270,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, true);
+ impl_layer->SetDrawsContent(true);
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
@@ -1269,6 +1280,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) {
{
scoped_ptr<TextureLayerImpl> impl_layer =
TextureLayerImpl::Create(host_impl_.active_tree(), 1, false);
+ impl_layer->SetDrawsContent(true);
ContextProvider* context_provider =
host_impl_.output_surface()->context_provider();
unsigned texture =
@@ -1353,6 +1365,7 @@ TEST_F(TextureLayerImplWithMailboxTest,
impl_layer->SetTextureMailbox(
test_data_.mailbox1_,
SingleReleaseCallback::Create(test_data_.release_mailbox1_));
+ impl_layer->SetDrawsContent(true);
impl_layer->DidBecomeActive();
EXPECT_TRUE(impl_layer->WillDraw(
DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider()));
diff --git a/cc/layers/tiled_layer_impl_unittest.cc b/cc/layers/tiled_layer_impl_unittest.cc
index 42913ef..71e4358 100644
--- a/cc/layers/tiled_layer_impl_unittest.cc
+++ b/cc/layers/tiled_layer_impl_unittest.cc
@@ -52,6 +52,8 @@ class TiledLayerImplTest : public testing::Test {
scoped_ptr<TiledLayerImpl> layer =
CreateLayerNoTiles(tile_size, layer_size, border_texels);
+ layer->SetDrawsContent(true);
+
ResourceProvider::ResourceId resource_id = 1;
for (int i = 0; i < layer->TilingForTesting()->num_tiles_x(); ++i) {
for (int j = 0; j < layer->TilingForTesting()->num_tiles_y(); ++j) {
diff --git a/cc/test/fake_content_layer_impl.cc b/cc/test/fake_content_layer_impl.cc
index 5f72668..b5e3539 100644
--- a/cc/test/fake_content_layer_impl.cc
+++ b/cc/test/fake_content_layer_impl.cc
@@ -8,7 +8,8 @@ namespace cc {
FakeContentLayerImpl::FakeContentLayerImpl(LayerTreeImpl* tree_impl, int id)
: TiledLayerImpl(tree_impl, id),
- lost_output_surface_count_(0) {
+ lost_output_surface_count_(0),
+ append_quads_count_(0) {
}
FakeContentLayerImpl::~FakeContentLayerImpl() {}
@@ -27,4 +28,11 @@ void FakeContentLayerImpl::DidLoseOutputSurface() {
++lost_output_surface_count_;
}
+void FakeContentLayerImpl::AppendQuads(QuadSink* quad_sink,
+ AppendQuadsData* append_quads_data) {
+ TiledLayerImpl::AppendQuads(quad_sink, append_quads_data);
+ ++append_quads_count_;
+}
+
+
} // namespace cc
diff --git a/cc/test/fake_content_layer_impl.h b/cc/test/fake_content_layer_impl.h
index 74c4eda..8ab3fa4 100644
--- a/cc/test/fake_content_layer_impl.h
+++ b/cc/test/fake_content_layer_impl.h
@@ -30,10 +30,19 @@ class FakeContentLayerImpl : public TiledLayerImpl {
virtual void DidLoseOutputSurface() OVERRIDE;
+ size_t append_quads_count() const {
+ return append_quads_count_;
+ }
+ void reset_append_quads_count() { append_quads_count_ = 0; }
+
+ virtual void AppendQuads(QuadSink* quad_sink,
+ AppendQuadsData* append_quads_data) OVERRIDE;
+
private:
explicit FakeContentLayerImpl(LayerTreeImpl* tree_impl, int id);
size_t lost_output_surface_count_;
+ size_t append_quads_count_;
};
} // namespace cc
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 7bece08..0698751 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -1023,7 +1023,7 @@ void LayerTreeHost::PaintLayerContents(
if (it.represents_target_render_surface()) {
PaintMasksForRenderSurface(
*it, queue, did_paint_content, need_more_updates);
- } else if (it.represents_itself()) {
+ } else if (it.represents_itself() && it->DrawsContent()) {
devtools_instrumentation::ScopedLayerTreeTask
update_layer(devtools_instrumentation::kUpdateLayer, it->id(), id());
DCHECK(!it->paint_properties().bounds.IsEmpty());
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index e1f8696..d483cc6 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -418,10 +418,10 @@ static bool LayerShouldBeSkipped(LayerType* layer,
bool layer_is_visible) {
// Layers can be skipped if any of these conditions are met.
// - is not visible due to it or one of its ancestors being hidden.
- // - does not draw content.
- // - is transparent
// - has empty bounds
// - the layer is not double-sided, but its back face is visible.
+ // - is transparent
+ // - does not draw content and does not participate in hit testing.
//
// Some additional conditions need to be computed at a later point after the
// recursion is finished.
@@ -435,7 +435,7 @@ static bool LayerShouldBeSkipped(LayerType* layer,
if (!layer_is_visible)
return true;
- if (!layer->DrawsContent() || layer->bounds().IsEmpty())
+ if (layer->bounds().IsEmpty())
return true;
LayerType* backface_test_layer = layer;
@@ -452,6 +452,13 @@ static bool LayerShouldBeSkipped(LayerType* layer,
IsLayerBackFaceVisible(backface_test_layer))
return true;
+ // The layer is visible to events. If it's subject to hit testing, then
+ // we can't skip it.
+ bool can_accept_input = !layer->touch_event_handler_region().IsEmpty() ||
+ layer->have_wheel_event_handlers();
+ if (!layer->DrawsContent() && !can_accept_input)
+ return true;
+
return false;
}
@@ -475,6 +482,7 @@ static inline bool SubtreeShouldBeSkipped(LayerImpl* layer,
// The opacity of a layer always applies to its children (either implicitly
// via a render surface or explicitly if the parent preserves 3D), so the
// entire subtree can be skipped if this layer is fully transparent.
+ // TODO(sad): Don't skip layers used for hit testing crbug.com/295295.
return !layer->opacity();
}
@@ -495,6 +503,7 @@ static inline bool SubtreeShouldBeSkipped(Layer* layer,
// In particular, it should not cause the subtree to be skipped.
// Similarly, for layers that might animate opacity using an impl-only
// animation, their subtree should also not be skipped.
+ // TODO(sad): Don't skip layers used for hit testing crbug.com/295295.
return !layer->opacity() && !layer->OpacityIsAnimating() &&
!layer->OpacityCanAnimateOnImplThread();
}
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 04ffc32..40cc92a 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -5454,6 +5454,121 @@ TEST_F(LayerTreeHostCommonTest, HitTestingForMultipleLayerLists) {
EXPECT_EQ(4, result_layer->id());
}
+TEST_F(LayerTreeHostCommonTest, HitTestingForEmptyLayers) {
+ FakeImplProxy proxy;
+ FakeLayerTreeHostImpl host_impl(&proxy);
+
+ // Layer 1 - root
+ scoped_ptr<LayerImpl> root =
+ LayerImpl::Create(host_impl.active_tree(), 1);
+ gfx::Transform identity_matrix;
+ gfx::PointF anchor;
+ gfx::PointF position;
+ gfx::Size bounds(100, 100);
+ SetLayerPropertiesForTesting(root.get(),
+ identity_matrix,
+ identity_matrix,
+ anchor,
+ position,
+ bounds,
+ false);
+ root->SetDrawsContent(true);
+
+ {
+ // Layer 2 - empty: drawsContent=false
+ gfx::PointF position(10.f, 10.f);
+ gfx::Size bounds(30, 30);
+ scoped_ptr<LayerImpl> empty_layer =
+ LayerImpl::Create(host_impl.active_tree(), 2);
+ SetLayerPropertiesForTesting(empty_layer.get(),
+ identity_matrix,
+ identity_matrix,
+ anchor,
+ position,
+ bounds,
+ false);
+
+ empty_layer->SetDrawsContent(false);
+ root->AddChild(empty_layer.Pass());
+ }
+
+ {
+ // Layer 3 - empty, but has touch handler
+ gfx::PointF position(10.f, 60.f);
+ gfx::Size bounds(30, 30);
+ scoped_ptr<LayerImpl> test_layer =
+ LayerImpl::Create(host_impl.active_tree(), 3);
+ SetLayerPropertiesForTesting(test_layer.get(),
+ identity_matrix,
+ identity_matrix,
+ anchor,
+ position,
+ bounds,
+ false);
+
+ test_layer->SetDrawsContent(false);
+ Region touch_handler_region(gfx::Rect(10, 10, 10, 10));
+ test_layer->SetTouchEventHandlerRegion(touch_handler_region);
+ root->AddChild(test_layer.Pass());
+ }
+
+ {
+ // Layer 4 - empty, but has mousewheel handler
+ gfx::PointF position(60.f, 60.f);
+ gfx::Size bounds(30, 30);
+ scoped_ptr<LayerImpl> test_layer =
+ LayerImpl::Create(host_impl.active_tree(), 4);
+ SetLayerPropertiesForTesting(test_layer.get(),
+ identity_matrix,
+ identity_matrix,
+ anchor,
+ position,
+ bounds,
+ false);
+
+ test_layer->SetDrawsContent(false);
+ test_layer->SetHaveWheelEventHandlers(true);
+ root->AddChild(test_layer.Pass());
+ }
+
+ LayerImplList render_surface_layer_list;
+ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
+ root.get(), root->bounds(), &render_surface_layer_list);
+ inputs.can_adjust_raster_scales = true;
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+
+ // Verify that the root layer and empty layers with touch/wheel handlers
+ // (but not the empty layer without a touch handler) are in the RSSL.
+ ASSERT_EQ(1u, render_surface_layer_list.size());
+ EXPECT_EQ(1, render_surface_layer_list[0]->id());
+ ASSERT_EQ(3u, root->render_surface()->layer_list().size());
+ EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id());
+ EXPECT_EQ(3, root->render_surface()->layer_list().at(1)->id());
+ EXPECT_EQ(4, root->render_surface()->layer_list().at(2)->id());
+
+ // Hit testing for a point inside the empty no-handlers layer should return
+ // the root layer.
+ gfx::Point test_point = gfx::Point(15, 15);
+ LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
+ test_point, render_surface_layer_list);
+ ASSERT_TRUE(result_layer);
+ EXPECT_EQ(1, result_layer->id());
+
+ // Hit testing for a point inside the touch handler layer should return it.
+ test_point = gfx::Point(15, 75);
+ result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
+ test_point, render_surface_layer_list);
+ ASSERT_TRUE(result_layer);
+ EXPECT_EQ(3, result_layer->id());
+
+ // Hit testing for a point inside the mousewheel layer should return it.
+ test_point = gfx::Point(75, 75);
+ result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
+ test_point, render_surface_layer_list);
+ ASSERT_TRUE(result_layer);
+ EXPECT_EQ(4, result_layer->id());
+}
+
TEST_F(LayerTreeHostCommonTest,
HitCheckingTouchHandlerRegionsForEmptyLayerList) {
// Hit checking on an empty render_surface_layer_list should return a null
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 505e13e..a224224 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -761,7 +761,7 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
contributing_render_pass,
occlusion_tracker,
&append_quads_data);
- } else if (it.represents_itself() &&
+ } else if (it.represents_itself() && it->DrawsContent() &&
!it->visible_content_rect().IsEmpty()) {
bool impl_draw_transform_is_unknown = false;
bool occluded = occlusion_tracker.Occluded(
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index aef9f35..25bcaf3 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -29,6 +29,7 @@
#include "cc/scheduler/frame_rate_controller.h"
#include "cc/test/fake_content_layer.h"
#include "cc/test/fake_content_layer_client.h"
+#include "cc/test/fake_content_layer_impl.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_painted_scrollbar_layer.h"
@@ -4883,6 +4884,44 @@ class LayerTreeHostTestOffscreenContext_WithContext
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestOffscreenContext_WithContext);
+class LayerTreeHostTestNoQuadsForEmptyLayer : public LayerTreeHostTest {
+ protected:
+ virtual void SetupTree() OVERRIDE {
+ LayerTreeHostTest::SetupTree();
+ root_layer_ = FakeContentLayer::Create(&client_);
+ root_layer_->SetBounds(gfx::Size(10, 10));
+ root_layer_->SetIsDrawable(false);
+ root_layer_->SetHaveWheelEventHandlers(true);
+ layer_tree_host()->SetRootLayer(root_layer_);
+ LayerTreeHostTest::SetupTree();
+ }
+
+ virtual void BeginTest() OVERRIDE {
+ PostSetNeedsCommitToMainThread();
+ }
+
+ virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
+ FakeContentLayerImpl* layer_impl =
+ static_cast<FakeContentLayerImpl*>(impl->RootLayer());
+ EXPECT_FALSE(layer_impl->DrawsContent());
+ EXPECT_EQ(0u, layer_impl->append_quads_count());
+ }
+
+ virtual void DidCommit() OVERRIDE {
+ // The layer is not drawable, so it should not be updated.
+ EXPECT_EQ(0u, root_layer_->update_count());
+ EndTest();
+ }
+ virtual void AfterTest() OVERRIDE {}
+
+ private:
+ FakeContentLayerClient client_;
+ scoped_refptr<FakeContentLayer> root_layer_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoQuadsForEmptyLayer);
+
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index eb6a015..6714503 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -249,8 +249,8 @@ class CC_EXPORT LayerTreeImpl {
// Persisted state for non-impl-side-painting.
int scrolling_layer_id_from_previous_tree_;
- // List of visible layers for the most recently prepared frame. Used for
- // rendering and input event hit testing.
+ // List of visible or hit-testable layers for the most recently prepared
+ // frame. Used for rendering and input event hit testing.
LayerImplList render_surface_layer_list_;
bool contents_textures_purged_;
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc
index 6bfc595..23d5ba6 100644
--- a/cc/trees/occlusion_tracker.cc
+++ b/cc/trees/occlusion_tracker.cc
@@ -414,6 +414,9 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::
if (stack_.empty())
return;
+ if (!layer->DrawsContent())
+ return;
+
if (!LayerOpacityKnown(layer) || layer->draw_opacity() < 1)
return;
diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc
index 7b72380..0e8b5d4 100644
--- a/cc/trees/occlusion_tracker_unittest.cc
+++ b/cc/trees/occlusion_tracker_unittest.cc
@@ -30,9 +30,10 @@ namespace {
class TestContentLayer : public Layer {
public:
- TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {}
+ TestContentLayer() : Layer(), override_opaque_contents_rect_(false) {
+ SetIsDrawable(true);
+ }
- virtual bool DrawsContent() const OVERRIDE { return true; }
virtual Region VisibleContentOpaqueRegion() const OVERRIDE {
if (override_opaque_contents_rect_)
return gfx::IntersectRects(opaque_contents_rect_, visible_content_rect());
@@ -342,6 +343,14 @@ template <typename Types> class OcclusionTrackerTest : public testing::Test {
Types::TestLayerIterator::Begin(render_surface_layer_list_.get());
}
+ void SetDrawsContent(LayerImpl* layer_impl, bool draws_content) {
+ layer_impl->SetDrawsContent(draws_content);
+ }
+
+ void SetDrawsContent(Layer* layer, bool draws_content) {
+ layer->SetIsDrawable(draws_content);
+ }
+
void EnterLayer(typename Types::LayerType* layer,
typename Types::OcclusionTrackerType* occlusion,
bool prevent_occlusion) {
@@ -3965,5 +3974,37 @@ class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude
ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude)
+template <class Types>
+class OcclusionTrackerTestEmptyEventLayerDoesNotOcclude
+ : public OcclusionTrackerTest<Types> {
+ protected:
+ explicit OcclusionTrackerTestEmptyEventLayerDoesNotOcclude(
+ bool opaque_layers)
+ : OcclusionTrackerTest<Types>(opaque_layers) {}
+ void RunMyTest() {
+ typename Types::ContentLayerType* root = this->CreateRoot(
+ this->identity_matrix, gfx::Point(), gfx::Size(400, 400));
+ typename Types::ContentLayerType* empty_layer = this->CreateDrawingLayer(
+ root, this->identity_matrix, gfx::Point(), gfx::Size(200, 200), true);
+ this->SetDrawsContent(empty_layer, false);
+ empty_layer->SetTouchEventHandlerRegion(gfx::Rect(10, 10, 10, 10));
+
+ this->CalcDrawEtc(root);
+
+ TestOcclusionTrackerWithClip<typename Types::LayerType,
+ typename Types::RenderSurfaceType> occlusion(
+ gfx::Rect(0, 0, 1000, 1000), false);
+
+ this->VisitLayer(empty_layer, &occlusion);
+
+ EXPECT_EQ(gfx::Rect().ToString(),
+ occlusion.occlusion_from_outside_target().ToString());
+ EXPECT_EQ(gfx::Rect().ToString(),
+ occlusion.occlusion_from_inside_target().ToString());
+ }
+};
+
+ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestEmptyEventLayerDoesNotOcclude)
+
} // namespace
} // namespace cc
diff --git a/cc/trees/quad_culler_unittest.cc b/cc/trees/quad_culler_unittest.cc
index 9a55878..c503de8 100644
--- a/cc/trees/quad_culler_unittest.cc
+++ b/cc/trees/quad_culler_unittest.cc
@@ -60,6 +60,7 @@ class QuadCullerTest : public testing::Test {
tiler->SetBounds(layer_rect.size());
layer->SetTilingData(*tiler);
layer->set_skips_draw(false);
+ layer->SetDrawsContent(true);
layer->draw_properties().target_space_transform = draw_transform;
layer->draw_properties().screen_space_transform = draw_transform;
layer->draw_properties().visible_content_rect = layer_rect;