diff options
author | vmpstr <vmpstr@chromium.org> | 2014-10-06 23:34:33 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-07 06:34:46 +0000 |
commit | 61c35e8db648a01dc75b7ab04af454e0fec9dfba (patch) | |
tree | 8a3f3110449920a67aaedb9ad9967f22d9bccee8 | |
parent | 541ad2c748eda43323ef93cae62ed3974f3a330c (diff) | |
download | chromium_src-61c35e8db648a01dc75b7ab04af454e0fec9dfba.zip chromium_src-61c35e8db648a01dc75b7ab04af454e0fec9dfba.tar.gz chromium_src-61c35e8db648a01dc75b7ab04af454e0fec9dfba.tar.bz2 |
cc: Unify the occlusion access by adding an ability to scale transform.
This change adds GetOcclusionWithGivenDrawTransform to Occlusion. This
allows us to get occlusion tracker out of the layer by always passing
an occlusion with a draw transform. Then, each layer can still get
a more convenient version of the occlusion by providing a different
draw transform.
R=danakj
Review URL: https://codereview.chromium.org/607023003
Cr-Commit-Position: refs/heads/master@{#298403}
-rw-r--r-- | cc/BUILD.gn | 1 | ||||
-rw-r--r-- | cc/cc_tests.gyp | 1 | ||||
-rw-r--r-- | cc/layers/picture_layer_impl.cc | 28 | ||||
-rw-r--r-- | cc/trees/occlusion.cc | 19 | ||||
-rw-r--r-- | cc/trees/occlusion.h | 3 | ||||
-rw-r--r-- | cc/trees/occlusion_unittest.cc | 272 |
6 files changed, 304 insertions, 20 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 0515a6f..c43eb3a 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn @@ -766,6 +766,7 @@ test("cc_unittests") { "trees/layer_tree_host_unittest_video.cc", "trees/layer_tree_impl_unittest.cc", "trees/occlusion_tracker_unittest.cc", + "trees/occlusion_unittest.cc", "trees/tree_synchronizer_unittest.cc", # Surfaces test files. diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index 18fcf7a..21299c0 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -122,6 +122,7 @@ 'trees/layer_tree_host_unittest_video.cc', 'trees/layer_tree_impl_unittest.cc', 'trees/occlusion_tracker_unittest.cc', + 'trees/occlusion_unittest.cc', 'trees/tree_synchronizer_unittest.cc', ], 'cc_surfaces_unit_tests_source_files': [ diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 8a78bb1..09c541e 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -165,30 +165,30 @@ void PictureLayerImpl::AppendQuads( AppendDebugBorderQuad( render_pass, content_bounds(), shared_quad_state, append_quads_data); - SolidColorLayerImpl::AppendSolidQuads( - render_pass, - occlusion_tracker, - shared_quad_state, - content_bounds(), - draw_properties().target_space_transform, - pile_->solid_color(), - append_quads_data); + SolidColorLayerImpl::AppendSolidQuads(render_pass, + occlusion_tracker, + shared_quad_state, + content_bounds(), + draw_transform(), + pile_->solid_color(), + append_quads_data); return; } + Occlusion occlusion = + occlusion_tracker.GetCurrentOcclusionForLayer(draw_transform()); + float max_contents_scale = MaximumTilingContentsScale(); gfx::Transform scaled_draw_transform = draw_transform(); scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale, SK_MScalar1 / max_contents_scale); gfx::Size scaled_content_bounds = gfx::ToCeiledSize(gfx::ScaleSize(content_bounds(), max_contents_scale)); - gfx::Rect scaled_visible_content_rect = gfx::ScaleToEnclosingRect(visible_content_rect(), max_contents_scale); scaled_visible_content_rect.Intersect(gfx::Rect(scaled_content_bounds)); - - Occlusion occlusion = - occlusion_tracker.GetCurrentOcclusionForLayer(scaled_draw_transform); + Occlusion scaled_occlusion = + occlusion.GetOcclusionWithGivenDrawTransform(scaled_draw_transform); shared_quad_state->SetAll(scaled_draw_transform, scaled_content_bounds, @@ -211,7 +211,7 @@ void PictureLayerImpl::AppendQuads( gfx::Rect geometry_rect = scaled_visible_content_rect; gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect(); gfx::Rect visible_geometry_rect = - occlusion.GetUnoccludedContentRect(geometry_rect); + scaled_occlusion.GetUnoccludedContentRect(geometry_rect); if (visible_geometry_rect.IsEmpty()) return; @@ -306,7 +306,7 @@ void PictureLayerImpl::AppendQuads( gfx::Rect geometry_rect = iter.geometry_rect(); gfx::Rect opaque_rect = contents_opaque() ? geometry_rect : gfx::Rect(); gfx::Rect visible_geometry_rect = - occlusion.GetUnoccludedContentRect(geometry_rect); + scaled_occlusion.GetUnoccludedContentRect(geometry_rect); if (visible_geometry_rect.IsEmpty()) continue; diff --git a/cc/trees/occlusion.cc b/cc/trees/occlusion.cc index d9da938..70ee32c 100644 --- a/cc/trees/occlusion.cc +++ b/cc/trees/occlusion.cc @@ -20,14 +20,23 @@ Occlusion::Occlusion(const gfx::Transform& draw_transform, occlusion_from_inside_target_(occlusion_from_inside_target) { } +Occlusion Occlusion::GetOcclusionWithGivenDrawTransform( + const gfx::Transform& transform) const { + return Occlusion( + transform, occlusion_from_outside_target_, occlusion_from_inside_target_); +} + +bool Occlusion::HasOcclusion() const { + return !occlusion_from_inside_target_.IsEmpty() || + !occlusion_from_outside_target_.IsEmpty(); +} + bool Occlusion::IsOccluded(const gfx::Rect& content_rect) const { if (content_rect.IsEmpty()) return true; - if (occlusion_from_inside_target_.IsEmpty() && - occlusion_from_outside_target_.IsEmpty()) { + if (!HasOcclusion()) return false; - } gfx::Rect unoccluded_rect_in_target_surface = GetUnoccludedRectInTargetSurface(content_rect); @@ -39,10 +48,8 @@ gfx::Rect Occlusion::GetUnoccludedContentRect( if (content_rect.IsEmpty()) return content_rect; - if (occlusion_from_inside_target_.IsEmpty() && - occlusion_from_outside_target_.IsEmpty()) { + if (!HasOcclusion()) return content_rect; - } gfx::Rect unoccluded_rect_in_target_surface = GetUnoccludedRectInTargetSurface(content_rect); diff --git a/cc/trees/occlusion.h b/cc/trees/occlusion.h index 60493cc..6d1e5b1 100644 --- a/cc/trees/occlusion.h +++ b/cc/trees/occlusion.h @@ -19,7 +19,10 @@ class CC_EXPORT Occlusion { Occlusion(const gfx::Transform& draw_transform, const SimpleEnclosedRegion& occlusion_from_outside_target, const SimpleEnclosedRegion& occlusion_from_inside_target); + Occlusion GetOcclusionWithGivenDrawTransform( + const gfx::Transform& transform) const; + bool HasOcclusion() const; bool IsOccluded(const gfx::Rect& content_rect) const; gfx::Rect GetUnoccludedContentRect(const gfx::Rect& content_rect) const; diff --git a/cc/trees/occlusion_unittest.cc b/cc/trees/occlusion_unittest.cc new file mode 100644 index 0000000..becc7a3 --- /dev/null +++ b/cc/trees/occlusion_unittest.cc @@ -0,0 +1,272 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/trees/occlusion.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +TEST(OcclusionTest, HasOcclusion) { + Occlusion empty; + EXPECT_FALSE(empty.HasOcclusion()); + + empty = Occlusion( + gfx::Transform(), SimpleEnclosedRegion(), SimpleEnclosedRegion()); + EXPECT_FALSE(empty.HasOcclusion()); + + Occlusion outside_nonempty( + gfx::Transform(), SimpleEnclosedRegion(10, 10), SimpleEnclosedRegion()); + EXPECT_TRUE(outside_nonempty.HasOcclusion()); + + Occlusion inside_nonempty( + gfx::Transform(), SimpleEnclosedRegion(), SimpleEnclosedRegion(10, 10)); + EXPECT_TRUE(inside_nonempty.HasOcclusion()); + + Occlusion both_nonempty(gfx::Transform(), + SimpleEnclosedRegion(10, 10), + SimpleEnclosedRegion(10, 10)); + EXPECT_TRUE(both_nonempty.HasOcclusion()); +} + +#define EXPECT_OCCLUSION(occlusion, rects, ...) \ + { \ + bool expected[] = {__VA_ARGS__}; \ + ASSERT_EQ(arraysize(rects), arraysize(expected)); \ + for (size_t i = 0; i < arraysize(rects); ++i) \ + EXPECT_EQ(expected[i], occlusion.IsOccluded(rects[i])) \ + << "Test failed for index " << i << "."; \ + } + +TEST(OcclusionTest, IsOccludedNoTransform) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + Occlusion no_occlusion; + EXPECT_OCCLUSION(no_occlusion, rects, false, false, false, false); + + Occlusion all_occluded_outside( + gfx::Transform(), SimpleEnclosedRegion(20, 20), SimpleEnclosedRegion()); + EXPECT_OCCLUSION(all_occluded_outside, rects, true, true, true, true); + + Occlusion all_occluded_inside( + gfx::Transform(), SimpleEnclosedRegion(), SimpleEnclosedRegion(20, 20)); + EXPECT_OCCLUSION(all_occluded_inside, rects, true, true, true, true); + + Occlusion all_occluded_mixed(gfx::Transform(), + SimpleEnclosedRegion(10, 20), + SimpleEnclosedRegion(10, 0, 10, 20)); + EXPECT_OCCLUSION(all_occluded_mixed, rects, true, true, true, true); + + Occlusion some_occluded(gfx::Transform(), + SimpleEnclosedRegion(10, 10), + SimpleEnclosedRegion(10, 10, 10, 10)); + EXPECT_OCCLUSION(some_occluded, rects, true, false, false, true); +} + +TEST(OcclusionTest, IsOccludedScaled) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + gfx::Transform half_scale; + half_scale.Scale(0.5, 0.5); + + gfx::Transform double_scale; + double_scale.Scale(2, 2); + + Occlusion all_occluded_outside_half( + half_scale, SimpleEnclosedRegion(10, 10), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_double( + double_scale, SimpleEnclosedRegion(40, 40), SimpleEnclosedRegion()); + EXPECT_OCCLUSION(all_occluded_outside_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_outside_double, rects, true, true, true, true); + + Occlusion all_occluded_inside_half( + half_scale, SimpleEnclosedRegion(), SimpleEnclosedRegion(10, 10)); + Occlusion all_occluded_inside_double( + double_scale, SimpleEnclosedRegion(), SimpleEnclosedRegion(40, 40)); + EXPECT_OCCLUSION(all_occluded_inside_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_inside_double, rects, true, true, true, true); + + Occlusion all_occluded_mixed_half(half_scale, + SimpleEnclosedRegion(5, 10), + SimpleEnclosedRegion(5, 0, 5, 10)); + Occlusion all_occluded_mixed_double(double_scale, + SimpleEnclosedRegion(20, 40), + SimpleEnclosedRegion(20, 0, 20, 40)); + EXPECT_OCCLUSION(all_occluded_mixed_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_mixed_double, rects, true, true, true, true); + + Occlusion some_occluded_half( + half_scale, SimpleEnclosedRegion(5, 5), SimpleEnclosedRegion(5, 5, 5, 5)); + Occlusion some_occluded_double(double_scale, + SimpleEnclosedRegion(20, 20), + SimpleEnclosedRegion(20, 20, 20, 20)); + EXPECT_OCCLUSION(some_occluded_half, rects, true, false, false, true); + EXPECT_OCCLUSION(some_occluded_double, rects, true, false, false, true); +} + +TEST(OcclusionTest, IsOccludedTranslated) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + gfx::Transform move_left; + move_left.Translate(-100, 0); + + gfx::Transform move_down; + move_down.Translate(0, 100); + + Occlusion all_occluded_outside_left( + move_left, SimpleEnclosedRegion(-100, 0, 20, 20), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_down( + move_down, SimpleEnclosedRegion(0, 100, 20, 20), SimpleEnclosedRegion()); + EXPECT_OCCLUSION(all_occluded_outside_left, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_outside_down, rects, true, true, true, true); + + Occlusion all_occluded_inside_left( + move_left, SimpleEnclosedRegion(), SimpleEnclosedRegion(-100, 0, 20, 20)); + Occlusion all_occluded_inside_down( + move_down, SimpleEnclosedRegion(), SimpleEnclosedRegion(0, 100, 20, 20)); + EXPECT_OCCLUSION(all_occluded_inside_left, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_inside_down, rects, true, true, true, true); + + Occlusion all_occluded_mixed_left(move_left, + SimpleEnclosedRegion(-100, 0, 10, 20), + SimpleEnclosedRegion(-90, 0, 10, 20)); + Occlusion all_occluded_mixed_down(move_down, + SimpleEnclosedRegion(0, 100, 10, 20), + SimpleEnclosedRegion(10, 100, 10, 20)); + EXPECT_OCCLUSION(all_occluded_mixed_left, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_mixed_down, rects, true, true, true, true); + + Occlusion some_occluded_left(move_left, + SimpleEnclosedRegion(-100, 0, 10, 10), + SimpleEnclosedRegion(-90, 10, 10, 10)); + Occlusion some_occluded_down(move_down, + SimpleEnclosedRegion(0, 100, 10, 10), + SimpleEnclosedRegion(10, 110, 10, 10)); + EXPECT_OCCLUSION(some_occluded_left, rects, true, false, false, true); + EXPECT_OCCLUSION(some_occluded_down, rects, true, false, false, true); +} + +TEST(OcclusionTest, IsOccludedScaledAfterConstruction) { + gfx::Rect rects[] = {gfx::Rect(10, 10), + gfx::Rect(10, 0, 10, 10), + gfx::Rect(0, 10, 10, 10), + gfx::Rect(10, 10, 10, 10)}; + + gfx::Transform half_transform; + half_transform.Scale(0.5, 0.5); + + gfx::Transform double_transform; + double_transform.Scale(2, 2); + + Occlusion all_occluded_outside( + gfx::Transform(), SimpleEnclosedRegion(10, 10), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_half = + all_occluded_outside.GetOcclusionWithGivenDrawTransform(half_transform); + + all_occluded_outside = Occlusion( + gfx::Transform(), SimpleEnclosedRegion(40, 40), SimpleEnclosedRegion()); + Occlusion all_occluded_outside_double = + all_occluded_outside.GetOcclusionWithGivenDrawTransform(double_transform); + + EXPECT_OCCLUSION(all_occluded_outside_half, rects, true, true, true, true); + EXPECT_OCCLUSION(all_occluded_outside_double, rects, true, true, true, true); + + Occlusion some_occluded(gfx::Transform(), + SimpleEnclosedRegion(5, 5), + SimpleEnclosedRegion(5, 5, 5, 5)); + Occlusion some_occluded_half = + some_occluded.GetOcclusionWithGivenDrawTransform(half_transform); + + some_occluded = Occlusion(gfx::Transform(), + SimpleEnclosedRegion(20, 20), + SimpleEnclosedRegion(20, 20, 20, 20)); + Occlusion some_occluded_double = + some_occluded.GetOcclusionWithGivenDrawTransform(double_transform); + + EXPECT_OCCLUSION(some_occluded_half, rects, true, false, false, true); + EXPECT_OCCLUSION(some_occluded_double, rects, true, false, false, true); +} + +TEST(OcclusionTest, GetUnoccludedContentRectNoTransform) { + Occlusion some_occluded(gfx::Transform(), + SimpleEnclosedRegion(10, 10), + SimpleEnclosedRegion(10, 10, 10, 10)); + + gfx::Rect full_query_result = + some_occluded.GetUnoccludedContentRect(gfx::Rect(20, 20)); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result); + + gfx::Rect half_query_result = + some_occluded.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result); +} + +TEST(OcclusionTest, GetUnoccludedContentRectScaled) { + gfx::Transform half_scale; + half_scale.Scale(0.5, 0.5); + + gfx::Transform double_scale; + double_scale.Scale(2, 2); + + Occlusion some_occluded_half( + half_scale, SimpleEnclosedRegion(5, 5), SimpleEnclosedRegion(5, 5, 5, 5)); + Occlusion some_occluded_double(double_scale, + SimpleEnclosedRegion(20, 20), + SimpleEnclosedRegion(20, 20, 20, 20)); + gfx::Rect full_query_result_half = + some_occluded_half.GetUnoccludedContentRect(gfx::Rect(20, 20)); + gfx::Rect full_query_result_double = + some_occluded_double.GetUnoccludedContentRect(gfx::Rect(20, 20)); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_half); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_double); + + gfx::Rect half_query_result_half = + some_occluded_half.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + gfx::Rect half_query_result_double = + some_occluded_half.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_half); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_double); +} + +TEST(OcclusionTest, GetUnoccludedContentRectTranslated) { + gfx::Transform move_left; + move_left.Translate(-100, 0); + + gfx::Transform move_down; + move_down.Translate(0, 100); + + Occlusion some_occluded_left(move_left, + SimpleEnclosedRegion(-100, 0, 10, 10), + SimpleEnclosedRegion(-90, 10, 10, 10)); + Occlusion some_occluded_down(move_down, + SimpleEnclosedRegion(0, 100, 0, 10), + SimpleEnclosedRegion(10, 110, 10, 10)); + + gfx::Rect full_query_result_left = + some_occluded_left.GetUnoccludedContentRect(gfx::Rect(20, 20)); + gfx::Rect full_query_result_down = + some_occluded_down.GetUnoccludedContentRect(gfx::Rect(20, 20)); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_left); + EXPECT_EQ(gfx::Rect(20, 20), full_query_result_down); + + gfx::Rect half_query_result_left = + some_occluded_left.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + gfx::Rect half_query_result_down = + some_occluded_down.GetUnoccludedContentRect(gfx::Rect(10, 0, 10, 20)); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_left); + EXPECT_EQ(gfx::Rect(10, 0, 10, 10), half_query_result_down); +} + +} // namespace +} // namespace cc |