summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmpstr <vmpstr@chromium.org>2014-10-06 23:34:33 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-07 06:34:46 +0000
commit61c35e8db648a01dc75b7ab04af454e0fec9dfba (patch)
tree8a3f3110449920a67aaedb9ad9967f22d9bccee8
parent541ad2c748eda43323ef93cae62ed3974f3a330c (diff)
downloadchromium_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.gn1
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/layers/picture_layer_impl.cc28
-rw-r--r--cc/trees/occlusion.cc19
-rw-r--r--cc/trees/occlusion.h3
-rw-r--r--cc/trees/occlusion_unittest.cc272
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