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