Index: cc/trees/occlusion_tracker.cc |
diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc |
index 9fc26da566700ce9b46cb88974730ba722a6b155..0f5cae930c9b9347db8bd3e4eb63bc58233003ed 100644 |
--- a/cc/trees/occlusion_tracker.cc |
+++ b/cc/trees/occlusion_tracker.cc |
@@ -19,9 +19,8 @@ namespace cc { |
template <typename LayerType, typename RenderSurfaceType> |
OcclusionTrackerBase<LayerType, RenderSurfaceType>::OcclusionTrackerBase( |
- gfx::Rect screen_space_clip_rect, bool record_metrics_for_frame) |
- : screen_space_clip_rect_(screen_space_clip_rect), |
- overdraw_metrics_(OverdrawMetrics::Create(record_metrics_for_frame)), |
+ bool record_metrics_for_frame) |
+ : overdraw_metrics_(OverdrawMetrics::Create(record_metrics_for_frame)), |
prevent_occlusion_(false), |
occluding_screen_space_rects_(NULL), |
non_occluding_screen_space_rects_(NULL) {} |
@@ -59,22 +58,7 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::LeaveLayer( |
} |
template <typename RenderSurfaceType> |
-static gfx::Rect ScreenSpaceClipRectInTargetSurface( |
- const RenderSurfaceType* target_surface, gfx::Rect screen_space_clip_rect) { |
- gfx::Transform inverse_screen_space_transform( |
- gfx::Transform::kSkipInitialization); |
- if (!target_surface->screen_space_transform().GetInverse( |
- &inverse_screen_space_transform)) |
- return target_surface->content_rect(); |
- |
- return gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( |
- inverse_screen_space_transform, screen_space_clip_rect)); |
-} |
- |
-template <typename RenderSurfaceType> |
static Region TransformSurfaceOpaqueRegion(const Region& region, |
- bool have_clip_rect, |
- gfx::Rect clip_rect_in_new_target, |
const gfx::Transform& transform) { |
if (region.IsEmpty()) |
return Region(); |
@@ -97,8 +81,6 @@ static Region TransformSurfaceOpaqueRegion(const Region& region, |
gfx::Rect transformed_rect = |
gfx::ToEnclosedRect(transformed_quad.BoundingBox()); |
DCHECK(!clipped); // We only map if the transform preserves axis alignment. |
- if (have_clip_rect) |
danakj
2013/09/16 17:29:08
I don't really understand this change. It's just a
|
- transformed_rect.Intersect(clip_rect_in_new_target); |
transformed_region.Union(transformed_rect); |
} |
return transformed_region; |
@@ -207,14 +189,10 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::EnterRenderTarget( |
stack_[last_index].occlusion_from_outside_target = |
TransformSurfaceOpaqueRegion<RenderSurfaceType>( |
stack_[last_index - 1].occlusion_from_outside_target, |
- false, |
- gfx::Rect(), |
old_target_to_new_target_transform); |
stack_[last_index].occlusion_from_outside_target.Union( |
TransformSurfaceOpaqueRegion<RenderSurfaceType>( |
stack_[last_index - 1].occlusion_from_inside_target, |
- false, |
- gfx::Rect(), |
old_target_to_new_target_transform)); |
} |
@@ -260,12 +238,6 @@ static void ReduceOcclusionBelowSurface(LayerType* contributing_layer, |
gfx::Rect affected_area_in_target = gfx::ToEnclosingRect( |
MathUtil::MapClippedRect(surface_transform, gfx::RectF(surface_rect))); |
- if (contributing_layer->render_surface()->is_clipped()) { |
- affected_area_in_target.Intersect( |
danakj
2013/09/16 17:29:08
Again, just an intersection. I think there's two w
alokp
2013/09/17 00:31:41
I have decided to break this into two patches - on
|
- contributing_layer->render_surface()->clip_rect()); |
- } |
- if (affected_area_in_target.IsEmpty()) |
- return; |
int outset_top, outset_right, outset_bottom, outset_left; |
contributing_layer->background_filters().GetOutsets( |
@@ -327,23 +299,22 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::LeaveToRenderTarget( |
Region old_occlusion_from_inside_target_in_new_target = |
TransformSurfaceOpaqueRegion<RenderSurfaceType>( |
stack_[last_index].occlusion_from_inside_target, |
- old_surface->is_clipped(), |
- old_surface->clip_rect(), |
old_surface->draw_transform()); |
if (old_target->has_replica() && !old_target->replica_has_mask()) { |
old_occlusion_from_inside_target_in_new_target.Union( |
TransformSurfaceOpaqueRegion<RenderSurfaceType>( |
stack_[last_index].occlusion_from_inside_target, |
- old_surface->is_clipped(), |
- old_surface->clip_rect(), |
old_surface->replica_draw_transform())); |
} |
+ // Verify that the occluded region is contained inside the |
+ // target surface clip-rect. |
+ DCHECK(!old_surface->is_clipped() || |
+ old_surface->clip_rect().Contains( |
+ old_occlusion_from_inside_target_in_new_target.bounds())); |
Region old_occlusion_from_outside_target_in_new_target = |
TransformSurfaceOpaqueRegion<RenderSurfaceType>( |
stack_[last_index].occlusion_from_outside_target, |
- false, |
- gfx::Rect(), |
old_surface->draw_transform()); |
gfx::Rect unoccluded_surface_rect; |
@@ -436,15 +407,6 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
if (!layer->draw_transform().Preserves2dAxisAlignment()) |
return; |
- gfx::Rect clip_rect_in_target = ScreenSpaceClipRectInTargetSurface( |
- layer->render_target()->render_surface(), screen_space_clip_rect_); |
- if (layer->is_clipped()) { |
- clip_rect_in_target.Intersect(layer->clip_rect()); |
- } else { |
- clip_rect_in_target.Intersect( |
- layer->render_target()->render_surface()->content_rect()); |
- } |
- |
for (Region::Iterator opaque_content_rects(opaque_contents); |
opaque_content_rects.has_rect(); |
opaque_content_rects.next()) { |
@@ -456,7 +418,16 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
gfx::Rect transformed_rect = |
gfx::ToEnclosedRect(transformed_quad.BoundingBox()); |
DCHECK(!clipped); // We only map if the transform preserves axis alignment. |
- transformed_rect.Intersect(clip_rect_in_target); |
+#ifndef NDEBUG |
danakj
2013/09/16 17:29:08
if (DCHECK_IS_ON()) {
|
+ // Verify that the occluded region is contained inside the target surface |
+ // clip-rect or bounds. We do not do any clipping here in occlusion tracker. |
+ // We assume that visible-content-rect has already been clipped during |
+ // CalculateDrawProperties. |
+ gfx::Rect clip_rect_in_target = layer->is_clipped() ? |
+ layer->clip_rect() : |
+ layer->render_target()->render_surface()->content_rect(); |
+ DCHECK(clip_rect_in_target.Contains(transformed_rect)); |
danakj
2013/09/16 17:29:08
Note that this DCHECK is verifying the clip rect i
|
+#endif // NDEBUG |
if (transformed_rect.width() < minimum_tracking_size_.width() && |
transformed_rect.height() < minimum_tracking_size_.height()) |
continue; |
@@ -476,6 +447,7 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
occluding_screen_space_rects_->push_back(screen_space_rect); |
} |
+ |
danakj
2013/09/16 17:29:08
extra whitespace
alokp
2013/09/17 00:31:41
Done.
|
if (!non_occluding_screen_space_rects_) |
return; |
@@ -489,7 +461,6 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
gfx::Rect transformed_rect = gfx::ToEnclosedRect( |
MathUtil::MapClippedRect(layer->draw_transform(), |
gfx::RectF(non_opaque_content_rects.rect()))); |
- transformed_rect.Intersect(clip_rect_in_target); |
if (transformed_rect.IsEmpty()) |
continue; |
@@ -512,8 +483,6 @@ bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( |
gfx::Rect content_rect, |
const gfx::Transform& draw_transform, |
bool impl_draw_transform_is_unknown, |
- bool is_clipped, |
- gfx::Rect clip_rect_in_target, |
bool* has_occlusion_from_outside_target_surface) const { |
if (has_occlusion_from_outside_target_surface) |
*has_occlusion_from_outside_target_surface = false; |
@@ -536,6 +505,11 @@ bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( |
DCHECK(render_target->render_surface()); |
DCHECK_EQ(render_target, stack_.back().target); |
+ if (stack_.back().occlusion_from_inside_target.IsEmpty() && |
+ stack_.back().occlusion_from_outside_target.IsEmpty()) { |
+ return false; |
+ } |
+ |
gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); |
if (!draw_transform.GetInverse(&inverse_draw_transform)) |
return false; |
@@ -544,9 +518,6 @@ bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( |
// partial pixels in the resulting Rect. |
Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
- // Layers can't clip across surfaces, so count this as internal occlusion. |
- if (is_clipped) |
- unoccluded_region_in_target_surface.Intersect(clip_rect_in_target); |
danakj
2013/09/16 17:29:08
I think I buy that this can go away (and not move
|
unoccluded_region_in_target_surface.Subtract( |
stack_.back().occlusion_from_inside_target); |
gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
@@ -554,14 +525,6 @@ bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( |
unoccluded_region_in_target_surface.Subtract( |
stack_.back().occlusion_from_outside_target); |
- // Treat other clipping as occlusion from outside the surface. |
danakj
2013/09/16 17:29:08
I'm not sure why you say that the has_occlusion_fr
alokp
2013/09/17 00:31:41
You are right. I do not see how I can preserve thi
|
- // TODO(danakj): Clip to visibleContentRect? |
- unoccluded_region_in_target_surface.Intersect( |
- render_target->render_surface()->content_rect()); |
- unoccluded_region_in_target_surface.Intersect( |
- ScreenSpaceClipRectInTargetSurface(render_target->render_surface(), |
- screen_space_clip_rect_)); |
- |
gfx::RectF unoccluded_rect_in_target_surface = |
unoccluded_region_in_target_surface.bounds(); |
@@ -582,8 +545,6 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
gfx::Rect content_rect, |
const gfx::Transform& draw_transform, |
bool impl_draw_transform_is_unknown, |
- bool is_clipped, |
- gfx::Rect clip_rect_in_target, |
bool* has_occlusion_from_outside_target_surface) const { |
if (has_occlusion_from_outside_target_surface) |
*has_occlusion_from_outside_target_surface = false; |
@@ -606,6 +567,11 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
DCHECK(render_target->render_surface()); |
DCHECK_EQ(render_target, stack_.back().target); |
+ if (stack_.back().occlusion_from_inside_target.IsEmpty() && |
+ stack_.back().occlusion_from_outside_target.IsEmpty()) { |
+ return content_rect; |
+ } |
+ |
gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); |
if (!draw_transform.GetInverse(&inverse_draw_transform)) |
return content_rect; |
@@ -614,9 +580,6 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
// partial pixels in the resulting Rect. |
Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
- // Layers can't clip across surfaces, so count this as internal occlusion. |
- if (is_clipped) |
- unoccluded_region_in_target_surface.Intersect(clip_rect_in_target); |
unoccluded_region_in_target_surface.Subtract( |
stack_.back().occlusion_from_inside_target); |
gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
@@ -624,14 +587,6 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
unoccluded_region_in_target_surface.Subtract( |
stack_.back().occlusion_from_outside_target); |
- // Treat other clipping as occlusion from outside the surface. |
- // TODO(danakj): Clip to visibleContentRect? |
- unoccluded_region_in_target_surface.Intersect( |
- render_target->render_surface()->content_rect()); |
- unoccluded_region_in_target_surface.Intersect( |
- ScreenSpaceClipRectInTargetSurface(render_target->render_surface(), |
- screen_space_clip_rect_)); |
- |
gfx::RectF unoccluded_rect_in_target_surface = |
unoccluded_region_in_target_surface.bounds(); |
gfx::Rect unoccluded_rect = gfx::ToEnclosingRect( |
@@ -675,10 +630,18 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
if (content_rect.IsEmpty()) |
return content_rect; |
- const RenderSurfaceType* surface = layer->render_surface(); |
- const LayerType* contributing_surface_render_target = |
- layer->parent()->render_target(); |
+ // 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). |
+ if (stack_.size() == 1) |
+ 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; |
+ } |
+ const RenderSurfaceType* surface = layer->render_surface(); |
if (!SurfaceTransformsToTargetKnown(surface)) |
return content_rect; |
@@ -689,38 +652,16 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: |
if (!draw_transform.GetInverse(&inverse_draw_transform)) |
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; |
- |
// Take the ToEnclosingRect at each step, as we want to contain any unoccluded |
// partial pixels in the resulting Rect. |
Region unoccluded_region_in_target_surface = gfx::ToEnclosingRect( |
MathUtil::MapClippedRect(draw_transform, gfx::RectF(content_rect))); |
- // Layers can't clip across surfaces, so count this as internal occlusion. |
- if (surface->is_clipped()) |
- unoccluded_region_in_target_surface.Intersect(surface->clip_rect()); |
- if (has_occlusion) { |
- const StackObject& second_last = stack_[stack_.size() - 2]; |
- unoccluded_region_in_target_surface.Subtract( |
- second_last.occlusion_from_inside_target); |
- } |
+ unoccluded_region_in_target_surface.Subtract( |
+ second_last.occlusion_from_inside_target); |
gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion = |
unoccluded_region_in_target_surface.bounds(); |
- if (has_occlusion) { |
- const StackObject& second_last = stack_[stack_.size() - 2]; |
- unoccluded_region_in_target_surface.Subtract( |
- second_last.occlusion_from_outside_target); |
- } |
- |
- // Treat other clipping as occlusion from outside the target surface. |
- unoccluded_region_in_target_surface.Intersect( |
- contributing_surface_render_target->render_surface()->content_rect()); |
- unoccluded_region_in_target_surface.Intersect( |
- ScreenSpaceClipRectInTargetSurface( |
- contributing_surface_render_target->render_surface(), |
- screen_space_clip_rect_)); |
+ unoccluded_region_in_target_surface.Subtract( |
+ second_last.occlusion_from_outside_target); |
gfx::RectF unoccluded_rect_in_target_surface = |
unoccluded_region_in_target_surface.bounds(); |