Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: ash/ash_root_window_transformer.cc

Issue 15730006: Use the source display's pixel size as a mirror window's size. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed comments Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/ash_root_window_transformer.h ('k') | ash/ash_root_window_transformer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 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.
4
5 #include "ash/ash_root_window_transformer.h"
6
7 #include <cmath>
8
9 #include "ash/display/display_info.h"
10 #include "ash/display/display_manager.h"
11 #include "ash/magnifier/magnification_controller.h"
12 #include "ash/shell.h"
13 #include "third_party/skia/include/utils/SkMatrix44.h"
14 #include "ui/aura/root_window.h"
15 #include "ui/aura/window_property.h"
16 #include "ui/compositor/dip_util.h"
17 #include "ui/gfx/display.h"
18 #include "ui/gfx/size_conversions.h"
19 #include "ui/gfx/transform.h"
20
21 DECLARE_WINDOW_PROPERTY_TYPE(gfx::Display::Rotation);
22
23 namespace ash {
24 namespace {
25
26 DEFINE_WINDOW_PROPERTY_KEY(gfx::Display::Rotation, kRotationPropertyKey,
27 gfx::Display::ROTATE_0);
28
29 // Round near zero value to zero.
30 void RoundNearZero(gfx::Transform* transform) {
31 const float kEpsilon = 0.001f;
32 SkMatrix44& matrix = transform->matrix();
33 for (int x = 0; x < 4; ++x) {
34 for (int y = 0; y < 4; ++y) {
35 if (std::abs(SkMScalarToFloat(matrix.get(x, y))) < kEpsilon)
36 matrix.set(x, y, SkFloatToMScalar(0.0f));
37 }
38 }
39 }
40
41 gfx::Transform CreateRotationTransform(aura::RootWindow* root_window,
42 const gfx::Display& display) {
43 internal::DisplayInfo info =
44 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
45
46 // TODO(oshima): Add animation. (crossfade+rotation, or just cross-fade)
47 #if defined(OS_WIN)
48 // Windows 8 bots refused to resize the host window, and
49 // updating the transform results in incorrectly resizing
50 // the root window. Don't apply the transform unless
51 // necessary so that unit tests pass on win8 bots.
52 if (info.rotation() == root_window->GetProperty(kRotationPropertyKey))
53 return gfx::Transform();
54 root_window->SetProperty(kRotationPropertyKey, info.rotation());
55 #endif
56
57 gfx::Transform rotate;
58 // The origin is (0, 0), so the translate width/height must be reduced by
59 // 1 pixel.
60 float one_pixel = 1.0f / display.device_scale_factor();
61 switch (info.rotation()) {
62 case gfx::Display::ROTATE_0:
63 break;
64 case gfx::Display::ROTATE_90:
65 rotate.Translate(display.bounds().height() - one_pixel, 0);
66 rotate.Rotate(90);
67 break;
68 case gfx::Display::ROTATE_270:
69 rotate.Translate(0, display.bounds().width() - one_pixel);
70 rotate.Rotate(270);
71 break;
72 case gfx::Display::ROTATE_180:
73 rotate.Translate(display.bounds().width() - one_pixel,
74 display.bounds().height() - one_pixel);
75 rotate.Rotate(180);
76 break;
77 }
78
79 RoundNearZero(&rotate);
80 return rotate;
81 }
82
83 gfx::Transform CreateMagnifierTransform(aura::RootWindow* root_window) {
84 MagnificationController* magnifier =
85 Shell::GetInstance()->magnification_controller();
86 float magnifier_scale = 1.f;
87 gfx::Point magnifier_offset;
88 if (magnifier && magnifier->IsEnabled()) {
89 magnifier_scale = magnifier->GetScale();
90 magnifier_offset = magnifier->GetWindowPosition();
91 }
92 gfx::Transform transform;
93 if (magnifier_scale != 1.f) {
94 transform.Scale(magnifier_scale, magnifier_scale);
95 transform.Translate(-magnifier_offset.x(), -magnifier_offset.y());
96 }
97 return transform;
98 }
99
100 gfx::Transform CreateOverscanAndUIScaleTransform(aura::RootWindow* root_window,
101 const gfx::Display& display) {
102 internal::DisplayInfo info =
103 Shell::GetInstance()->display_manager()->GetDisplayInfo(display.id());
104 gfx::Insets insets = info.GetOverscanInsetsInPixel();
105 float scale = info.ui_scale();
106
107 gfx::Transform transform;
108 if (insets.top() != 0 || insets.left() != 0) {
109 float device_scale_factor = ui::GetDeviceScaleFactor(root_window->layer());
110 float x_offset = insets.left() / device_scale_factor;
111 float y_offset = insets.top() / device_scale_factor;
112 transform.Translate(x_offset, y_offset);
113 }
114 float inverted_scale = 1.0f / scale;
115 transform.Scale(inverted_scale, inverted_scale);
116 return transform;
117 }
118
119 } // namespace
120
121 AshRootWindowTransformer::AshRootWindowTransformer(aura::RootWindow* root,
122 const gfx::Display& display)
123 : root_window_(root) {
124 root_window_bounds_transform_ =
125 CreateOverscanAndUIScaleTransform(root, display) *
126 CreateRotationTransform(root, display);
127 transform_ = root_window_bounds_transform_ * CreateMagnifierTransform(root);
128 CHECK(transform_.GetInverse(&invert_transform_));
129
130 internal::DisplayInfo info = Shell::GetInstance()->
131 display_manager()->GetDisplayInfo(display.id());
132 root_window_ui_scale_ = info.ui_scale();
133 host_insets_ = info.GetOverscanInsetsInPixel();
134 MagnificationController* magnifier =
135 Shell::GetInstance()->magnification_controller();
136
137 bool scaled = (root_window_ui_scale_ != 1.f) ||
138 (magnifier && magnifier->GetScale() != 1.f);
139 root_window_->layer()->SetForceRenderSurface(scaled);
140 }
141
142 AshRootWindowTransformer::~AshRootWindowTransformer() {}
143
144 gfx::Transform AshRootWindowTransformer::GetTransform() const {
145 return transform_;
146 }
147
148 gfx::Transform AshRootWindowTransformer::GetInverseTransform() const {
149 return invert_transform_;
150 }
151
152 gfx::Rect AshRootWindowTransformer::GetRootWindowBounds(
153 const gfx::Size& host_size) const {
154 gfx::Rect bounds(host_size);
155 bounds.Inset(host_insets_);
156 bounds = ui::ConvertRectToDIP(root_window_->layer(), bounds);
157 gfx::RectF new_bounds(bounds);
158 root_window_bounds_transform_.TransformRect(&new_bounds);
159 // Apply |root_window_scale_| twice as the downscaling
160 // is already applied once in |SetTransformInternal()|.
161 // TODO(oshima): This is a bit ugly. Consider specifying
162 // the pseudo host resolution instead.
163 new_bounds.Scale(root_window_ui_scale_ * root_window_ui_scale_);
164 // Ignore the origin because RootWindow's insets are handled by
165 // the transform.
166 // Floor the size because the bounds is no longer aligned to
167 // backing pixel when |root_window_scale_| is specified
168 // (850 height at 1.25 scale becomes 1062.5 for example.)
169 return gfx::Rect(gfx::ToFlooredSize(new_bounds.size()));
170 }
171
172 gfx::Insets AshRootWindowTransformer::GetHostInsets() const {
173 return host_insets_;
174 }
175
176 } // namespace ash
OLDNEW
« no previous file with comments | « ash/ash_root_window_transformer.h ('k') | ash/ash_root_window_transformer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698