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
),
41 use_output_surface_for_resource(false),
44 overlay_handled(false) {}
46 OverlayCandidate::~OverlayCandidate() {}
49 gfx::OverlayTransform
OverlayCandidate::GetOverlayTransform(
50 const gfx::Transform
& quad_transform
,
52 if (!quad_transform
.Preserves2dAxisAlignment()) {
53 return gfx::OVERLAY_TRANSFORM_INVALID
;
56 gfx::Vector3dF x_axis
= MathUtil::GetXAxis(quad_transform
);
57 gfx::Vector3dF y_axis
= MathUtil::GetYAxis(quad_transform
);
62 Axis x_to
= VectorToAxis(x_axis
);
63 Axis y_to
= VectorToAxis(y_axis
);
65 if (x_to
== AXIS_POS_X
&& y_to
== AXIS_POS_Y
)
66 return gfx::OVERLAY_TRANSFORM_NONE
;
67 else if (x_to
== AXIS_NEG_X
&& y_to
== AXIS_POS_Y
)
68 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
69 else if (x_to
== AXIS_POS_X
&& y_to
== AXIS_NEG_Y
)
70 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
71 else if (x_to
== AXIS_NEG_Y
&& y_to
== AXIS_POS_X
)
72 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
73 else if (x_to
== AXIS_NEG_X
&& y_to
== AXIS_NEG_Y
)
74 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
75 else if (x_to
== AXIS_POS_Y
&& y_to
== AXIS_NEG_X
)
76 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
78 return gfx::OVERLAY_TRANSFORM_INVALID
;
82 gfx::OverlayTransform
OverlayCandidate::ModifyTransform(
83 gfx::OverlayTransform in
,
84 gfx::OverlayTransform delta
) {
85 // There are 8 different possible transforms. We can characterize these
86 // by looking at where the origin moves and the direction the horizontal goes.
87 // (TL=top-left, BR=bottom-right, H=horizontal, V=vertical).
89 // FLIP_VERTICAL: BL, H
90 // FLIP_HORIZONTAL: TR, H
94 // Missing transforms: TL, V & BR, V
95 // Basic combinations:
96 // Flip X & Y -> Rotate 180 (TL,H -> TR,H -> BR,H or TL,H -> BL,H -> BR,H)
97 // Flip X or Y + Rotate 180 -> other flip (eg, TL,H -> TR,H -> BL,H)
98 // Rotate + Rotate simply adds values.
99 // Rotate 90/270 + flip is invalid because we can only have verticals with
100 // the origin in TR or BL.
101 if (delta
== gfx::OVERLAY_TRANSFORM_NONE
)
104 case gfx::OVERLAY_TRANSFORM_NONE
:
106 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
108 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
109 return gfx::OVERLAY_TRANSFORM_NONE
;
110 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
111 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
112 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
113 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
115 return gfx::OVERLAY_TRANSFORM_INVALID
;
118 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
120 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
121 return gfx::OVERLAY_TRANSFORM_NONE
;
122 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
123 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
124 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
125 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
126 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
127 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
129 return gfx::OVERLAY_TRANSFORM_INVALID
;
132 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
134 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
135 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
136 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
137 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
138 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
139 return gfx::OVERLAY_TRANSFORM_NONE
;
141 return gfx::OVERLAY_TRANSFORM_INVALID
;
144 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
146 case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
:
147 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
;
148 case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
:
149 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL
;
150 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
151 return gfx::OVERLAY_TRANSFORM_ROTATE_270
;
152 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
153 return gfx::OVERLAY_TRANSFORM_NONE
;
154 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
155 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
157 return gfx::OVERLAY_TRANSFORM_INVALID
;
160 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
162 case gfx::OVERLAY_TRANSFORM_ROTATE_90
:
163 return gfx::OVERLAY_TRANSFORM_NONE
;
164 case gfx::OVERLAY_TRANSFORM_ROTATE_180
:
165 return gfx::OVERLAY_TRANSFORM_ROTATE_90
;
166 case gfx::OVERLAY_TRANSFORM_ROTATE_270
:
167 return gfx::OVERLAY_TRANSFORM_ROTATE_180
;
169 return gfx::OVERLAY_TRANSFORM_INVALID
;
173 return gfx::OVERLAY_TRANSFORM_INVALID
;
178 gfx::RectF
OverlayCandidate::GetOverlayRect(
179 const gfx::Transform
& quad_transform
,
180 const gfx::Rect
& rect
) {
181 DCHECK(quad_transform
.Preserves2dAxisAlignment());
183 gfx::RectF
float_rect(rect
);
184 quad_transform
.TransformRect(&float_rect
);