| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/trees/occlusion.h" | 5 #include "cc/trees/occlusion.h" |
| 6 | 6 |
| 7 #include "cc/base/math_util.h" | 7 #include "cc/base/math_util.h" |
| 8 #include "cc/base/region.h" |
| 8 #include "ui/gfx/geometry/rect.h" | 9 #include "ui/gfx/geometry/rect.h" |
| 9 | 10 |
| 10 namespace cc { | 11 namespace cc { |
| 11 | 12 |
| 12 Occlusion::Occlusion() { | 13 Occlusion::Occlusion() { |
| 13 } | 14 } |
| 14 | 15 |
| 15 Occlusion::Occlusion(const gfx::Transform& draw_transform, | 16 Occlusion::Occlusion(const gfx::Transform& draw_transform, |
| 16 const SimpleEnclosedRegion& occlusion_from_outside_target, | 17 const SimpleEnclosedRegion& occlusion_from_outside_target, |
| 17 const SimpleEnclosedRegion& occlusion_from_inside_target) | 18 const SimpleEnclosedRegion& occlusion_from_inside_target) |
| 18 : draw_transform_(draw_transform), | 19 : draw_transform_(draw_transform), |
| 20 inverse_draw_transform_(gfx::Transform::kSkipInitialization), |
| 19 occlusion_from_outside_target_(occlusion_from_outside_target), | 21 occlusion_from_outside_target_(occlusion_from_outside_target), |
| 20 occlusion_from_inside_target_(occlusion_from_inside_target) { | 22 occlusion_from_inside_target_(occlusion_from_inside_target) {} |
| 21 } | |
| 22 | 23 |
| 23 Occlusion Occlusion::GetOcclusionWithGivenDrawTransform( | 24 Occlusion Occlusion::GetOcclusionWithGivenDrawTransform( |
| 24 const gfx::Transform& transform) const { | 25 const gfx::Transform& transform) const { |
| 25 return Occlusion( | 26 return Occlusion( |
| 26 transform, occlusion_from_outside_target_, occlusion_from_inside_target_); | 27 transform, occlusion_from_outside_target_, occlusion_from_inside_target_); |
| 27 } | 28 } |
| 28 | 29 |
| 29 bool Occlusion::HasOcclusion() const { | 30 bool Occlusion::HasOcclusion() const { |
| 30 return !occlusion_from_inside_target_.IsEmpty() || | 31 return !occlusion_from_inside_target_.IsEmpty() || |
| 31 !occlusion_from_outside_target_.IsEmpty(); | 32 !occlusion_from_outside_target_.IsEmpty(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 49 return content_rect; | 50 return content_rect; |
| 50 | 51 |
| 51 if (!HasOcclusion()) | 52 if (!HasOcclusion()) |
| 52 return content_rect; | 53 return content_rect; |
| 53 | 54 |
| 54 gfx::Rect unoccluded_rect_in_target_surface = | 55 gfx::Rect unoccluded_rect_in_target_surface = |
| 55 GetUnoccludedRectInTargetSurface(content_rect); | 56 GetUnoccludedRectInTargetSurface(content_rect); |
| 56 if (unoccluded_rect_in_target_surface.IsEmpty()) | 57 if (unoccluded_rect_in_target_surface.IsEmpty()) |
| 57 return gfx::Rect(); | 58 return gfx::Rect(); |
| 58 | 59 |
| 59 gfx::Transform inverse_draw_transform(gfx::Transform::kSkipInitialization); | 60 if (!inverse_transform_initialized_) { |
| 60 bool ok = draw_transform_.GetInverse(&inverse_draw_transform); | 61 bool ok = draw_transform_.GetInverse(&inverse_draw_transform_); |
| 61 // TODO(ajuma): Skip drawing layers with uninvertible draw transforms, and | 62 // TODO(ajuma): Skip drawing layers with uninvertible draw transforms, and |
| 62 // change this to a DCHECK. crbug.com/517170 | 63 // change this to a DCHECK. crbug.com/517170 |
| 63 if (!ok) | 64 if (!ok) |
| 64 return content_rect; | 65 return content_rect; |
| 66 inverse_transform_initialized_ = true; |
| 67 } |
| 65 | 68 |
| 66 gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( | 69 gfx::Rect unoccluded_rect = MathUtil::ProjectEnclosingClippedRect( |
| 67 inverse_draw_transform, unoccluded_rect_in_target_surface); | 70 inverse_draw_transform_, unoccluded_rect_in_target_surface); |
| 68 unoccluded_rect.Intersect(content_rect); | 71 unoccluded_rect.Intersect(content_rect); |
| 69 | 72 |
| 70 return unoccluded_rect; | 73 return unoccluded_rect; |
| 71 } | 74 } |
| 72 | 75 |
| 73 gfx::Rect Occlusion::GetUnoccludedRectInTargetSurface( | 76 gfx::Rect Occlusion::GetUnoccludedRectInTargetSurface( |
| 74 const gfx::Rect& content_rect) const { | 77 const gfx::Rect& content_rect) const { |
| 75 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded | 78 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded |
| 76 // partial pixels in the resulting Rect. | 79 // partial pixels in the resulting Rect. |
| 77 gfx::Rect unoccluded_rect_in_target_surface = | 80 gfx::Rect unoccluded_rect_in_target_surface = |
| 78 MathUtil::MapEnclosingClippedRect(draw_transform_, content_rect); | 81 MathUtil::MapEnclosingClippedRect(draw_transform_, content_rect); |
| 79 DCHECK_LE(occlusion_from_inside_target_.GetRegionComplexity(), 1u); | 82 DCHECK_LE(occlusion_from_inside_target_.GetRegionComplexity(), 1u); |
| 80 DCHECK_LE(occlusion_from_outside_target_.GetRegionComplexity(), 1u); | 83 DCHECK_LE(occlusion_from_outside_target_.GetRegionComplexity(), 1u); |
| 81 // These subtract operations are more lossy than if we did both operations at | 84 // These subtract operations are more lossy than if we did both operations at |
| 82 // once. | 85 // once. |
| 83 unoccluded_rect_in_target_surface.Subtract( | 86 unoccluded_rect_in_target_surface.Subtract( |
| 84 occlusion_from_inside_target_.bounds()); | 87 occlusion_from_inside_target_.bounds()); |
| 85 unoccluded_rect_in_target_surface.Subtract( | 88 unoccluded_rect_in_target_surface.Subtract( |
| 86 occlusion_from_outside_target_.bounds()); | 89 occlusion_from_outside_target_.bounds()); |
| 87 | 90 |
| 88 return unoccluded_rect_in_target_surface; | 91 return unoccluded_rect_in_target_surface; |
| 89 } | 92 } |
| 90 | 93 |
| 94 void Occlusion::OccludeContentRegion(Region* region) const { |
| 95 if (!draw_transform_.IsScaleOrTranslation()) |
| 96 return; |
| 97 |
| 98 if (!inverse_transform_initialized_) { |
| 99 bool ok = draw_transform_.GetInverse(&inverse_draw_transform_); |
| 100 if (!ok) |
| 101 return; |
| 102 inverse_transform_initialized_ = true; |
| 103 } |
| 104 |
| 105 if (!occlusion_from_inside_target_.IsEmpty()) { |
| 106 region->Subtract(MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( |
| 107 inverse_draw_transform_, occlusion_from_inside_target_.bounds())); |
| 108 } |
| 109 if (!occlusion_from_outside_target_.IsEmpty()) { |
| 110 region->Subtract(MathUtil::MapEnclosedRectWith2dAxisAlignedTransform( |
| 111 inverse_draw_transform_, occlusion_from_outside_target_.bounds())); |
| 112 } |
| 113 } |
| 114 |
| 91 bool Occlusion::IsEqual(const Occlusion& other) const { | 115 bool Occlusion::IsEqual(const Occlusion& other) const { |
| 92 return draw_transform_ == other.draw_transform_ && | 116 return draw_transform_ == other.draw_transform_ && |
| 93 occlusion_from_inside_target_ == other.occlusion_from_inside_target_ && | 117 occlusion_from_inside_target_ == other.occlusion_from_inside_target_ && |
| 94 occlusion_from_outside_target_ == other.occlusion_from_outside_target_; | 118 occlusion_from_outside_target_ == other.occlusion_from_outside_target_; |
| 95 } | 119 } |
| 96 | 120 |
| 97 std::string Occlusion::ToString() const { | 121 std::string Occlusion::ToString() const { |
| 98 return draw_transform_.ToString() + "outside(" + | 122 return draw_transform_.ToString() + "outside(" + |
| 99 occlusion_from_outside_target_.ToString() + ") inside(" + | 123 occlusion_from_outside_target_.ToString() + ") inside(" + |
| 100 occlusion_from_inside_target_.ToString() + ")"; | 124 occlusion_from_inside_target_.ToString() + ")"; |
| 101 } | 125 } |
| 102 | 126 |
| 103 } // namespace cc | 127 } // namespace cc |
| OLD | NEW |