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.
5 #include "cc/trees/occlusion.h"
7 #include "cc/base/math_util.h"
8 #include "ui/gfx/geometry/rect.h"
12 Occlusion::Occlusion() {
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
) {
23 Occlusion
Occlusion::GetOcclusionWithGivenDrawTransform(
24 const gfx::Transform
& transform
) const {
26 transform
, occlusion_from_outside_target_
, occlusion_from_inside_target_
);
29 bool Occlusion::HasOcclusion() const {
30 return !occlusion_from_inside_target_
.IsEmpty() ||
31 !occlusion_from_outside_target_
.IsEmpty();
34 bool Occlusion::IsOccluded(const gfx::Rect
& content_rect
) const {
35 if (content_rect
.IsEmpty())
41 gfx::Rect unoccluded_rect_in_target_surface
=
42 GetUnoccludedRectInTargetSurface(content_rect
);
43 return unoccluded_rect_in_target_surface
.IsEmpty();
46 gfx::Rect
Occlusion::GetUnoccludedContentRect(
47 const gfx::Rect
& content_rect
) const {
48 if (content_rect
.IsEmpty())
54 gfx::Rect unoccluded_rect_in_target_surface
=
55 GetUnoccludedRectInTargetSurface(content_rect
);
56 if (unoccluded_rect_in_target_surface
.IsEmpty())
59 gfx::Transform
inverse_draw_transform(gfx::Transform::kSkipInitialization
);
60 bool ok
= draw_transform_
.GetInverse(&inverse_draw_transform
);
61 // TODO(ajuma): Skip drawing layers with uninvertible draw transforms, and
62 // change this to a DCHECK. crbug.com/517170
66 gfx::Rect unoccluded_rect
= MathUtil::ProjectEnclosingClippedRect(
67 inverse_draw_transform
, unoccluded_rect_in_target_surface
);
68 unoccluded_rect
.Intersect(content_rect
);
70 return unoccluded_rect
;
73 gfx::Rect
Occlusion::GetUnoccludedRectInTargetSurface(
74 const gfx::Rect
& content_rect
) const {
75 // Take the ToEnclosingRect at each step, as we want to contain any unoccluded
76 // partial pixels in the resulting Rect.
77 gfx::Rect unoccluded_rect_in_target_surface
=
78 MathUtil::MapEnclosingClippedRect(draw_transform_
, content_rect
);
79 DCHECK_LE(occlusion_from_inside_target_
.GetRegionComplexity(), 1u);
80 DCHECK_LE(occlusion_from_outside_target_
.GetRegionComplexity(), 1u);
81 // These subtract operations are more lossy than if we did both operations at
83 unoccluded_rect_in_target_surface
.Subtract(
84 occlusion_from_inside_target_
.bounds());
85 unoccluded_rect_in_target_surface
.Subtract(
86 occlusion_from_outside_target_
.bounds());
88 return unoccluded_rect_in_target_surface
;
91 bool Occlusion::IsEqual(const Occlusion
& other
) const {
92 return draw_transform_
== other
.draw_transform_
&&
93 occlusion_from_inside_target_
== other
.occlusion_from_inside_target_
&&
94 occlusion_from_outside_target_
== other
.occlusion_from_outside_target_
;
97 std::string
Occlusion::ToString() const {
98 return draw_transform_
.ToString() + "outside(" +
99 occlusion_from_outside_target_
.ToString() + ") inside(" +
100 occlusion_from_inside_target_
.ToString() + ")";