| 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 =
|
|
|