Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2050)

Unified Diff: cc/trees/occlusion_tracker.cc

Issue 23708021: Do not clip inside OcclusionTracker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: added DCHECK Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();

Powered by Google App Engine
This is Rietveld 408576698