Home | History | Annotate | Download | only in trees
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/trees/occlusion.h"
      6 
      7 #include "cc/base/math_util.h"
      8 #include "ui/gfx/rect.h"
      9 
     10 namespace cc {
     11 
     12 Occlusion::Occlusion() {
     13 }
     14 
     15 Occlusion::Occlusion(const gfx::Transform& draw_transform,
     16                      const SimpleEnclosedRegion& occlusion_from_outside_target,
     17                      const SimpleEnclosedRegion& occlusion_from_inside_target)
     18     : draw_transform_(draw_transform),
     19       occlusion_from_outside_target_(occlusion_from_outside_target),
     20       occlusion_from_inside_target_(occlusion_from_inside_target) {
     21 }
     22 
     23 bool Occlusion::IsOccluded(const gfx::Rect& content_rect) const {
     24   if (content_rect.IsEmpty())
     25     return true;
     26 
     27   if (occlusion_from_inside_target_.IsEmpty() &&
     28       occlusion_from_outside_target_.IsEmpty()) {
     29     return false;
     30   }
     31 
     32   gfx::Rect unoccluded_rect_in_target_surface =
     33       GetUnoccludedRectInTargetSurface(content_rect);
     34   return unoccluded_rect_in_target_surface.IsEmpty();
     35 }
     36 
     37 gfx::Rect Occlusion::GetUnoccludedContentRect(
     38     const gfx::Rect& content_rect) const {
     39   if (content_rect.IsEmpty())
     40     return content_rect;
     41 
     42   if (occlusion_from_inside_target_.IsEmpty() &&
     43       occlusion_from_outside_target_.IsEmpty()) {
     44     return content_rect;
     45   }
     46 
     47   gfx::Rect unoccluded_rect_in_target_surface =
     48       GetUnoccludedRectInTargetSurface(content_rect);
     49   if (unoccluded_rect_in_target_surface.IsEmpty())
     50     return gfx::Rect();
     51 
     52   gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization);
     53   bool ok = draw_transform_.GetInverse(&inverse_draw_transform);
     54   DCHECK(ok);
     55 
     56   gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect(
     57       inverse_draw_transform, unoccluded_rect_in_target_surface);
     58   unoccluded_rect.Intersect(content_rect);
     59 
     60   return unoccluded_rect;
     61 }
     62 
     63 gfx::Rect Occlusion::GetUnoccludedRectInTargetSurface(
     64     const gfx::Rect& content_rect) const {
     65   // Take the ToEnclosingRect at each step, as we want to contain any unoccluded
     66   // partial pixels in the resulting Rect.
     67   gfx::Rect unoccluded_rect_in_target_surface =
     68       MathUtil::MapEnclosingClippedRect(draw_transform_, content_rect);
     69   DCHECK_LE(occlusion_from_inside_target_.GetRegionComplexity(), 1u);
     70   DCHECK_LE(occlusion_from_outside_target_.GetRegionComplexity(), 1u);
     71   // These subtract operations are more lossy than if we did both operations at
     72   // once.
     73   unoccluded_rect_in_target_surface.Subtract(
     74       occlusion_from_inside_target_.bounds());
     75   unoccluded_rect_in_target_surface.Subtract(
     76       occlusion_from_outside_target_.bounds());
     77 
     78   return unoccluded_rect_in_target_surface;
     79 }
     80 
     81 }  // namespace cc
     82