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/output/overlay_candidate.h"
9 #include "base/logging.h"
10 #include "cc/base/math_util.h"
11 #include "ui/gfx/geometry/rect_conversions.h"
12 #include "ui/gfx/geometry/vector3d_f.h"
17 // Tolerance for considering axis vector elements to be zero.
18 const SkMScalar kEpsilon
= std::numeric_limits
<float>::epsilon();
20 enum Axis
{ NONE
, AXIS_POS_X
, AXIS_NEG_X
, AXIS_POS_Y
, AXIS_NEG_Y
};
22 Axis
VectorToAxis(const gfx::Vector3dF
& vec
) {
23 if (std::abs(vec
.z()) > kEpsilon
)
25 const bool x_zero
= (std::abs(vec
.x()) <= kEpsilon
);
26 const bool y_zero
= (std::abs(vec
.y()) <= kEpsilon
);
27 if (x_zero
&& !y_zero
)
28 return (vec
.y() > 0) ? AXIS_POS_Y
: AXIS_NEG_Y
;
29 else if (y_zero
&& !x_zero
)
30 return (vec
.x() > 0) ? AXIS_POS_X
: AXIS_NEG_X
;
37 OverlayCandidate::OverlayCandidate()
38 : transform(gfx::OVERLAY_TRANSFORM_NONE
),
40 uv_rect(0.f
, 0.f
, 1.f
, 1.f
),
43 overlay_handled(false) {}
45 OverlayCandidate::~OverlayCandidate() {}
48 gfx::OverlayTransform
OverlayCandidate::GetOverlayTransform(
49 const gfx::Transform
& quad_transform
,
51 if (!quad_transform
.Preserves2dAxisAlignment()) {
52 return gfx::OVERLAY_TRANSFORM_INVALID
;
55 gfx::Vector3dF x_axis
= MathUtil::GetXAxis(quad_transform
);
56 gfx::Vector3dF y_axis
= MathUtil::GetYAxis(quad_transform
);
61 Axis x_to
= VectorToAxis(x_axis
);
62 Axis y_to
= VectorToAxis(y_axis
);
64 if (x_to
== AXIS_POS_X
&& y_to
== AXIS_POS_Y
)
65 return gfx::OVERLAY_TRANSFORM_NONE
;
66 else if (x_to
== AXIS_NEG_X
&& y_to
== AXIS_POS_Y
)
67 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
68 else if (x_to
== AXIS_POS_X
&& y_to
== AXIS_NEG_Y
)
69 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
70 else if (x_to
== AXIS_NEG_Y
&& y_to
== AXIS_POS_X
)
71 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
72 else if (x_to
== AXIS_NEG_X
&& y_to
== AXIS_NEG_Y
)
73 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
74 else if (x_to
== AXIS_POS_Y
&& y_to
== AXIS_NEG_X
)
75 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
77 return gfx::OVERLAY_TRANSFORM_INVALID
;
81 gfx::OverlayTransform
OverlayCandidate::ModifyTransform(
82 gfx::OverlayTransform in
,
83 gfx::OverlayTransform delta
) {
84 // There are 8 different possible transforms. We can characterize these
85 // by looking at where the origin moves and the direction the horizontal goes.
86 // (TL=top-left, BR=bottom-right, H=horizontal, V=vertical).
88 // FLIP_VERTICAL: BL, H
89 // FLIP_HORIZONTAL: TR, H
93 // Missing transforms: TL, V & BR, V
94 // Basic combinations:
95 // Flip X & Y -> Rotate 180 (TL,H -> TR,H -> BR,H or TL,H -> BL,H -> BR,H)
96 // Flip X or Y + Rotate 180 -> other flip (eg, TL,H -> TR,H -> BL,H)
97 // Rotate + Rotate simply adds values.
98 // Rotate 90/270 + flip is invalid because we can only have verticals with
99 // the origin in TR or BL.
100 if (delta
== gfx::OVERLAY_TRANSFORM_NONE
)
103 case gfx::OVERLAY_TRANSFORM_NONE
:
105 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
107 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
108 return gfx::OVERLAY_TRANSFORM_NONE
;
109 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
110 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
111 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
112 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
114 return gfx::OVERLAY_TRANSFORM_INVALID
;
117 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
119 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
120 return gfx::OVERLAY_TRANSFORM_NONE
;
121 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
122 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
123 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
124 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
125 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
126 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
128 return gfx::OVERLAY_TRANSFORM_INVALID
;
131 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
133 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
134 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
135 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
136 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
137 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
138 return gfx::OVERLAY_TRANSFORM_NONE
;
140 return gfx::OVERLAY_TRANSFORM_INVALID
;
143 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
145 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
146 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
147 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
148 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
149 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
150 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
151 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
152 return gfx::OVERLAY_TRANSFORM_NONE
;
153 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
154 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
156 return gfx::OVERLAY_TRANSFORM_INVALID
;
159 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
161 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
162 return gfx::OVERLAY_TRANSFORM_NONE
;
163 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
164 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
165 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
166 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
168 return gfx::OVERLAY_TRANSFORM_INVALID
;
172 return gfx::OVERLAY_TRANSFORM_INVALID
;
177 gfx::RectF
OverlayCandidate::GetOverlayRect(
178 const gfx::Transform
& quad_transform
,
179 const gfx::Rect
& rect
) {
180 DCHECK(quad_transform
.Preserves2dAxisAlignment());
182 gfx::RectF
float_rect(rect
);
183 quad_transform
.TransformRect(&float_rect
);