summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/BUILD.gn2
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/layers/layer_impl.h4
-rw-r--r--cc/layers/picture_image_layer_impl_unittest.cc2
-rw-r--r--cc/layers/picture_layer_impl.cc18
-rw-r--r--cc/layers/picture_layer_impl.h5
-rw-r--r--cc/layers/picture_layer_impl_unittest.cc20
-rw-r--r--cc/resources/picture_layer_tiling.cc19
-rw-r--r--cc/resources/picture_layer_tiling.h16
-rw-r--r--cc/resources/picture_layer_tiling_perftest.cc26
-rw-r--r--cc/resources/picture_layer_tiling_unittest.cc187
-rw-r--r--cc/resources/tile_manager_perftest.cc10
-rw-r--r--cc/resources/tile_manager_unittest.cc96
-rw-r--r--cc/trees/layer_tree_impl.cc11
-rw-r--r--cc/trees/occlusion.cc48
-rw-r--r--cc/trees/occlusion.h36
-rw-r--r--cc/trees/occlusion_tracker.cc10
-rw-r--r--cc/trees/occlusion_tracker.h6
-rw-r--r--cc/trees/occlusion_tracker_unittest.cc5
19 files changed, 227 insertions, 296 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 300150f..6d70f46 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -452,6 +452,8 @@ component("cc") {
"trees/layer_tree_impl.h",
"trees/layer_tree_settings.cc",
"trees/layer_tree_settings.h",
+ "trees/occlusion.cc",
+ "trees/occlusion.h",
"trees/occlusion_tracker.cc",
"trees/occlusion_tracker.h",
"trees/proxy.cc",
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 9d62397..af640a2 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -481,6 +481,8 @@
'trees/layer_tree_impl.h',
'trees/layer_tree_settings.cc',
'trees/layer_tree_settings.h',
+ 'trees/occlusion.cc',
+ 'trees/occlusion.h',
'trees/occlusion_tracker.cc',
'trees/occlusion_tracker.h',
'trees/proxy.cc',
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index c10710c..65143ab 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -49,6 +49,7 @@ namespace cc {
class LayerTreeHostImpl;
class LayerTreeImpl;
class MicroBenchmarkImpl;
+class Occlusion;
template <typename LayerType>
class OcclusionTracker;
class RenderPass;
@@ -204,8 +205,7 @@ class CC_EXPORT LayerImpl : public LayerAnimationValueObserver,
virtual RenderPassId FirstContributingRenderPassId() const;
virtual RenderPassId NextContributingRenderPassId(RenderPassId id) const;
- virtual void UpdateTiles(
- const OcclusionTracker<LayerImpl>* occlusion_tracker) {}
+ virtual void UpdateTiles(const Occlusion& occlusion_in_layer_space) {}
virtual void NotifyTileStateChanged(const Tile* tile) {}
virtual ScrollbarLayerImplBase* ToScrollbarLayer();
diff --git a/cc/layers/picture_image_layer_impl_unittest.cc b/cc/layers/picture_image_layer_impl_unittest.cc
index 48b4d7b..f22b6cd 100644
--- a/cc/layers/picture_image_layer_impl_unittest.cc
+++ b/cc/layers/picture_image_layer_impl_unittest.cc
@@ -84,7 +84,7 @@ class PictureImageLayerImplTest : public testing::Test {
maximum_animation_contents_scale;
layer->draw_properties().screen_space_transform_is_animating =
animating_transform_to_screen;
- layer->UpdateTiles(NULL);
+ layer->UpdateTiles(Occlusion());
}
protected:
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 05dab30..1205e07 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -420,17 +420,11 @@ void PictureLayerImpl::AppendQuads(
}
void PictureLayerImpl::UpdateTiles(
- const OcclusionTracker<LayerImpl>* occlusion_tracker) {
+ const Occlusion& occlusion_in_content_space) {
TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTiles");
DoPostCommitInitializationIfNeeded();
- // TODO(danakj): We should always get an occlusion tracker when we are using
- // occlusion, so update this check when we don't use a pending tree in the
- // browser compositor.
- DCHECK(!occlusion_tracker ||
- layer_tree_impl()->settings().use_occlusion_for_tile_prioritization);
-
visible_rect_for_tile_priority_ = visible_content_rect();
viewport_rect_for_tile_priority_ =
layer_tree_impl()->ViewportRectForTilePriority();
@@ -465,14 +459,14 @@ void PictureLayerImpl::UpdateTiles(
should_update_tile_priorities_ = true;
- UpdateTilePriorities(occlusion_tracker);
+ UpdateTilePriorities(occlusion_in_content_space);
if (layer_tree_impl()->IsPendingTree())
MarkVisibleResourcesAsRequired();
}
void PictureLayerImpl::UpdateTilePriorities(
- const OcclusionTracker<LayerImpl>* occlusion_tracker) {
+ const Occlusion& occlusion_in_content_space) {
TRACE_EVENT0("cc", "PictureLayerImpl::UpdateTilePriorities");
double current_frame_time_in_seconds =
@@ -502,9 +496,7 @@ void PictureLayerImpl::UpdateTilePriorities(
visible_layer_rect,
ideal_contents_scale_,
current_frame_time_in_seconds,
- occlusion_tracker,
- render_target(),
- draw_transform());
+ occlusion_in_content_space);
}
// Tile priorities were modified.
@@ -756,7 +748,7 @@ void PictureLayerImpl::SyncTiling(
// when we stop using the pending tree in the browser compositor. If we want
// to support occlusion tracking here, we need to dirty the draw properties
// or save occlusion as a draw property.
- UpdateTilePriorities(NULL);
+ UpdateTilePriorities(Occlusion());
}
}
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index fd4fe0a..c7d987f 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -110,7 +110,7 @@ class CC_EXPORT PictureLayerImpl
const OcclusionTracker<LayerImpl>& occlusion_tracker,
AppendQuadsData* append_quads_data) OVERRIDE;
virtual void UpdateTiles(
- const OcclusionTracker<LayerImpl>* occlusion_tracker) OVERRIDE;
+ const Occlusion& occlusion_in_content_space) OVERRIDE;
virtual void NotifyTileStateChanged(const Tile* tile) OVERRIDE;
virtual void DidBecomeActive() OVERRIDE;
virtual void DidBeginTracing() OVERRIDE;
@@ -160,8 +160,7 @@ class CC_EXPORT PictureLayerImpl
void RemoveAllTilings();
void SyncFromActiveLayer(const PictureLayerImpl* other);
void AddTilingsForRasterScale();
- void UpdateTilePriorities(
- const OcclusionTracker<LayerImpl>* occlusion_tracker);
+ void UpdateTilePriorities(const Occlusion& occlusion_in_content_space);
virtual bool ShouldAdjustRasterScale() const;
virtual void RecalculateRasterScales();
void CleanUpTilingsOnActiveLayer(
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 44662d7..6742207 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -160,7 +160,7 @@ class PictureLayerImplTest : public testing::Test {
maximum_animation_contents_scale;
layer->draw_properties().screen_space_transform_is_animating =
animating_transform_to_screen;
- layer->UpdateTiles(NULL);
+ layer->UpdateTiles(Occlusion());
}
static void VerifyAllTilesExistAndHavePile(
const PictureLayerTiling* tiling,
@@ -348,7 +348,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
resourceless_software_draw);
active_layer_->draw_properties().visible_content_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
- active_layer_->UpdateTiles(NULL);
+ active_layer_->UpdateTiles(Occlusion());
gfx::Rect viewport_rect_for_tile_priority_in_view_space =
viewport_rect_for_tile_priority;
@@ -386,7 +386,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
resourceless_software_draw);
active_layer_->draw_properties().visible_content_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
- active_layer_->UpdateTiles(NULL);
+ active_layer_->UpdateTiles(Occlusion());
gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization);
bool success = transform_for_tile_priority.GetInverse(&screen_to_view);
@@ -447,7 +447,7 @@ TEST_F(PictureLayerImplTest,
resourceless_software_draw);
active_layer_->draw_properties().visible_content_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
- active_layer_->UpdateTiles(NULL);
+ active_layer_->UpdateTiles(Occlusion());
gfx::Rect visible_rect_for_tile_priority =
active_layer_->visible_rect_for_tile_priority();
@@ -475,7 +475,7 @@ TEST_F(PictureLayerImplTest,
viewport,
transform,
resourceless_software_draw);
- active_layer_->UpdateTiles(NULL);
+ active_layer_->UpdateTiles(Occlusion());
visible_rect_for_tile_priority =
gfx::ScaleToEnclosingRect(visible_rect_for_tile_priority, 2);
@@ -1508,7 +1508,7 @@ TEST_F(PictureLayerImplTest, TileOutsideOfViewportForTilePriorityNotRequired) {
time_ticks += base::TimeDelta::FromMilliseconds(200);
host_impl_.SetCurrentBeginFrameArgs(
CreateBeginFrameArgsForTesting(time_ticks));
- pending_layer_->UpdateTiles(NULL);
+ pending_layer_->UpdateTiles(Occlusion());
pending_layer_->MarkVisibleResourcesAsRequired();
@@ -2575,7 +2575,7 @@ TEST_F(PictureLayerImplTest, LayerRasterTileIterator) {
pending_layer_->draw_properties().visible_content_rect =
gfx::Rect(1100, 1100, 500, 500);
- pending_layer_->UpdateTiles(NULL);
+ pending_layer_->UpdateTiles(Occlusion());
unique_tiles.clear();
high_res_tile_count = 0u;
@@ -2605,7 +2605,7 @@ TEST_F(PictureLayerImplTest, LayerRasterTileIterator) {
pending_layer_->draw_properties().visible_content_rect =
gfx::Rect(0, 0, 500, 500);
- pending_layer_->UpdateTiles(NULL);
+ pending_layer_->UpdateTiles(Occlusion());
std::vector<Tile*> high_res_tiles = high_res_tiling->AllTilesForTesting();
for (std::vector<Tile*>::iterator tile_it = high_res_tiles.begin();
@@ -3169,7 +3169,7 @@ TEST_F(NoLowResPictureLayerImplTest,
resourceless_software_draw);
active_layer_->draw_properties().visible_content_rect = viewport;
active_layer_->draw_properties().screen_space_transform = transform;
- active_layer_->UpdateTiles(NULL);
+ active_layer_->UpdateTiles(Occlusion());
gfx::Rect visible_rect_for_tile_priority =
active_layer_->visible_rect_for_tile_priority();
@@ -3197,7 +3197,7 @@ TEST_F(NoLowResPictureLayerImplTest,
viewport,
transform,
resourceless_software_draw);
- active_layer_->UpdateTiles(NULL);
+ active_layer_->UpdateTiles(Occlusion());
visible_rect_for_tile_priority =
gfx::ScaleToEnclosingRect(visible_rect_for_tile_priority, 2);
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index 0d50658..0229879 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -15,7 +15,6 @@
#include "cc/base/math_util.h"
#include "cc/resources/tile.h"
#include "cc/resources/tile_priority.h"
-#include "cc/trees/occlusion_tracker.h"
#include "ui/gfx/point_conversions.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/safe_integer_conversions.h"
@@ -540,9 +539,7 @@ void PictureLayerTiling::UpdateTilePriorities(
const gfx::Rect& visible_layer_rect,
float ideal_contents_scale,
double current_frame_time_in_seconds,
- const OcclusionTracker<LayerImpl>* occlusion_tracker,
- const LayerImpl* render_target,
- const gfx::Transform& draw_transform) {
+ const Occlusion& occlusion_in_layer_space) {
if (!NeedsUpdateForFrameAtTime(current_frame_time_in_seconds)) {
// This should never be zero for the purposes of has_ever_been_updated().
DCHECK_NE(current_frame_time_in_seconds, 0.0);
@@ -605,16 +602,10 @@ void PictureLayerTiling::UpdateTilePriorities(
tile->SetPriority(tree, now_priority);
// Set whether tile is occluded or not.
- bool is_occluded = false;
- if (occlusion_tracker) {
- gfx::Rect tile_query_rect = ScaleToEnclosingRect(
- IntersectRects(tile->content_rect(), visible_rect_in_content_space),
- 1.0f / contents_scale_);
- // TODO(vmpstr): Remove render_target and draw_transform from the
- // parameters so they can be hidden from the tiling.
- is_occluded = occlusion_tracker->Occluded(
- render_target, tile_query_rect, draw_transform);
- }
+ gfx::Rect tile_query_rect = ScaleToEnclosingRect(
+ IntersectRects(tile->content_rect(), visible_rect_in_content_space),
+ 1.0f / contents_scale_);
+ bool is_occluded = occlusion_in_layer_space.IsOccluded(tile_query_rect);
tile->set_is_occluded(tree, is_occluded);
}
diff --git a/cc/resources/picture_layer_tiling.h b/cc/resources/picture_layer_tiling.h
index 35bbf94..e3fffee 100644
--- a/cc/resources/picture_layer_tiling.h
+++ b/cc/resources/picture_layer_tiling.h
@@ -17,6 +17,7 @@
#include "cc/base/tiling_data.h"
#include "cc/resources/tile.h"
#include "cc/resources/tile_priority.h"
+#include "cc/trees/occlusion.h"
#include "ui/gfx/rect.h"
namespace base {
@@ -27,8 +28,6 @@ class TracedValue;
namespace cc {
-template <typename LayerType>
-class OcclusionTracker;
class PictureLayerTiling;
class PicturePileImpl;
@@ -237,14 +236,11 @@ class CC_EXPORT PictureLayerTiling {
void Reset();
- void UpdateTilePriorities(
- WhichTree tree,
- const gfx::Rect& visible_layer_rect,
- float ideal_contents_scale,
- double current_frame_time_in_seconds,
- const OcclusionTracker<LayerImpl>* occlusion_tracker,
- const LayerImpl* render_target,
- const gfx::Transform& draw_transform);
+ void UpdateTilePriorities(WhichTree tree,
+ const gfx::Rect& visible_layer_rect,
+ float ideal_contents_scale,
+ double current_frame_time_in_seconds,
+ const Occlusion& occlusion_in_layer_space);
// Copies the src_tree priority into the dst_tree priority for all tiles.
// The src_tree priority is reset to the lowest priority possible. This
diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc
index 00338ab..f1b462f 100644
--- a/cc/resources/picture_layer_tiling_perftest.cc
+++ b/cc/resources/picture_layer_tiling_perftest.cc
@@ -74,13 +74,8 @@ class PictureLayerTilingPerfTest : public testing::Test {
timer_.Reset();
do {
- picture_layer_tiling_->UpdateTilePriorities(PENDING_TREE,
- viewport_rect,
- 1.f,
- timer_.NumLaps() + 1,
- NULL,
- NULL,
- gfx::Transform());
+ picture_layer_tiling_->UpdateTilePriorities(
+ PENDING_TREE, viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion());
timer_.NextLap();
} while (!timer_.HasTimeLimitExpired());
@@ -104,13 +99,8 @@ class PictureLayerTilingPerfTest : public testing::Test {
timer_.Reset();
do {
- picture_layer_tiling_->UpdateTilePriorities(PENDING_TREE,
- viewport_rect,
- 1.f,
- timer_.NumLaps() + 1,
- NULL,
- NULL,
- gfx::Transform());
+ picture_layer_tiling_->UpdateTilePriorities(
+ PENDING_TREE, viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion());
viewport_rect = gfx::Rect(viewport_rect.x() + xoffsets[offsetIndex],
viewport_rect.y() + yoffsets[offsetIndex],
@@ -139,7 +129,7 @@ class PictureLayerTilingPerfTest : public testing::Test {
PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
picture_layer_tiling_->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
timer_.Reset();
do {
@@ -164,7 +154,7 @@ class PictureLayerTilingPerfTest : public testing::Test {
PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
picture_layer_tiling_->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
timer_.Reset();
do {
@@ -194,7 +184,7 @@ class PictureLayerTilingPerfTest : public testing::Test {
PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
picture_layer_tiling_->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
timer_.Reset();
TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
@@ -226,7 +216,7 @@ class PictureLayerTilingPerfTest : public testing::Test {
PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
picture_layer_tiling_->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
SMOOTHNESS_TAKES_PRIORITY,
diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc
index 0795e11..e64191d 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -44,9 +44,7 @@ static void UpdateAllTilePriorities(PictureLayerTilingSet* set,
visible_layer_rect,
layer_contents_scale,
current_frame_time_in_seconds,
- NULL,
- NULL,
- gfx::Transform());
+ Occlusion());
}
}
@@ -540,8 +538,7 @@ TEST(PictureLayerTilingTest, SkewportLimits) {
client.SetTileSize(gfx::Size(100, 100));
tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.f, 1.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
// Move viewport down 50 pixels in 0.5 seconds.
gfx::Rect down_skewport =
@@ -607,8 +604,7 @@ TEST(PictureLayerTilingTest, ComputeSkewport) {
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.f, 1.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
// Move viewport down 50 pixels in 0.5 seconds.
gfx::Rect down_skewport =
@@ -675,8 +671,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
gfx::Rect viewport_in_content_space =
gfx::ToEnclosedRect(gfx::ScaleRect(viewport, 0.25f));
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.f, 1.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 1.0, Occlusion());
gfx::Rect soon_rect = viewport;
soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
@@ -760,8 +755,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
EXPECT_EQ(25, skewport.width());
EXPECT_EQ(35, skewport.height());
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.f, 2.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.f, 2.0, Occlusion());
have_now = false;
have_eventually = false;
@@ -812,8 +806,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
EXPECT_FLOAT_EQ(4.f, priority.distance_to_visible);
// Change the underlying layer scale.
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 2.0f, 3.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 2.0f, 3.0, Occlusion());
priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible);
@@ -826,8 +819,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
// Test additional scales.
tiling = TestablePictureLayerTiling::Create(0.2f, layer_bounds, &client);
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 4.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 4.0, Occlusion());
priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible);
@@ -838,8 +830,7 @@ TEST(PictureLayerTilingTest, ViewportDistanceWithScale) {
priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible);
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 0.5f, 5.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 0.5f, 5.0, Occlusion());
priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible);
@@ -1087,8 +1078,7 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorStaticViewport) {
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
PictureLayerTiling::TilingRasterTileIterator empty_iterator;
EXPECT_FALSE(empty_iterator);
@@ -1196,10 +1186,9 @@ TEST(PictureLayerTilingTest, TilingRasterTileIteratorMovingViewport) {
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.f, layer_bounds, &client);
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, moved_viewport, 1.0f, 2.0, NULL, NULL, gfx::Transform());
+ ACTIVE_TREE, moved_viewport, 1.0f, 2.0, Occlusion());
gfx::Rect soon_rect = moved_viewport;
soon_rect.Inset(-312.f, -312.f, -312.f, -312.f);
@@ -1272,8 +1261,7 @@ TEST(PictureLayerTilingTest, TilingEvictionTileIteratorStaticViewport) {
client.set_tree(ACTIVE_TREE);
tiling = TestablePictureLayerTiling::Create(1.0f, layer_bounds, &client);
- tiling->UpdateTilePriorities(
- ACTIVE_TREE, viewport, 1.0f, 1.0, NULL, NULL, gfx::Transform());
+ tiling->UpdateTilePriorities(ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
PictureLayerTiling::TilingRasterTileIterator empty_iterator;
EXPECT_FALSE(empty_iterator);
@@ -1351,19 +1339,15 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExist) {
gfx::Rect(layer_bounds), // visible content rect
1.f, // current contents scale
1.0, // current frame time
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
// Make the viewport rect empty. All tiles are killed and become zombies.
tiling_->UpdateTilePriorities(ACTIVE_TREE,
- gfx::Rect(), // visible content rect
- 1.f, // current contents scale
- 2.0, // current frame time
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ gfx::Rect(), // visible content rect
+ 1.f, // current contents scale
+ 2.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, false));
}
@@ -1381,19 +1365,15 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExistGiantViewport) {
gfx::Rect(layer_bounds), // visible content rect
1.f, // current contents scale
1.0, // current frame time
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
// If the visible content rect is empty, it should still have live tiles.
tiling_->UpdateTilePriorities(ACTIVE_TREE,
- giant_rect, // visible content rect
- 1.f, // current contents scale
- 2.0, // current frame time
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ giant_rect, // visible content rect
+ 1.f, // current contents scale
+ 2.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
}
@@ -1410,12 +1390,10 @@ TEST_F(PictureLayerTilingIteratorTest, TilesExistOutsideViewport) {
client_.set_tree(ACTIVE_TREE);
tiling_->UpdateTilePriorities(ACTIVE_TREE,
- viewport_rect, // visible content rect
- 1.f, // current contents scale
- 1.0, // current frame time
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ viewport_rect, // visible content rect
+ 1.f, // current contents scale
+ 1.0, // current frame time
+ Occlusion());
VerifyTiles(1.f, gfx::Rect(layer_bounds), base::Bind(&TileExists, true));
}
@@ -1442,12 +1420,10 @@ TEST_F(PictureLayerTilingIteratorTest,
client_.set_tree(ACTIVE_TREE);
set_max_tiles_for_interest_area(1);
tiling_->UpdateTilePriorities(ACTIVE_TREE,
- visible_rect, // visible content rect
- 1.f, // current contents scale
- 1.0, // current frame time
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ visible_rect, // visible content rect
+ 1.f, // current contents scale
+ 1.0, // current frame time
+ Occlusion());
VerifyTiles(1.f,
gfx::Rect(layer_bounds),
base::Bind(&TilesIntersectingRectExist, visible_rect, true));
@@ -1533,9 +1509,7 @@ TEST(UpdateTilePrioritiesTest, VisibleTiles) {
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -1590,9 +1564,7 @@ TEST(UpdateTilePrioritiesTest, OffscreenTiles) {
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -1657,9 +1629,7 @@ TEST(UpdateTilePrioritiesTest, PartiallyOffscreenLayer) {
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -1718,9 +1688,7 @@ TEST(UpdateTilePrioritiesTest, PartiallyOffscreenRotatedLayer) {
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -1803,9 +1771,7 @@ TEST(UpdateTilePrioritiesTest, PerspectiveLayer) {
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -1898,9 +1864,7 @@ TEST(UpdateTilePrioritiesTest, PerspectiveLayerClippedByW) {
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -1964,18 +1928,14 @@ TEST(UpdateTilePrioritiesTest, BasicMotion) {
viewport_in_layer_space,
last_layer_contents_scale,
last_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
// current frame
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -2046,18 +2006,14 @@ TEST(UpdateTilePrioritiesTest, RotationMotion) {
viewport_in_layer_space,
last_layer_contents_scale,
last_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
// current frame
tiling->UpdateTilePriorities(ACTIVE_TREE,
viewport_in_layer_space,
current_layer_contents_scale,
current_frame_time_in_seconds,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ Occlusion());
ASSERT_TRUE(tiling->TileAt(0, 0));
ASSERT_TRUE(tiling->TileAt(0, 1));
@@ -2086,13 +2042,8 @@ TEST(PictureLayerTilingTest, ResetClearsPriorities) {
tiling = TestablePictureLayerTiling::Create(1.0f, // contents_scale
gfx::Size(100, 100),
&client);
- tiling->UpdateTilePriorities(ACTIVE_TREE,
- gfx::Rect(0, 0, 100, 100),
- 1.0f,
- 1.0f,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
std::vector<scoped_refptr<Tile> > tiles = tiling->AllRefTilesForTesting();
ASSERT_GT(tiles.size(), 0u);
@@ -2132,13 +2083,8 @@ TEST(PictureLayerTilingTest, RecycledTilesCleared) {
gfx::Size(10000, 10000),
&active_client);
// Create all tiles on this tiling.
- active_tiling->UpdateTilePriorities(ACTIVE_TREE,
- gfx::Rect(0, 0, 100, 100),
- 1.0f,
- 1.0f,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
FakePictureLayerTilingClient recycle_client;
recycle_client.SetTileSize(gfx::Size(100, 100));
@@ -2152,13 +2098,8 @@ TEST(PictureLayerTilingTest, RecycledTilesCleared) {
&recycle_client);
// Create all tiles on the second tiling. All tiles should be shared.
- recycle_tiling->UpdateTilePriorities(PENDING_TREE,
- gfx::Rect(0, 0, 100, 100),
- 1.0f,
- 1.0f,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ recycle_tiling->UpdateTilePriorities(
+ PENDING_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
// Set the second tiling as recycled.
active_client.set_twin_tiling(NULL);
@@ -2171,25 +2112,15 @@ TEST(PictureLayerTilingTest, RecycledTilesCleared) {
EXPECT_EQ(active_tiling->TileAt(0, 0), recycle_tiling->TileAt(0, 0));
// Move the viewport far away from the (0, 0) tile.
- active_tiling->UpdateTilePriorities(ACTIVE_TREE,
- gfx::Rect(9000, 9000, 100, 100),
- 1.0f,
- 2.0,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(9000, 9000, 100, 100), 1.0f, 2.0, Occlusion());
// Ensure the tile was deleted on both tilings.
EXPECT_FALSE(active_tiling->TileAt(0, 0));
EXPECT_FALSE(recycle_tiling->TileAt(0, 0));
// Move the viewport back to (0, 0) tile.
- active_tiling->UpdateTilePriorities(ACTIVE_TREE,
- gfx::Rect(0, 0, 100, 100),
- 1.0f,
- 3.0,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 3.0, Occlusion());
// Ensure that we now have a tile here, but the recycle tiling does not.
EXPECT_TRUE(active_tiling->TileAt(0, 0));
@@ -2206,13 +2137,8 @@ TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) {
gfx::Size(100, 100),
&active_client);
// Create all tiles on this tiling.
- active_tiling->UpdateTilePriorities(ACTIVE_TREE,
- gfx::Rect(0, 0, 100, 100),
- 1.0f,
- 1.0f,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ active_tiling->UpdateTilePriorities(
+ ACTIVE_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
FakePictureLayerTilingClient recycle_client;
recycle_client.SetTileSize(gfx::Size(100, 100));
@@ -2226,13 +2152,8 @@ TEST(PictureLayerTilingTest, RecycledTilesClearedOnReset) {
&recycle_client);
// Create all tiles on the recycle tiling. All tiles should be shared.
- recycle_tiling->UpdateTilePriorities(PENDING_TREE,
- gfx::Rect(0, 0, 100, 100),
- 1.0f,
- 1.0f,
- NULL, // occlusion tracker
- NULL, // render target
- gfx::Transform()); // draw transform
+ recycle_tiling->UpdateTilePriorities(
+ PENDING_TREE, gfx::Rect(0, 0, 100, 100), 1.0f, 1.0f, Occlusion());
// Set the second tiling as recycled.
active_client.set_twin_tiling(NULL);
diff --git a/cc/resources/tile_manager_perftest.cc b/cc/resources/tile_manager_perftest.cc
index 3aa04a2..65ec4d8 100644
--- a/cc/resources/tile_manager_perftest.cc
+++ b/cc/resources/tile_manager_perftest.cc
@@ -187,7 +187,7 @@ class TileManagerPerfTest : public testing::Test {
std::vector<LayerImpl*> layers = CreateLayers(layer_count, 10);
for (unsigned i = 0; i < layers.size(); ++i)
- layers[i]->UpdateTiles(NULL);
+ layers[i]->UpdateTiles(Occlusion());
timer_.Reset();
do {
@@ -214,7 +214,7 @@ class TileManagerPerfTest : public testing::Test {
std::vector<LayerImpl*> layers = CreateLayers(layer_count, 100);
for (unsigned i = 0; i < layers.size(); ++i)
- layers[i]->UpdateTiles(NULL);
+ layers[i]->UpdateTiles(Occlusion());
int priority_count = 0;
timer_.Reset();
@@ -251,7 +251,7 @@ class TileManagerPerfTest : public testing::Test {
for (unsigned i = 0; i < layers.size(); ++i) {
FakePictureLayerImpl* layer =
static_cast<FakePictureLayerImpl*>(layers[i]);
- layer->UpdateTiles(NULL);
+ layer->UpdateTiles(Occlusion());
for (size_t j = 0; j < layer->GetTilings()->num_tilings(); ++j) {
tile_manager()->InitializeTilesWithResourcesForTesting(
layer->GetTilings()->tiling_at(j)->AllTilesForTesting());
@@ -286,7 +286,7 @@ class TileManagerPerfTest : public testing::Test {
for (unsigned i = 0; i < layers.size(); ++i) {
FakePictureLayerImpl* layer =
static_cast<FakePictureLayerImpl*>(layers[i]);
- layer->UpdateTiles(NULL);
+ layer->UpdateTiles(Occlusion());
for (size_t j = 0; j < layer->GetTilings()->num_tilings(); ++j) {
tile_manager()->InitializeTilesWithResourcesForTesting(
layer->GetTilings()->tiling_at(j)->AllTilesForTesting());
@@ -396,7 +396,7 @@ class TileManagerPerfTest : public testing::Test {
BeginFrameArgs args = CreateBeginFrameArgsForTesting();
host_impl_.UpdateCurrentBeginFrameArgs(args);
for (unsigned i = 0; i < layers.size(); ++i)
- layers[i]->UpdateTiles(NULL);
+ layers[i]->UpdateTiles(Occlusion());
GlobalStateThatImpactsTilePriority global_state(GlobalStateForTest());
tile_manager()->ManageTiles(global_state);
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index f229fcd..fdba050 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -646,37 +646,13 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) {
// Renew all of the tile priorities.
gfx::Rect viewport(50, 50, 100, 100);
pending_layer_->HighResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_layer_->render_target(),
- pending_layer_->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
pending_layer_->LowResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_layer_->render_target(),
- pending_layer_->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
active_layer_->HighResTiling()->UpdateTilePriorities(
- ACTIVE_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- active_layer_->render_target(),
- active_layer_->draw_transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
active_layer_->LowResTiling()->UpdateTilePriorities(
- ACTIVE_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- active_layer_->render_target(),
- active_layer_->draw_transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
// Populate all tiles directly from the tilings.
all_tiles.clear();
@@ -845,37 +821,13 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) {
// Renew all of the tile priorities.
gfx::Rect viewport(50, 50, 100, 100);
pending_layer_->HighResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_layer_->render_target(),
- pending_layer_->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
pending_layer_->LowResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_layer_->render_target(),
- pending_layer_->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
active_layer_->HighResTiling()->UpdateTilePriorities(
- ACTIVE_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- active_layer_->render_target(),
- active_layer_->draw_transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
active_layer_->LowResTiling()->UpdateTilePriorities(
- ACTIVE_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- active_layer_->render_target(),
- active_layer_->draw_transform());
+ ACTIVE_TREE, viewport, 1.0f, 1.0, Occlusion());
// Populate all tiles directly from the tilings.
all_tiles.clear();
@@ -1020,37 +972,13 @@ TEST_F(TileManagerTilePriorityQueueTest,
// Renew all of the tile priorities.
gfx::Rect viewport(layer_bounds);
pending_layer_->HighResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_layer_->render_target(),
- pending_layer_->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
pending_layer_->LowResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_layer_->render_target(),
- pending_layer_->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
pending_child_layer->HighResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_child_layer->render_target(),
- pending_child_layer->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
pending_child_layer->LowResTiling()->UpdateTilePriorities(
- PENDING_TREE,
- viewport,
- 1.0f,
- 1.0,
- NULL,
- pending_child_layer->render_target(),
- pending_child_layer->draw_transform());
+ PENDING_TREE, viewport, 1.0f, 1.0, Occlusion());
// Populate all tiles directly from the tilings.
all_tiles.clear();
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 328234f..e368bb8 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -520,8 +520,13 @@ bool LayerTreeImpl::UpdateDrawProperties() {
occlusion_tracker->EnterLayer(it);
LayerImpl* layer = *it;
+ const Occlusion& occlusion_in_content_space =
+ occlusion_tracker ? occlusion_tracker->GetCurrentOcclusionForLayer(
+ layer->draw_transform())
+ : Occlusion();
+
if (it.represents_itself())
- layer->UpdateTiles(occlusion_tracker.get());
+ layer->UpdateTiles(occlusion_in_content_space);
if (!it.represents_contributing_render_surface()) {
if (occlusion_tracker)
@@ -530,10 +535,10 @@ bool LayerTreeImpl::UpdateDrawProperties() {
}
if (layer->mask_layer())
- layer->mask_layer()->UpdateTiles(occlusion_tracker.get());
+ layer->mask_layer()->UpdateTiles(occlusion_in_content_space);
if (layer->replica_layer() && layer->replica_layer()->mask_layer())
layer->replica_layer()->mask_layer()->UpdateTiles(
- occlusion_tracker.get());
+ occlusion_in_content_space);
if (occlusion_tracker)
occlusion_tracker->LeaveLayer(it);
diff --git a/cc/trees/occlusion.cc b/cc/trees/occlusion.cc
new file mode 100644
index 0000000..c91c0ca
--- /dev/null
+++ b/cc/trees/occlusion.cc
@@ -0,0 +1,48 @@
+// 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 "cc/base/math_util.h"
+#include "ui/gfx/rect.h"
+
+namespace cc {
+
+Occlusion::Occlusion() {
+}
+
+Occlusion::Occlusion(const gfx::Transform& draw_transform,
+ const SimpleEnclosedRegion& occlusion_from_outside_target,
+ const SimpleEnclosedRegion& occlusion_from_inside_target)
+ : draw_transform_(draw_transform),
+ occlusion_from_outside_target_(occlusion_from_outside_target),
+ occlusion_from_inside_target_(occlusion_from_inside_target) {
+}
+
+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()) {
+ return false;
+ }
+
+ // Take the ToEnclosingRect at each step, as we want to contain any unoccluded
+ // partial pixels in the resulting Rect.
+ gfx::Rect unoccluded_rect_in_target_surface =
+ MathUtil::MapEnclosingClippedRect(draw_transform_, content_rect);
+ DCHECK_LE(occlusion_from_inside_target_.GetRegionComplexity(), 1u);
+ DCHECK_LE(occlusion_from_outside_target_.GetRegionComplexity(), 1u);
+ // These subtract operations are more lossy than if we did both operations at
+ // once.
+ unoccluded_rect_in_target_surface.Subtract(
+ occlusion_from_inside_target_.bounds());
+ unoccluded_rect_in_target_surface.Subtract(
+ occlusion_from_outside_target_.bounds());
+
+ return unoccluded_rect_in_target_surface.IsEmpty();
+}
+
+} // namespace cc
diff --git a/cc/trees/occlusion.h b/cc/trees/occlusion.h
new file mode 100644
index 0000000..982d7e8
--- /dev/null
+++ b/cc/trees/occlusion.h
@@ -0,0 +1,36 @@
+// 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.
+
+#ifndef CC_TREES_OCCLUSION_H_
+#define CC_TREES_OCCLUSION_H_
+
+#include "base/basictypes.h"
+#include "cc/base/cc_export.h"
+#include "cc/base/simple_enclosed_region.h"
+#include "ui/gfx/transform.h"
+
+namespace gfx {
+class Rect;
+} // namespace gfx
+
+namespace cc {
+
+class CC_EXPORT Occlusion {
+ public:
+ Occlusion();
+ Occlusion(const gfx::Transform& draw_transform,
+ const SimpleEnclosedRegion& occlusion_from_outside_target,
+ const SimpleEnclosedRegion& occlusion_from_inside_target);
+
+ bool IsOccluded(const gfx::Rect& content_rect) const;
+
+ private:
+ gfx::Transform draw_transform_;
+ SimpleEnclosedRegion occlusion_from_outside_target_;
+ SimpleEnclosedRegion occlusion_from_inside_target_;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_OCCLUSION_H_
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc
index f233e07..8fdd6e2 100644
--- a/cc/trees/occlusion_tracker.cc
+++ b/cc/trees/occlusion_tracker.cc
@@ -28,6 +28,16 @@ template <typename LayerType>
OcclusionTracker<LayerType>::~OcclusionTracker() {}
template <typename LayerType>
+Occlusion OcclusionTracker<LayerType>::GetCurrentOcclusionForLayer(
+ const gfx::Transform& draw_transform) const {
+ DCHECK(!stack_.empty());
+ const StackObject& back = stack_.back();
+ return Occlusion(draw_transform,
+ back.occlusion_from_outside_target,
+ back.occlusion_from_inside_target);
+}
+
+template <typename LayerType>
void OcclusionTracker<LayerType>::EnterLayer(
const LayerIteratorPosition<LayerType>& layer_iterator) {
LayerType* render_target = layer_iterator.target_render_surface_layer;
diff --git a/cc/trees/occlusion_tracker.h b/cc/trees/occlusion_tracker.h
index 8d07f43..9b4b74e 100644
--- a/cc/trees/occlusion_tracker.h
+++ b/cc/trees/occlusion_tracker.h
@@ -11,6 +11,7 @@
#include "cc/base/cc_export.h"
#include "cc/base/simple_enclosed_region.h"
#include "cc/layers/layer_iterator.h"
+#include "cc/trees/occlusion.h"
#include "ui/gfx/rect.h"
namespace cc {
@@ -35,6 +36,11 @@ class CC_EXPORT OcclusionTracker {
explicit OcclusionTracker(const gfx::Rect& screen_space_clip_rect);
~OcclusionTracker();
+ // Return an occlusion that retains the current state of the tracker
+ // and can be used outside of a layer walk to check occlusion.
+ Occlusion GetCurrentOcclusionForLayer(
+ const gfx::Transform& draw_transform) const;
+
// Called at the beginning of each step in the LayerIterator's front-to-back
// traversal.
void EnterLayer(const LayerIteratorPosition<LayerType>& layer_iterator);
diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc
index aaf655f2..56059cb 100644
--- a/cc/trees/occlusion_tracker_unittest.cc
+++ b/cc/trees/occlusion_tracker_unittest.cc
@@ -85,6 +85,11 @@ class TestOcclusionTrackerWithClip : public TestOcclusionTracker<LayerType> {
bool OccludedLayer(const LayerType* layer,
const gfx::Rect& content_rect) const {
DCHECK(layer->visible_content_rect().Contains(content_rect));
+ EXPECT_EQ(
+ this->Occluded(
+ layer->render_target(), content_rect, layer->draw_transform()),
+ this->GetCurrentOcclusionForLayer(layer->draw_transform())
+ .IsOccluded(content_rect));
return this->Occluded(
layer->render_target(), content_rect, layer->draw_transform());
}