1 // Copyright 2014 Intel Corporation. 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 "ozone/wayland/proxy_display.h"
7 #include "ozone/ui/events/event_factory_ozone_wayland.h"
8 #include "ozone/ui/events/output_change_observer.h"
9 #include "ozone/wayland/screen.h"
11 namespace ozonewayland {
13 WaylandProxyDisplay::WaylandProxyDisplay(): screen_(NULL) {
14 ui::OzoneDisplay::SetInstance(this);
17 WaylandProxyDisplay::~WaylandProxyDisplay() {
20 // TODO(vignatti): GPU process conceptually is the one that deals with hardware
21 // details and therefore we assume that the window system connection should
22 // happen in there only. There's a glitch with Chrome though, that creates its
23 // frame contents requiring access to the window system, before the GPU process
24 // even exists. In other words, Chrome runs
25 // BrowserMainLoop::PreMainMessageLoopRun before GpuProcessHost::Get. If the
26 // assumption of window system connection belongs to the GPU process is valid,
27 // then I believe this Chrome behavior needs to be addressed upstream.
29 // For now, we create another window system connection to look ahead the needed
30 // output properties that Chrome (among others) need and then close right after
31 // that. I haven't measured how long it takes to open a Wayland connection,
32 // listen all the interface the compositor sends and close it, but _for_ _sure_
33 // it slows down the overall initialization time of Chromium targets.
34 // Therefore, this is something that has to be solved in the future, moving all
35 // Chrome tasks after GPU process is created.
37 void WaylandProxyDisplay::LookAheadOutputGeometry() {
38 wl_display* display = wl_display_connect(NULL);
42 static const struct wl_registry_listener registry_output = {
43 WaylandProxyDisplay::DisplayHandleOutputOnly
46 wl_registry* registry = wl_display_get_registry(display);
47 wl_registry_add_listener(registry, ®istry_output, this);
49 if (wl_display_roundtrip(display) > 0) {
50 while (screen_->Geometry().IsEmpty())
51 wl_display_roundtrip(display);
53 ui::EventFactoryOzoneWayland* event_factory =
54 ui::EventFactoryOzoneWayland::GetInstance();
55 DCHECK(event_factory->GetOutputChangeObserver());
57 unsigned width = screen_->Geometry().width();
58 unsigned height = screen_->Geometry().height();
59 event_factory->GetOutputChangeObserver()->OnOutputSizeChanged(width,
68 wl_registry_destroy(registry);
69 wl_display_flush(display);
70 wl_display_disconnect(display);
74 void WaylandProxyDisplay::DisplayHandleOutputOnly(void *data,
75 struct wl_registry *registry,
77 const char *interface,
79 WaylandProxyDisplay* disp = static_cast<WaylandProxyDisplay*>(data);
81 if (strcmp(interface, "wl_output") == 0) {
82 WaylandScreen* screen = new WaylandScreen(registry, name);
83 disp->screen_ = screen;
87 } // namespace ozonewayland