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
),
42 use_output_surface_for_resource(false),
45 overlay_handled(false) {}
47 OverlayCandidate::~OverlayCandidate() {}
50 gfx::OverlayTransform
OverlayCandidate::GetOverlayTransform(
51 const gfx::Transform
& quad_transform
,
53 if (!quad_transform
.Preserves2dAxisAlignment()) {
54 return gfx::OVERLAY_TRANSFORM_INVALID
;
57 gfx::Vector3dF x_axis
= MathUtil::GetXAxis(quad_transform
);
58 gfx::Vector3dF y_axis
= MathUtil::GetYAxis(quad_transform
);
63 Axis x_to
= VectorToAxis(x_axis
);
64 Axis y_to
= VectorToAxis(y_axis
);
66 if (x_to
== AXIS_POS_X
&& y_to
== AXIS_POS_Y
)
67 return gfx::OVERLAY_TRANSFORM_NONE
;
68 else if (x_to
== AXIS_NEG_X
&& y_to
== AXIS_POS_Y
)
69 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
70 else if (x_to
== AXIS_POS_X
&& y_to
== AXIS_NEG_Y
)
71 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
72 else if (x_to
== AXIS_NEG_Y
&& y_to
== AXIS_POS_X
)
73 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
74 else if (x_to
== AXIS_NEG_X
&& y_to
== AXIS_NEG_Y
)
75 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
76 else if (x_to
== AXIS_POS_Y
&& y_to
== AXIS_NEG_X
)
77 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
79 return gfx::OVERLAY_TRANSFORM_INVALID
;
83 gfx::OverlayTransform
OverlayCandidate::ModifyTransform(
84 gfx::OverlayTransform in
,
85 gfx::OverlayTransform delta
) {
86 // There are 8 different possible transforms. We can characterize these
87 // by looking at where the origin moves and the direction the horizontal goes.
88 // (TL=top-left, BR=bottom-right, H=horizontal, V=vertical).
90 // FLIP_VERTICAL: BL, H
91 // FLIP_HORIZONTAL: TR, H
95 // Missing transforms: TL, V & BR, V
96 // Basic combinations:
97 // Flip X & Y -> Rotate 180 (TL,H -> TR,H -> BR,H or TL,H -> BL,H -> BR,H)
98 // Flip X or Y + Rotate 180 -> other flip (eg, TL,H -> TR,H -> BL,H)
99 // Rotate + Rotate simply adds values.
100 // Rotate 90/270 + flip is invalid because we can only have verticals with
101 // the origin in TR or BL.
102 if (delta
== gfx::OVERLAY_TRANSFORM_NONE
)
105 case gfx::OVERLAY_TRANSFORM_NONE
:
107 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
109 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
110 return gfx::OVERLAY_TRANSFORM_NONE
;
111 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
112 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
113 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
114 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
116 return gfx::OVERLAY_TRANSFORM_INVALID
;
119 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
121 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
122 return gfx::OVERLAY_TRANSFORM_NONE
;
123 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
124 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
125 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
126 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
127 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
128 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
130 return gfx::OVERLAY_TRANSFORM_INVALID
;
133 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
135 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
136 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
137 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
138 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
139 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
140 return gfx::OVERLAY_TRANSFORM_NONE
;
142 return gfx::OVERLAY_TRANSFORM_INVALID
;
145 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
147 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
148 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
149 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
150 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
151 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
152 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
153 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
154 return gfx::OVERLAY_TRANSFORM_NONE
;
155 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
156 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
158 return gfx::OVERLAY_TRANSFORM_INVALID
;
161 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
163 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
164 return gfx::OVERLAY_TRANSFORM_NONE
;
165 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
166 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
167 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
168 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
170 return gfx::OVERLAY_TRANSFORM_INVALID
;
174 return gfx::OVERLAY_TRANSFORM_INVALID
;
179 gfx::RectF
OverlayCandidate::GetOverlayRect(
180 const gfx::Transform
& quad_transform
,
181 const gfx::Rect
& rect
) {
182 DCHECK(quad_transform
.Preserves2dAxisAlignment());
184 gfx::RectF
float_rect(rect
);
185 quad_transform
.TransformRect(&float_rect
);