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

Side by Side Diff: components/mus/display_manager.cc

Issue 1377493002: mus: move View Manager to components/mus/vm (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 5 years, 2 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
« no previous file with comments | « components/mus/display_manager.h ('k') | components/mus/display_manager_delegate.h » ('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 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.
4
5 #include "components/mus/display_manager.h"
6
7 #include "base/numerics/safe_conversions.h"
8 #include "cc/output/compositor_frame.h"
9 #include "cc/output/delegated_frame_data.h"
10 #include "cc/quads/render_pass.h"
11 #include "cc/quads/shared_quad_state.h"
12 #include "cc/quads/surface_draw_quad.h"
13 #include "components/mus/display_manager_factory.h"
14 #include "components/mus/gles2/gpu_state.h"
15 #include "components/mus/public/interfaces/gpu.mojom.h"
16 #include "components/mus/public/interfaces/quads.mojom.h"
17 #include "components/mus/server_view.h"
18 #include "components/mus/surfaces/surfaces_state.h"
19 #include "components/mus/view_coordinate_conversions.h"
20 #include "mojo/application/public/cpp/application_connection.h"
21 #include "mojo/application/public/cpp/application_impl.h"
22 #include "mojo/converters/geometry/geometry_type_converters.h"
23 #include "mojo/converters/input_events/input_events_type_converters.h"
24 #include "mojo/converters/input_events/mojo_extended_key_event_data.h"
25 #include "mojo/converters/surfaces/surfaces_type_converters.h"
26 #include "mojo/converters/surfaces/surfaces_utils.h"
27 #include "mojo/converters/transform/transform_type_converters.h"
28 #include "third_party/skia/include/core/SkXfermode.h"
29 #include "ui/events/event.h"
30 #include "ui/events/event_utils.h"
31 #include "ui/gfx/display.h"
32 #include "ui/platform_window/platform_ime_controller.h"
33 #include "ui/platform_window/platform_window.h"
34
35 #if defined(OS_WIN)
36 #include "ui/platform_window/win/win_window.h"
37 #elif defined(USE_X11)
38 #include "ui/platform_window/x11/x11_window.h"
39 #elif defined(OS_ANDROID)
40 #include "ui/platform_window/android/platform_window_android.h"
41 #endif
42
43 using mojo::Rect;
44 using mojo::Size;
45
46 namespace mus {
47 namespace {
48
49 // DrawViewTree recursively visits ServerViews, creating a SurfaceDrawQuad for
50 // each that lacks one. For Views that already have CompositorFrames, we can
51 // skip this step and let cc::SurfaceAggregator do the heavy lifting.
52 // |skip_view| indicates whether or not we should generate a SurfaceDrawQuad
53 // for the provided |view|.
54 void DrawViewTree(cc::RenderPass* pass,
55 const ServerView* view,
56 const gfx::Vector2d& parent_to_root_origin_offset,
57 float opacity,
58 bool skip_view) {
59 if (!view->visible())
60 return;
61
62 const gfx::Rect absolute_bounds =
63 view->bounds() + parent_to_root_origin_offset;
64
65 std::vector<const ServerView*> children(view->GetChildren());
66 // TODO(rjkroege, fsamuel): Make sure we're handling alpha correctly.
67 const float combined_opacity = opacity * view->opacity();
68 for (auto it = children.rbegin(); it != children.rend(); ++it) {
69 DrawViewTree(pass, *it, absolute_bounds.OffsetFromOrigin(),
70 combined_opacity,
71 view->parent() &&
72 !view->surface_id().is_null() /* skip_view */);
73 }
74
75 if (skip_view || view->surface_id().is_null())
76 return;
77
78 gfx::Transform quad_to_target_transform;
79 quad_to_target_transform.Translate(absolute_bounds.x(), absolute_bounds.y());
80 gfx::Rect bounds_at_origin(view->bounds().size());
81
82 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
83 // TODO(fsamuel): These clipping and visible rects are incorrect. They need
84 // to be populated from CompositorFrame structs.
85 sqs->SetAll(
86 quad_to_target_transform, bounds_at_origin.size() /* layer_bounds */,
87 bounds_at_origin /* visible_layer_bounds */,
88 bounds_at_origin /* clip_rect */, false /* is_clipped */, view->opacity(),
89 SkXfermode::kSrc_Mode, 0 /* sorting-context_id */);
90
91 auto surface_quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
92 surface_quad->SetNew(sqs, bounds_at_origin /* rect */,
93 bounds_at_origin /* visible_rect */, view->surface_id());
94 }
95
96 } // namespace
97
98 // static
99 DisplayManagerFactory* DisplayManager::factory_ = nullptr;
100
101 // static
102 DisplayManager* DisplayManager::Create(
103 mojo::ApplicationImpl* app_impl,
104 const scoped_refptr<GpuState>& gpu_state,
105 const scoped_refptr<SurfacesState>& surfaces_state) {
106 if (factory_) {
107 return factory_->CreateDisplayManager(app_impl, gpu_state,
108 surfaces_state);
109 }
110 return new DefaultDisplayManager(app_impl, gpu_state,
111 surfaces_state);
112 }
113
114 DefaultDisplayManager::DefaultDisplayManager(
115 mojo::ApplicationImpl* app_impl,
116 const scoped_refptr<GpuState>& gpu_state,
117 const scoped_refptr<SurfacesState>& surfaces_state)
118 : app_impl_(app_impl),
119 gpu_state_(gpu_state),
120 surfaces_state_(surfaces_state),
121 delegate_(nullptr),
122 draw_timer_(false, false),
123 frame_pending_(false),
124 weak_factory_(this) {
125 metrics_.size_in_pixels = mojo::Size::New();
126 metrics_.size_in_pixels->width = 800;
127 metrics_.size_in_pixels->height = 600;
128 }
129
130 void DefaultDisplayManager::Init(DisplayManagerDelegate* delegate) {
131 delegate_ = delegate;
132
133 gfx::Rect bounds(metrics_.size_in_pixels.To<gfx::Size>());
134 #if defined(OS_WIN)
135 platform_window_.reset(new ui::WinWindow(this, bounds));
136 #elif defined(USE_X11)
137 platform_window_.reset(new ui::X11Window(this));
138 #elif defined(OS_ANDROID)
139 platform_window_.reset(new ui::PlatformWindowAndroid(this));
140 #else
141 NOTREACHED() << "Unsupported platform";
142 #endif
143 platform_window_->SetBounds(bounds);
144 platform_window_->Show();
145 }
146
147 DefaultDisplayManager::~DefaultDisplayManager() {
148 delegate_->OnTopLevelSurfaceChanged(cc::SurfaceId());
149 // Invalidate WeakPtrs now to avoid callbacks back into the
150 // DefaultDisplayManager during destruction of |top_level_display_client_|.
151 weak_factory_.InvalidateWeakPtrs();
152 top_level_display_client_.reset();
153 // Destroy the PlatformWindow early on as it may call us back during
154 // destruction and we want to be in a known state. But destroy the surface
155 // first because it can still be using the platform window.
156 platform_window_.reset();
157 }
158
159 void DefaultDisplayManager::SchedulePaint(const ServerView* view,
160 const gfx::Rect& bounds) {
161 DCHECK(view);
162 if (!view->IsDrawn())
163 return;
164 const gfx::Rect root_relative_rect =
165 ConvertRectBetweenViews(view, delegate_->GetRootView(), bounds);
166 if (root_relative_rect.IsEmpty())
167 return;
168 dirty_rect_.Union(root_relative_rect);
169 WantToDraw();
170 }
171
172 void DefaultDisplayManager::SetViewportSize(const gfx::Size& size) {
173 platform_window_->SetBounds(gfx::Rect(size));
174 }
175
176 void DefaultDisplayManager::SetTitle(const base::string16& title) {
177 platform_window_->SetTitle(title);
178 }
179
180 const mojo::ViewportMetrics& DefaultDisplayManager::GetViewportMetrics() {
181 return metrics_;
182 }
183
184 void DefaultDisplayManager::UpdateTextInputState(
185 const ui::TextInputState& state) {
186 ui::PlatformImeController* ime = platform_window_->GetPlatformImeController();
187 if (ime)
188 ime->UpdateTextInputState(state);
189 }
190
191 void DefaultDisplayManager::SetImeVisibility(bool visible) {
192 ui::PlatformImeController* ime = platform_window_->GetPlatformImeController();
193 if (ime)
194 ime->SetImeVisibility(visible);
195 }
196
197 void DefaultDisplayManager::Draw() {
198 if (!delegate_->GetRootView()->visible())
199 return;
200
201 // TODO(fsamuel): We should add a trace for generating a top level frame.
202 scoped_ptr<cc::CompositorFrame> frame(GenerateCompositorFrame());
203 frame_pending_ = true;
204 if (top_level_display_client_) {
205 top_level_display_client_->SubmitCompositorFrame(
206 frame.Pass(), base::Bind(&DefaultDisplayManager::DidDraw,
207 weak_factory_.GetWeakPtr()));
208 }
209 dirty_rect_ = gfx::Rect();
210 }
211
212 void DefaultDisplayManager::DidDraw() {
213 frame_pending_ = false;
214 if (!dirty_rect_.IsEmpty())
215 WantToDraw();
216 }
217
218 void DefaultDisplayManager::WantToDraw() {
219 if (draw_timer_.IsRunning() || frame_pending_)
220 return;
221
222 draw_timer_.Start(
223 FROM_HERE, base::TimeDelta(),
224 base::Bind(&DefaultDisplayManager::Draw, weak_factory_.GetWeakPtr()));
225 }
226
227 void DefaultDisplayManager::UpdateMetrics(const gfx::Size& size,
228 float device_pixel_ratio) {
229 if (gfx::Display::HasForceDeviceScaleFactor())
230 device_pixel_ratio = gfx::Display::GetForcedDeviceScaleFactor();
231 if (metrics_.size_in_pixels.To<gfx::Size>() == size &&
232 metrics_.device_pixel_ratio == device_pixel_ratio)
233 return;
234 mojo::ViewportMetrics old_metrics;
235 old_metrics.size_in_pixels = metrics_.size_in_pixels.Clone();
236 old_metrics.device_pixel_ratio = metrics_.device_pixel_ratio;
237
238 metrics_.size_in_pixels = mojo::Size::From(size);
239 metrics_.device_pixel_ratio = device_pixel_ratio;
240
241 delegate_->OnViewportMetricsChanged(old_metrics, metrics_);
242 }
243
244 scoped_ptr<cc::CompositorFrame>
245 DefaultDisplayManager::GenerateCompositorFrame() {
246 scoped_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
247 render_pass->damage_rect = dirty_rect_;
248 render_pass->output_rect = gfx::Rect(metrics_.size_in_pixels.To<gfx::Size>());
249
250 DrawViewTree(render_pass.get(),
251 delegate_->GetRootView(),
252 gfx::Vector2d(), 1.0f,
253 false /* skip_view */);
254
255 scoped_ptr<cc::DelegatedFrameData> frame_data(new cc::DelegatedFrameData);
256 frame_data->device_scale_factor = metrics_.device_pixel_ratio;
257 frame_data->render_pass_list.push_back(render_pass.Pass());
258
259 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
260 frame->delegated_frame_data = frame_data.Pass();
261 return frame.Pass();
262 }
263
264 void DefaultDisplayManager::OnBoundsChanged(const gfx::Rect& new_bounds) {
265 UpdateMetrics(new_bounds.size(), metrics_.device_pixel_ratio);
266 }
267
268 void DefaultDisplayManager::OnDamageRect(const gfx::Rect& damaged_region) {
269 dirty_rect_.Union(damaged_region);
270 WantToDraw();
271 }
272
273 void DefaultDisplayManager::DispatchEvent(ui::Event* event) {
274 mojo::EventPtr mojo_event(mojo::Event::From(*event));
275 delegate_->OnEvent(mojo_event.Pass());
276
277 switch (event->type()) {
278 case ui::ET_MOUSE_PRESSED:
279 case ui::ET_TOUCH_PRESSED:
280 platform_window_->SetCapture();
281 break;
282 case ui::ET_MOUSE_RELEASED:
283 case ui::ET_TOUCH_RELEASED:
284 platform_window_->ReleaseCapture();
285 break;
286 default:
287 break;
288 }
289
290 #if defined(USE_X11)
291 // We want to emulate the WM_CHAR generation behaviour of Windows.
292 //
293 // On Linux, we've previously inserted characters by having
294 // InputMethodAuraLinux take all key down events and send a character event
295 // to the TextInputClient. This causes a mismatch in code that has to be
296 // shared between Windows and Linux, including blink code. Now that we're
297 // trying to have one way of doing things, we need to standardize on and
298 // emulate Windows character events.
299 //
300 // This is equivalent to what we're doing in the current Linux port, but
301 // done once instead of done multiple times in different places.
302 if (event->type() == ui::ET_KEY_PRESSED) {
303 ui::KeyEvent* key_press_event = static_cast<ui::KeyEvent*>(event);
304 ui::KeyEvent char_event(key_press_event->GetCharacter(),
305 key_press_event->key_code(),
306 key_press_event->flags());
307
308 DCHECK_EQ(key_press_event->GetCharacter(), char_event.GetCharacter());
309 DCHECK_EQ(key_press_event->key_code(), char_event.key_code());
310 DCHECK_EQ(key_press_event->flags(), char_event.flags());
311
312 char_event.SetExtendedKeyEventData(
313 make_scoped_ptr(new mojo::MojoExtendedKeyEventData(
314 key_press_event->GetLocatedWindowsKeyboardCode(),
315 key_press_event->GetText(), key_press_event->GetUnmodifiedText())));
316
317 delegate_->OnEvent(mojo::Event::From(char_event));
318 }
319 #endif
320 }
321
322 void DefaultDisplayManager::OnCloseRequest() {
323 platform_window_->Close();
324 }
325
326 void DefaultDisplayManager::OnClosed() {
327 delegate_->OnDisplayClosed();
328 }
329
330 void DefaultDisplayManager::OnWindowStateChanged(
331 ui::PlatformWindowState new_state) {}
332
333 void DefaultDisplayManager::OnLostCapture() {}
334
335 void DefaultDisplayManager::OnAcceleratedWidgetAvailable(
336 gfx::AcceleratedWidget widget,
337 float device_pixel_ratio) {
338 if (widget != gfx::kNullAcceleratedWidget) {
339 top_level_display_client_.reset(
340 new TopLevelDisplayClient(widget, gpu_state_, surfaces_state_));
341 delegate_->OnTopLevelSurfaceChanged(
342 top_level_display_client_->surface_id());
343 }
344 UpdateMetrics(metrics_.size_in_pixels.To<gfx::Size>(), device_pixel_ratio);
345 }
346
347 void DefaultDisplayManager::OnActivationChanged(bool active) {}
348
349 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/display_manager.h ('k') | components/mus/display_manager_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698