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

Unified Diff: cc/trees/occlusion_tracker.cc

Issue 202523002: cc: Replace Region with SimpleEnclosedRegion for occlusion tracking (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: simpleregion: . Created 6 years, 4 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 fb3b5acfe94c90fc145aa1f44279270e1f7a453f..a25b444fc6b1dd4580557f1d323865582ce8283b 100644
--- a/cc/trees/occlusion_tracker.cc
+++ b/cc/trees/occlusion_tracker.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "cc/base/math_util.h"
+#include "cc/base/region.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/render_surface.h"
@@ -65,13 +66,13 @@ static gfx::Rect ScreenSpaceClipRectInTargetSurface(
}
template <typename RenderSurfaceType>
-static Region TransformSurfaceOpaqueRegion(
- const Region& region,
+static SimpleEnclosedRegion TransformSurfaceOpaqueRegion(
+ const SimpleEnclosedRegion& region,
bool have_clip_rect,
const gfx::Rect& clip_rect_in_new_target,
const gfx::Transform& transform) {
if (region.IsEmpty())
- return Region();
+ return region;
// Verify that rects within the |surface| will remain rects in its target
// surface after applying |transform|. If this is true, then apply |transform|
@@ -79,23 +80,19 @@ static Region TransformSurfaceOpaqueRegion(
// TODO(danakj): Find a rect interior to each transformed quad.
if (!transform.Preserves2dAxisAlignment())
- return Region();
+ return SimpleEnclosedRegion();
- // TODO(danakj): If the Region is too complex, degrade gracefully here by
- // skipping rects in it.
- Region transformed_region;
- for (Region::Iterator rects(region); rects.has_rect(); rects.next()) {
+ gfx::Rect transformed_rect;
+ for (size_t i = 0; i < region.GetRegionComplexity(); ++i) {
bool clipped;
gfx::QuadF transformed_quad =
- MathUtil::MapQuad(transform, gfx::QuadF(rects.rect()), &clipped);
- gfx::Rect transformed_rect =
- gfx::ToEnclosedRect(transformed_quad.BoundingBox());
+ MathUtil::MapQuad(transform, gfx::QuadF(region.GetRect(i)), &clipped);
+ transformed_rect = gfx::ToEnclosedRect(transformed_quad.BoundingBox());
DCHECK(!clipped); // We only map if the transform preserves axis alignment.
if (have_clip_rect)
transformed_rect.Intersect(clip_rect_in_new_target);
- transformed_region.Union(transformed_rect);
}
- return transformed_region;
+ return SimpleEnclosedRegion(transformed_rect);
}
static inline bool LayerOpacityKnown(const Layer* layer) {
@@ -240,11 +237,12 @@ void OcclusionTracker<LayerType>::FinishedRenderTarget(
}
template <typename LayerType>
-static void ReduceOcclusionBelowSurface(LayerType* contributing_layer,
- const gfx::Rect& surface_rect,
- const gfx::Transform& surface_transform,
- LayerType* render_target,
- Region* occlusion_from_inside_target) {
+static void ReduceOcclusionBelowSurface(
+ LayerType* contributing_layer,
+ const gfx::Rect& surface_rect,
+ const gfx::Transform& surface_transform,
+ LayerType* render_target,
+ SimpleEnclosedRegion* occlusion_from_inside_target) {
if (surface_rect.IsEmpty())
return;
@@ -265,13 +263,13 @@ static void ReduceOcclusionBelowSurface(LayerType* contributing_layer,
// to expand outside the clip.
affected_area_in_target.Inset(
-outset_left, -outset_top, -outset_right, -outset_bottom);
- Region affected_occlusion = IntersectRegions(*occlusion_from_inside_target,
- affected_area_in_target);
- Region::Iterator affected_occlusion_rects(affected_occlusion);
+ SimpleEnclosedRegion affected_occlusion = IntersectSimpleEnclosedRegions(
+ *occlusion_from_inside_target,
+ SimpleEnclosedRegion(affected_area_in_target));
occlusion_from_inside_target->Subtract(affected_area_in_target);
- for (; affected_occlusion_rects.has_rect(); affected_occlusion_rects.next()) {
- gfx::Rect occlusion_rect = affected_occlusion_rects.rect();
+ for (size_t i = 0; i < affected_occlusion.GetRegionComplexity(); ++i) {
+ gfx::Rect occlusion_rect = affected_occlusion.GetRect(i);
// Shrink the rect by expanding the non-opaque pixels outside the rect.
@@ -309,7 +307,7 @@ void OcclusionTracker<LayerType>::LeaveToRenderTarget(
const typename LayerType::RenderSurfaceType* old_surface =
old_target->render_surface();
- Region old_occlusion_from_inside_target_in_new_target =
+ SimpleEnclosedRegion old_occlusion_from_inside_target_in_new_target =
TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
stack_[last_index].occlusion_from_inside_target,
old_surface->is_clipped(),
@@ -324,7 +322,7 @@ void OcclusionTracker<LayerType>::LeaveToRenderTarget(
old_surface->replica_draw_transform()));
}
- Region old_occlusion_from_outside_target_in_new_target =
+ SimpleEnclosedRegion old_occlusion_from_outside_target_in_new_target =
TransformSurfaceOpaqueRegion<typename LayerType::RenderSurfaceType>(
stack_[last_index].occlusion_from_outside_target,
false,
@@ -400,8 +398,6 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer(
const LayerType* layer) {
DCHECK(!stack_.empty());
DCHECK_EQ(layer->render_target(), stack_.back().target);
- if (stack_.empty())
- return;
if (!LayerOpacityKnown(layer) || layer->draw_opacity() < 1)
return;
@@ -415,7 +411,7 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer(
if (!LayerTransformsToTargetKnown(layer))
return;
- Region opaque_contents = layer->VisibleContentOpaqueRegion();
+ SimpleEnclosedRegion opaque_contents = layer->VisibleContentOpaqueRegion();
if (opaque_contents.IsEmpty())
return;
@@ -434,14 +430,12 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer(
layer->render_target()->render_surface()->content_rect());
}
- for (Region::Iterator opaque_content_rects(opaque_contents);
- opaque_content_rects.has_rect();
- opaque_content_rects.next()) {
+ for (size_t i = 0; i < opaque_contents.GetRegionComplexity(); ++i) {
bool clipped;
- gfx::QuadF transformed_quad = MathUtil::MapQuad(
- layer->draw_transform(),
- gfx::QuadF(opaque_content_rects.rect()),
- &clipped);
+ gfx::QuadF transformed_quad =
+ MathUtil::MapQuad(layer->draw_transform(),
+ gfx::QuadF(opaque_contents.GetRect(i)),
+ &clipped);
gfx::Rect transformed_rect =
gfx::ToEnclosedRect(transformed_quad.BoundingBox());
DCHECK(!clipped); // We only map if the transform preserves axis alignment.
@@ -468,8 +462,9 @@ void OcclusionTracker<LayerType>::MarkOccludedBehindLayer(
if (!non_occluding_screen_space_rects_)
return;
- Region non_opaque_contents =
- SubtractRegions(gfx::Rect(layer->content_bounds()), opaque_contents);
+ 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()) {
@@ -514,8 +509,9 @@ bool OcclusionTracker<LayerType>::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()) {
+ const StackObject& back = stack_.back();
+ if (back.occlusion_from_inside_target.IsEmpty() &&
+ back.occlusion_from_outside_target.IsEmpty()) {
return false;
}
@@ -525,17 +521,16 @@ bool OcclusionTracker<LayerType>::Occluded(
// 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::Rect unoccluded_rect_in_target_surface =
MathUtil::MapEnclosingClippedRect(draw_transform, content_rect);
- 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);
-
- gfx::RectF unoccluded_rect_in_target_surface =
- unoccluded_region_in_target_surface.bounds();
+ DCHECK_LE(back.occlusion_from_inside_target.GetRegionComplexity(), 1u);
+ DCHECK_LE(back.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(
+ stack_.back().occlusion_from_inside_target.bounds());
+ unoccluded_rect_in_target_surface.Subtract(
+ stack_.back().occlusion_from_outside_target.bounds());
return unoccluded_rect_in_target_surface.IsEmpty();
}
@@ -544,13 +539,13 @@ template <typename LayerType>
gfx::Rect OcclusionTracker<LayerType>::UnoccludedContentRect(
const gfx::Rect& content_rect,
const gfx::Transform& draw_transform) const {
- if (stack_.empty())
- return content_rect;
+ DCHECK(!stack_.empty());
if (content_rect.IsEmpty())
return content_rect;
- if (stack_.back().occlusion_from_inside_target.IsEmpty() &&
- stack_.back().occlusion_from_outside_target.IsEmpty()) {
+ const StackObject& back = stack_.back();
+ if (back.occlusion_from_inside_target.IsEmpty() &&
+ back.occlusion_from_outside_target.IsEmpty()) {
return content_rect;
}
@@ -560,18 +555,20 @@ gfx::Rect OcclusionTracker<LayerType>::UnoccludedContentRect(
// 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::Rect unoccluded_rect_in_target_surface =
MathUtil::MapEnclosingClippedRect(draw_transform, content_rect);
- unoccluded_region_in_target_surface.Subtract(
- stack_.back().occlusion_from_inside_target);
- unoccluded_region_in_target_surface.Subtract(
- stack_.back().occlusion_from_outside_target);
-
- if (unoccluded_region_in_target_surface.IsEmpty())
+ DCHECK_LE(back.occlusion_from_inside_target.GetRegionComplexity(), 1u);
+ DCHECK_LE(back.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(
+ back.occlusion_from_inside_target.bounds());
+ unoccluded_rect_in_target_surface.Subtract(
+ back.occlusion_from_outside_target.bounds());
+
+ if (unoccluded_rect_in_target_surface.IsEmpty())
return gfx::Rect();
- gfx::Rect unoccluded_rect_in_target_surface =
- unoccluded_region_in_target_surface.bounds();
gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect(
inverse_draw_transform, unoccluded_rect_in_target_surface);
unoccluded_rect.Intersect(content_rect);
@@ -594,7 +591,6 @@ gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect(
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;
@@ -605,18 +601,21 @@ gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect(
// 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::Rect unoccluded_rect_in_target_surface =
MathUtil::MapEnclosingClippedRect(draw_transform, content_rect);
- unoccluded_region_in_target_surface.Subtract(
- second_last.occlusion_from_inside_target);
- unoccluded_region_in_target_surface.Subtract(
- second_last.occlusion_from_outside_target);
-
- if (unoccluded_region_in_target_surface.IsEmpty())
+ 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_in_target_surface =
- unoccluded_region_in_target_surface.bounds();
gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect(
inverse_draw_transform, unoccluded_rect_in_target_surface);
unoccluded_rect.Intersect(content_rect);
@@ -624,6 +623,17 @@ gfx::Rect OcclusionTracker<LayerType>::UnoccludedContributingSurfaceContentRect(
return unoccluded_rect;
}
+template <typename LayerType>
+Region OcclusionTracker<LayerType>::ComputeVisibleRegionInScreen() const {
+ DCHECK(!stack_.back().target->parent());
+ const SimpleEnclosedRegion& occluded =
+ stack_.back().occlusion_from_inside_target;
+ Region visible_region(screen_space_clip_rect_);
+ for (size_t i = 0; i < occluded.GetRegionComplexity(); ++i)
+ visible_region.Subtract(occluded.GetRect(i));
+ return visible_region;
+}
+
// Instantiate (and export) templates here for the linker.
template class OcclusionTracker<Layer>;
template class OcclusionTracker<LayerImpl>;

Powered by Google App Engine
This is Rietveld 408576698