[go: nahoru, domu]

blob: 1977457eafa1388c23864ed2104d1f7f28180524 [file] [log] [blame]
spang@chromium.org85905ed2014-07-24 18:48:411// 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
martina.kollarovac0f8a962015-12-21 09:09:005#include <utility>
6
spang@chromium.org85905ed2014-07-24 18:48:417#include "base/at_exit.h"
8#include "base/command_line.h"
avi9a24d662015-12-24 05:38:289#include "base/macros.h"
danakj25c52c32016-04-12 21:51:0810#include "base/memory/ptr_util.h"
spang@chromium.org85905ed2014-07-24 18:48:4111#include "base/message_loop/message_loop.h"
12#include "base/run_loop.h"
dcastagna7e2234382017-01-17 17:15:0513#include "base/task_scheduler/task_scheduler.h"
gab042f8e92016-05-11 20:37:0314#include "base/threading/thread_task_runner_handle.h"
Robert Kroegerb0c2e452017-06-19 21:36:1915#include "base/trace_event/trace_event.h"
16#include "components/tracing/common/trace_to_console.h"
17#include "components/tracing/common/tracing_switches.h"
dnicoara655c4e62015-02-11 18:25:5618#include "ui/display/types/display_snapshot.h"
19#include "ui/display/types/native_display_delegate.h"
20#include "ui/display/types/native_display_observer.h"
spangb7d90492015-01-12 16:07:5621#include "ui/events/event.h"
kpschoedel3b0960a2015-05-11 17:52:1122#include "ui/events/keycodes/dom/dom_code.h"
dnicoara6e408ee82015-01-14 03:55:2723#include "ui/events/ozone/layout/keyboard_layout_engine.h"
24#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
dnicoara3f6f5e052014-12-17 03:30:4525#include "ui/gfx/geometry/rect.h"
spang@chromium.org85905ed2014-07-24 18:48:4126#include "ui/gfx/geometry/size.h"
spang@chromium.org85905ed2014-07-24 18:48:4127#include "ui/gl/gl_surface.h"
kylechar5b9dec12016-05-16 15:40:5728#include "ui/gl/init/gl_factory.h"
dnicoara3f6f5e052014-12-17 03:30:4529#include "ui/ozone/demo/gl_renderer.h"
30#include "ui/ozone/demo/software_renderer.h"
dnicoara52f460f2014-12-17 17:18:1031#include "ui/ozone/demo/surfaceless_gl_renderer.h"
dnicoara09b7de5d2015-02-21 01:20:0132#include "ui/ozone/public/ozone_gpu_test_helper.h"
spang@chromium.org85905ed2014-07-24 18:48:4133#include "ui/ozone/public/ozone_platform.h"
dnicoara52f460f2014-12-17 17:18:1034#include "ui/ozone/public/ozone_switches.h"
spang@chromium.org85905ed2014-07-24 18:48:4135#include "ui/platform_window/platform_window.h"
36#include "ui/platform_window/platform_window_delegate.h"
37
38const int kTestWindowWidth = 800;
39const int kTestWindowHeight = 600;
40
spang@chromium.org85905ed2014-07-24 18:48:4141const char kDisableGpu[] = "disable-gpu";
42
spangcb6a15f2015-09-16 22:48:5543const char kDisableSurfaceless[] = "disable-surfaceless";
44
dnicoara3f6f5e052014-12-17 03:30:4545const char kWindowSize[] = "window-size";
46
dnicoara655c4e62015-02-11 18:25:5647class DemoWindow;
48
kylechar7a463842016-05-26 14:46:1249scoped_refptr<gl::GLSurface> CreateGLSurface(gfx::AcceleratedWidget widget) {
50 scoped_refptr<gl::GLSurface> surface;
spangcb6a15f2015-09-16 22:48:5551 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(kDisableSurfaceless))
kylechar5b9dec12016-05-16 15:40:5752 surface = gl::init::CreateSurfacelessViewGLSurface(widget);
spangcb6a15f2015-09-16 22:48:5553 if (!surface)
kylechar5b9dec12016-05-16 15:40:5754 surface = gl::init::CreateViewGLSurface(widget);
spangcb6a15f2015-09-16 22:48:5555 return surface;
56}
57
dnicoara655c4e62015-02-11 18:25:5658class RendererFactory {
59 public:
60 enum RendererType {
61 GL,
dnicoara655c4e62015-02-11 18:25:5662 SOFTWARE,
63 };
64
65 RendererFactory();
66 ~RendererFactory();
67
68 bool Initialize();
danakj25c52c32016-04-12 21:51:0869 std::unique_ptr<ui::Renderer> CreateRenderer(gfx::AcceleratedWidget widget,
70 const gfx::Size& size);
dnicoara655c4e62015-02-11 18:25:5671
72 private:
spang6f2e80c2015-06-17 17:41:0473 RendererType type_ = SOFTWARE;
dnicoara655c4e62015-02-11 18:25:5674
75 // Helper for applications that do GL on main thread.
dnicoara09b7de5d2015-02-21 01:20:0176 ui::OzoneGpuTestHelper gpu_helper_;
dnicoara655c4e62015-02-11 18:25:5677
dnicoara655c4e62015-02-11 18:25:5678 DISALLOW_COPY_AND_ASSIGN(RendererFactory);
79};
80
kylechar7a067ec2017-01-07 01:16:2881class WindowManager : public display::NativeDisplayObserver {
dnicoara655c4e62015-02-11 18:25:5682 public:
83 WindowManager(const base::Closure& quit_closure);
84 ~WindowManager() override;
85
86 void Quit();
87
88 void AddWindow(DemoWindow* window);
89 void RemoveWindow(DemoWindow* window);
90
91 private:
kylechar7a067ec2017-01-07 01:16:2892 void OnDisplaysAquired(
93 const std::vector<display::DisplaySnapshot*>& displays);
dnicoara655c4e62015-02-11 18:25:5694 void OnDisplayConfigured(const gfx::Rect& bounds, bool success);
95
kylechar7a067ec2017-01-07 01:16:2896 // display::NativeDisplayDelegate:
dnicoara655c4e62015-02-11 18:25:5697 void OnConfigurationChanged() override;
kylechar3f0ff6fe92016-12-14 15:16:1998 void OnDisplaySnapshotsInvalidated() override;
dnicoara655c4e62015-02-11 18:25:5699
kylechar7a067ec2017-01-07 01:16:28100 std::unique_ptr<display::NativeDisplayDelegate> delegate_;
dnicoara655c4e62015-02-11 18:25:56101 base::Closure quit_closure_;
102 RendererFactory renderer_factory_;
danakj25c52c32016-04-12 21:51:08103 std::vector<std::unique_ptr<DemoWindow>> windows_;
dnicoara655c4e62015-02-11 18:25:56104
105 // Flags used to keep track of the current state of display configuration.
106 //
107 // True if configuring the displays. In this case a new display configuration
108 // isn't started.
spang6f2e80c2015-06-17 17:41:04109 bool is_configuring_ = false;
dnicoara655c4e62015-02-11 18:25:56110
111 // If |is_configuring_| is true and another display configuration event
112 // happens, the event is deferred. This is set to true and a display
113 // configuration will be scheduled after the current one finishes.
spang6f2e80c2015-06-17 17:41:04114 bool should_configure_ = false;
dnicoara655c4e62015-02-11 18:25:56115
116 DISALLOW_COPY_AND_ASSIGN(WindowManager);
117};
118
spang@chromium.org85905ed2014-07-24 18:48:41119class DemoWindow : public ui::PlatformWindowDelegate {
120 public:
dnicoara655c4e62015-02-11 18:25:56121 DemoWindow(WindowManager* window_manager,
122 RendererFactory* renderer_factory,
123 const gfx::Rect& bounds)
124 : window_manager_(window_manager),
125 renderer_factory_(renderer_factory),
dnicoara655c4e62015-02-11 18:25:56126 weak_ptr_factory_(this) {
127 platform_window_ =
128 ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds);
spang@chromium.org85905ed2014-07-24 18:48:41129 }
spanga3f37292014-11-07 23:19:01130 ~DemoWindow() override {}
spang@chromium.org85905ed2014-07-24 18:48:41131
132 gfx::AcceleratedWidget GetAcceleratedWidget() {
133 // TODO(spang): We should start rendering asynchronously.
spang@chromium.org5afd0bf2014-07-29 15:33:57134 DCHECK_NE(widget_, gfx::kNullAcceleratedWidget)
spang@chromium.org85905ed2014-07-24 18:48:41135 << "Widget not available synchronously";
136 return widget_;
137 }
138
139 gfx::Size GetSize() { return platform_window_->GetBounds().size(); }
140
dnicoara655c4e62015-02-11 18:25:56141 void Start() {
142 base::ThreadTaskRunnerHandle::Get()->PostTask(
143 FROM_HERE,
144 base::Bind(&DemoWindow::StartOnGpu, weak_ptr_factory_.GetWeakPtr()));
spang@chromium.org85905ed2014-07-24 18:48:41145 }
146
147 void Quit() {
dnicoara655c4e62015-02-11 18:25:56148 window_manager_->Quit();
149 }
spang@chromium.org85905ed2014-07-24 18:48:41150
151 // PlatformWindowDelegate:
dnicoara655c4e62015-02-11 18:25:56152 void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
153 void OnDamageRect(const gfx::Rect& damaged_region) override {}
154 void DispatchEvent(ui::Event* event) override {
moshayedi4e6623012016-03-02 04:53:58155 if (event->IsKeyEvent() && event->AsKeyEvent()->code() == ui::DomCode::US_Q)
dnicoara655c4e62015-02-11 18:25:56156 Quit();
157 }
158 void OnCloseRequest() override { Quit(); }
159 void OnClosed() override {}
160 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {}
161 void OnLostCapture() override {}
skyb2afc802015-06-18 16:24:25162 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget,
163 float device_pixel_ratio) override {
spang@chromium.org5afd0bf2014-07-29 15:33:57164 DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
spang@chromium.org85905ed2014-07-24 18:48:41165 widget_ = widget;
166 }
sievers58f433642015-10-19 18:47:50167 void OnAcceleratedWidgetDestroyed() override {
168 NOTREACHED();
169 }
spanga3f37292014-11-07 23:19:01170 void OnActivationChanged(bool active) override {}
spang@chromium.org85905ed2014-07-24 18:48:41171
172 private:
dnicoara655c4e62015-02-11 18:25:56173 // Since we pretend to have a GPU process, we should also pretend to
174 // initialize the GPU resources via a posted task.
175 void StartOnGpu() {
176 renderer_ =
177 renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize());
dnicoara2f70d992015-05-25 16:14:24178 renderer_->Initialize();
dnicoara655c4e62015-02-11 18:25:56179 }
spang@chromium.org85905ed2014-07-24 18:48:41180
dnicoara655c4e62015-02-11 18:25:56181 WindowManager* window_manager_; // Not owned.
182 RendererFactory* renderer_factory_; // Not owned.
spangaa2a3722014-09-03 05:14:58183
danakj25c52c32016-04-12 21:51:08184 std::unique_ptr<ui::Renderer> renderer_;
dnicoara3f6f5e052014-12-17 03:30:45185
spang@chromium.org85905ed2014-07-24 18:48:41186 // Window-related state.
danakj25c52c32016-04-12 21:51:08187 std::unique_ptr<ui::PlatformWindow> platform_window_;
spang6f2e80c2015-06-17 17:41:04188 gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
spang@chromium.org85905ed2014-07-24 18:48:41189
dnicoara655c4e62015-02-11 18:25:56190 base::WeakPtrFactory<DemoWindow> weak_ptr_factory_;
spangbb91b33b2015-01-09 23:06:17191
spang@chromium.org85905ed2014-07-24 18:48:41192 DISALLOW_COPY_AND_ASSIGN(DemoWindow);
193};
194
dnicoara655c4e62015-02-11 18:25:56195///////////////////////////////////////////////////////////////////////////////
196// RendererFactory implementation:
197
spang6f2e80c2015-06-17 17:41:04198RendererFactory::RendererFactory() {
dnicoara655c4e62015-02-11 18:25:56199}
200
201RendererFactory::~RendererFactory() {
202}
203
204bool RendererFactory::Initialize() {
Joone Hur7928288382017-06-15 00:40:19205 ui::OzonePlatform::InitParams params;
206 params.single_process = true;
207 ui::OzonePlatform::InitializeForGPU(params);
208
dnicoara655c4e62015-02-11 18:25:56209 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
kylechar5b9dec12016-05-16 15:40:57210 if (!command_line->HasSwitch(kDisableGpu) && gl::init::InitializeGLOneOff() &&
dnicoara09b7de5d2015-02-21 01:20:01211 gpu_helper_.Initialize(base::ThreadTaskRunnerHandle::Get(),
212 base::ThreadTaskRunnerHandle::Get())) {
spangcb6a15f2015-09-16 22:48:55213 type_ = GL;
dnicoara655c4e62015-02-11 18:25:56214 } else {
215 type_ = SOFTWARE;
216 }
217
218 return true;
219}
220
danakj25c52c32016-04-12 21:51:08221std::unique_ptr<ui::Renderer> RendererFactory::CreateRenderer(
dnicoara655c4e62015-02-11 18:25:56222 gfx::AcceleratedWidget widget,
223 const gfx::Size& size) {
224 switch (type_) {
spangcb6a15f2015-09-16 22:48:55225 case GL: {
kylechar7a463842016-05-26 14:46:12226 scoped_refptr<gl::GLSurface> surface = CreateGLSurface(widget);
spangcb6a15f2015-09-16 22:48:55227 if (!surface)
228 LOG(FATAL) << "Failed to create GL surface";
fwang0054fa92016-09-21 13:34:16229 if (!surface->SupportsAsyncSwap())
230 LOG(FATAL) << "GL surface must support SwapBuffersAsync";
spangcb6a15f2015-09-16 22:48:55231 if (surface->IsSurfaceless())
riceaeb5cdbe2016-08-22 02:47:27232 return base::MakeUnique<ui::SurfacelessGlRenderer>(widget, surface,
233 size);
spangcb6a15f2015-09-16 22:48:55234 else
riceaeb5cdbe2016-08-22 02:47:27235 return base::MakeUnique<ui::GlRenderer>(widget, surface, size);
spangcb6a15f2015-09-16 22:48:55236 }
dnicoara655c4e62015-02-11 18:25:56237 case SOFTWARE:
riceaeb5cdbe2016-08-22 02:47:27238 return base::MakeUnique<ui::SoftwareRenderer>(widget, size);
dnicoara655c4e62015-02-11 18:25:56239 }
240
241 return nullptr;
242}
243
244///////////////////////////////////////////////////////////////////////////////
245// WindowManager implementation:
246
247WindowManager::WindowManager(const base::Closure& quit_closure)
248 : delegate_(
249 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()),
spang6f2e80c2015-06-17 17:41:04250 quit_closure_(quit_closure) {
dnicoara655c4e62015-02-11 18:25:56251 if (!renderer_factory_.Initialize())
252 LOG(FATAL) << "Failed to initialize renderer factory";
253
254 if (delegate_) {
255 delegate_->AddObserver(this);
256 delegate_->Initialize();
257 OnConfigurationChanged();
258 } else {
259 LOG(WARNING) << "No display delegate; falling back to test window";
260 int width = kTestWindowWidth;
261 int height = kTestWindowHeight;
262 sscanf(base::CommandLine::ForCurrentProcess()
263 ->GetSwitchValueASCII(kWindowSize)
264 .c_str(),
265 "%dx%d", &width, &height);
266
267 DemoWindow* window = new DemoWindow(this, &renderer_factory_,
268 gfx::Rect(gfx::Size(width, height)));
269 window->Start();
270 }
271}
272
273WindowManager::~WindowManager() {
274 if (delegate_)
275 delegate_->RemoveObserver(this);
276}
277
278void WindowManager::Quit() {
279 quit_closure_.Run();
280}
281
282void WindowManager::OnConfigurationChanged() {
283 if (is_configuring_) {
284 should_configure_ = true;
285 return;
286 }
287
288 is_configuring_ = true;
289 delegate_->GrabServer();
290 delegate_->GetDisplays(
291 base::Bind(&WindowManager::OnDisplaysAquired, base::Unretained(this)));
292}
293
kylechar3f0ff6fe92016-12-14 15:16:19294void WindowManager::OnDisplaySnapshotsInvalidated() {}
295
dnicoara655c4e62015-02-11 18:25:56296void WindowManager::OnDisplaysAquired(
kylechar7a067ec2017-01-07 01:16:28297 const std::vector<display::DisplaySnapshot*>& displays) {
dnicoara655c4e62015-02-11 18:25:56298 windows_.clear();
299
300 gfx::Point origin;
tonikitoof24d3682017-02-25 05:16:55301 for (auto* display : displays) {
dnicoara655c4e62015-02-11 18:25:56302 if (!display->native_mode()) {
303 LOG(ERROR) << "Display " << display->display_id()
304 << " doesn't have a native mode";
305 continue;
306 }
307
308 delegate_->Configure(
309 *display, display->native_mode(), origin,
310 base::Bind(&WindowManager::OnDisplayConfigured, base::Unretained(this),
311 gfx::Rect(origin, display->native_mode()->size())));
312 origin.Offset(display->native_mode()->size().width(), 0);
313 }
314 delegate_->UngrabServer();
315 is_configuring_ = false;
316
317 if (should_configure_) {
318 should_configure_ = false;
319 base::ThreadTaskRunnerHandle::Get()->PostTask(
320 FROM_HERE, base::Bind(&WindowManager::OnConfigurationChanged,
321 base::Unretained(this)));
322 }
323}
324
325void WindowManager::OnDisplayConfigured(const gfx::Rect& bounds, bool success) {
326 if (success) {
danakj25c52c32016-04-12 21:51:08327 std::unique_ptr<DemoWindow> window(
dnicoara655c4e62015-02-11 18:25:56328 new DemoWindow(this, &renderer_factory_, bounds));
329 window->Start();
martina.kollarovac0f8a962015-12-21 09:09:00330 windows_.push_back(std::move(window));
dnicoara655c4e62015-02-11 18:25:56331 } else {
332 LOG(ERROR) << "Failed to configure display at " << bounds.ToString();
333 }
334}
335
spang@chromium.org85905ed2014-07-24 18:48:41336int main(int argc, char** argv) {
avi6b10fd02014-12-23 05:51:23337 base::CommandLine::Init(argc, argv);
spang@chromium.org85905ed2014-07-24 18:48:41338 base::AtExitManager exit_manager;
339
dnicoara655c4e62015-02-11 18:25:56340 // Initialize logging so we can enable VLOG messages.
341 logging::LoggingSettings settings;
342 logging::InitLogging(settings);
343
Robert Kroegerb0c2e452017-06-19 21:36:19344 // Initialize tracing.
345 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
346 switches::kTraceToConsole)) {
347 base::trace_event::TraceConfig trace_config =
348 tracing::GetConfigForTraceToConsole();
349 base::trace_event::TraceLog::GetInstance()->SetEnabled(
350 trace_config, base::trace_event::TraceLog::RECORDING_MODE);
351 }
352
spang@chromium.org85905ed2014-07-24 18:48:41353 // Build UI thread message loop. This is used by platform
354 // implementations for event polling & running background tasks.
355 base::MessageLoopForUI message_loop;
fdorayf264f1a2017-04-26 21:54:58356 base::TaskScheduler::CreateAndStartWithDefaultParams("OzoneDemo");
spang@chromium.org85905ed2014-07-24 18:48:41357
358 ui::OzonePlatform::InitializeForUI();
dnicoara6e408ee82015-01-14 03:55:27359 ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()
360 ->SetCurrentLayoutByName("us");
spang@chromium.org85905ed2014-07-24 18:48:41361
spang@chromium.org85905ed2014-07-24 18:48:41362 base::RunLoop run_loop;
spangbb91b33b2015-01-09 23:06:17363
dnicoara655c4e62015-02-11 18:25:56364 WindowManager window_manager(run_loop.QuitClosure());
spangbb91b33b2015-01-09 23:06:17365
366 run_loop.Run();
spang@chromium.org85905ed2014-07-24 18:48:41367
368 return 0;
369}