Index: cc/trees/occlusion_tracker.cc |
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc |
index bce1fd514e8bc82318b2857e5f39f1edba0f3b9a..388eb6ee2caa20c2a797bc6b4c8f0c22206ecc36 100644 |
--- a/cc/trees/occlusion_tracker.cc |
+++ b/cc/trees/occlusion_tracker.cc |
@@ -20,12 +20,12 @@ namespace cc { |
template <typename LayerType> |
OcclusionTracker<LayerType>::OcclusionTracker( |
const gfx::Rect& screen_space_clip_rect) |
- : screen_space_clip_rect_(screen_space_clip_rect), |
- occluding_screen_space_rects_(NULL), |
- non_occluding_screen_space_rects_(NULL) {} |
+ : screen_space_clip_rect_(screen_space_clip_rect) { |
+} |
template <typename LayerType> |
-OcclusionTracker<LayerType>::~OcclusionTracker() {} |
+OcclusionTracker<LayerType>::~OcclusionTracker() { |
+} |
template <typename LayerType> |
Occlusion OcclusionTracker<LayerType>::GetCurrentOcclusionForLayer( |
@@ -38,6 +38,21 @@ Occlusion OcclusionTracker<LayerType>::GetCurrentOcclusionForLayer( |
} |
template <typename LayerType> |
+Occlusion |
+OcclusionTracker<LayerType>::GetCurrentOcclusionForContributingSurface( |
+ const gfx::Transform& draw_transform) const { |
+ DCHECK(!stack_.empty()); |
+ if (stack_.size() < 2) |
+ return Occlusion(); |
+ // A contributing surface doesn't get occluded by things inside its own |
+ // surface, so only things outside the surface can occlude it. That occlusion |
+ // is found just below the top of the stack (if it exists). |
+ const StackObject& second_last = stack_[stack_.size() - 2]; |
+ return Occlusion(draw_transform, second_last.occlusion_from_outside_target, |
+ second_last.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; |
@@ -340,12 +355,15 @@ void OcclusionTracker<LayerType>::LeaveToRenderTarget( |
gfx::Rect unoccluded_surface_rect; |
gfx::Rect unoccluded_replica_rect; |
if (old_target->background_filters().HasFilterThatMovesPixels()) { |
- unoccluded_surface_rect = UnoccludedContributingSurfaceContentRect( |
- old_surface->content_rect(), old_surface->draw_transform()); |
+ Occlusion surface_occlusion = GetCurrentOcclusionForContributingSurface( |
+ old_surface->draw_transform()); |
+ unoccluded_surface_rect = |
+ surface_occlusion.GetUnoccludedContentRect(old_surface->content_rect()); |
if (old_target->has_replica()) { |
- unoccluded_replica_rect = UnoccludedContributingSurfaceContentRect( |
- old_surface->content_rect(), |
+ Occlusion replica_occlusion = GetCurrentOcclusionForContributingSurface( |
old_surface->replica_draw_transform()); |
+ unoccluded_replica_rect = replica_occlusion.GetUnoccludedContentRect( |
+ old_surface->content_rect()); |
} |
} |
@@ -447,99 +465,10 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer( |
transformed_rect.height() < minimum_tracking_size_.height()) |
continue; |
stack_.back().occlusion_from_inside_target.Union(transformed_rect); |
- |
- if (!occluding_screen_space_rects_) |
- continue; |
- |
- // Save the occluding area in screen space for debug visualization. |
- bool clipped; |
- gfx::QuadF screen_space_quad = MathUtil::MapQuad( |
- layer->render_target()->render_surface()->screen_space_transform(), |
- gfx::QuadF(transformed_rect), &clipped); |
- // TODO(danakj): Store the quad in the debug info instead of the bounding |
- // box. |
- gfx::Rect screen_space_rect = |
- gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); |
- occluding_screen_space_rects_->push_back(screen_space_rect); |
- } |
- |
- if (!non_occluding_screen_space_rects_) |
- return; |
- |
- Region non_opaque_contents(gfx::Rect(layer->content_bounds())); |
- non_opaque_contents.Subtract(opaque_contents); |
- |
- for (Region::Iterator non_opaque_content_rects(non_opaque_contents); |
- non_opaque_content_rects.has_rect(); |
- non_opaque_content_rects.next()) { |
- gfx::Rect transformed_rect = |
- MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( |
- layer->draw_transform(), non_opaque_content_rects.rect()); |
- transformed_rect.Intersect(clip_rect_in_target); |
- if (transformed_rect.IsEmpty()) |
- continue; |
- |
- bool clipped; |
- gfx::QuadF screen_space_quad = MathUtil::MapQuad( |
- layer->render_target()->render_surface()->screen_space_transform(), |
- gfx::QuadF(transformed_rect), |
- &clipped); |
- // TODO(danakj): Store the quad in the debug info instead of the bounding |
- // box. |
- gfx::Rect screen_space_rect = |
- gfx::ToEnclosedRect(screen_space_quad.BoundingBox()); |
- non_occluding_screen_space_rects_->push_back(screen_space_rect); |
} |
} |
template <typename LayerType> |
-gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect( |
- const gfx::Rect& content_rect, |
- const gfx::Transform& draw_transform) const { |
- if (content_rect.IsEmpty()) |
- return content_rect; |
- |
- // A contributing surface doesn't get occluded by things inside its own |
- // surface, so only things outside the surface can occlude it. That occlusion |
- // is found just below the top of the stack (if it exists). |
- bool has_occlusion = stack_.size() > 1; |
- if (!has_occlusion) |
- return content_rect; |
- |
- const StackObject& second_last = stack_[stack_.size() - 2]; |
- if (second_last.occlusion_from_inside_target.IsEmpty() && |
- second_last.occlusion_from_outside_target.IsEmpty()) |
- return content_rect; |
- |
- gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); |
- bool ok = draw_transform.GetInverse(&inverse_draw_transform); |
- DCHECK(ok); |
- |
- // 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(second_last.occlusion_from_inside_target.GetRegionComplexity(), 1u); |
- DCHECK_LE(second_last.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( |
- second_last.occlusion_from_inside_target.bounds()); |
- unoccluded_rect_in_target_surface.Subtract( |
- second_last.occlusion_from_outside_target.bounds()); |
- |
- if (unoccluded_rect_in_target_surface.IsEmpty()) |
- return gfx::Rect(); |
- |
- gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( |
- inverse_draw_transform, unoccluded_rect_in_target_surface); |
- unoccluded_rect.Intersect(content_rect); |
- |
- return unoccluded_rect; |
-} |
- |
-template <typename LayerType> |
Region OcclusionTracker<LayerType>::ComputeVisibleRegionInScreen() const { |
DCHECK(!stack_.back().target->parent()); |
const SimpleEnclosedRegion& occluded = |