Skip to content

Commit

Permalink
Do not clip inside OcclusionTracker.
Browse files Browse the repository at this point in the history
Assume that content-rect is already clipped. This allows us to
early-out from occlusion testing when there is no occlusion.

BUG=276725

Review URL: https://codereview.chromium.org/23708021

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227133 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
alokp@chromium.org committed Oct 4, 2013
1 parent ff2cfd3 commit cfc2d2d
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 984 deletions.
4 changes: 1 addition & 3 deletions cc/layers/tiled_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,7 @@ void TiledLayer::MarkOcclusionsAndRequestTextures(
if (occlusion && occlusion->Occluded(render_target(),
visible_tile_rect,
draw_transform(),
draw_transform_is_animating(),
is_clipped(),
clip_rect())) {
draw_transform_is_animating())) {
tile->occluded = true;
occluded_tile_count++;
} else {
Expand Down
4 changes: 1 addition & 3 deletions cc/trees/layer_tree_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -768,9 +768,7 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
it->render_target(),
it->visible_content_rect(),
it->draw_transform(),
impl_draw_transform_is_unknown,
it->is_clipped(),
it->clip_rect());
impl_draw_transform_is_unknown);
if (!occluded && it->WillDraw(draw_mode, resource_provider_.get())) {
DCHECK_EQ(active_tree_, it->layer_tree_impl());

Expand Down
40 changes: 12 additions & 28 deletions cc/trees/occlusion_tracker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -508,9 +508,7 @@ bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded(
const LayerType* render_target,
gfx::Rect content_rect,
const gfx::Transform& draw_transform,
bool impl_draw_transform_is_unknown,
bool is_clipped,
gfx::Rect clip_rect_in_target) const {
bool impl_draw_transform_is_unknown) const {
if (prevent_occlusion_)
return false;

Expand All @@ -530,6 +528,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;
Expand All @@ -538,24 +541,13 @@ 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);
unoccluded_region_in_target_surface.Subtract(
stack_.back().occlusion_from_inside_target);
gfx::RectF unoccluded_rect_in_target_surface_without_outside_occlusion =
unoccluded_region_in_target_surface.bounds();
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();

Expand All @@ -568,9 +560,7 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>::
const LayerType* render_target,
gfx::Rect content_rect,
const gfx::Transform& draw_transform,
bool impl_draw_transform_is_unknown,
bool is_clipped,
gfx::Rect clip_rect_in_target) const {
bool impl_draw_transform_is_unknown) const {
if (prevent_occlusion_)
return content_rect;

Expand All @@ -590,6 +580,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;
Expand All @@ -598,24 +593,13 @@ 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 =
unoccluded_region_in_target_surface.bounds();
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(
Expand Down
14 changes: 4 additions & 10 deletions cc/trees/occlusion_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,21 @@ class CC_EXPORT OcclusionTrackerBase {
// Returns true if the given rect in content space for a layer is fully
// occluded in either screen space or the layer's target surface.
// |render_target| is the contributing layer's render target, and
// |draw_transform|, |transformsToTargetKnown| and |clippedRectInTarget| are
// relative to that.
// |draw_transform| and |impl_draw_transform_is_unknown| are relative to that.
bool Occluded(const LayerType* render_target,
gfx::Rect content_rect,
const gfx::Transform& draw_transform,
bool impl_draw_transform_is_unknown,
bool is_clipped,
gfx::Rect clip_rect_in_target) const;
bool impl_draw_transform_is_unknown) const;

// Gives an unoccluded sub-rect of |content_rect| in the content space of a
// layer. Used when considering occlusion for a layer that paints/draws
// something. |render_target| is the contributing layer's render target, and
// |draw_transform|, |transformsToTargetKnown| and |clippedRectInTarget| are
// relative to that.
// |draw_transform| and |impl_draw_transform_is_unknown| are relative to that.
gfx::Rect UnoccludedContentRect(
const LayerType* render_target,
gfx::Rect content_rect,
const gfx::Transform& draw_transform,
bool impl_draw_transform_is_unknown,
bool is_clipped,
gfx::Rect clip_rect_in_target) const;
bool impl_draw_transform_is_unknown) const;

// Gives an unoccluded sub-rect of |content_rect| in the content space of the
// render_target owned by the layer. Used when considering occlusion for a
Expand Down
Loading

0 comments on commit cfc2d2d

Please sign in to comment.