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

Side by Side Diff: ui/ozone/demo/ozone_demo.cc

Issue 805003002: [Ozone-Demo] Add support for NativeDisplayDelegate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ozone-demo2
Patch Set: Keep our story straight and post tasks that are supposed to be proxied to the GPU Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/at_exit.h" 5 #include "base/at_exit.h"
6 #include "base/command_line.h" 6 #include "base/command_line.h"
7 #include "base/memory/scoped_vector.h"
7 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
9 #include "base/timer/timer.h" 11 #include "base/timer/timer.h"
12 #include "ui/display/types/display_snapshot.h"
13 #include "ui/display/types/native_display_delegate.h"
14 #include "ui/display/types/native_display_observer.h"
10 #include "ui/events/event.h" 15 #include "ui/events/event.h"
11 #include "ui/events/keycodes/dom3/dom_code.h" 16 #include "ui/events/keycodes/dom3/dom_code.h"
12 #include "ui/events/ozone/layout/keyboard_layout_engine.h" 17 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
13 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" 18 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
14 #include "ui/gfx/geometry/rect.h" 19 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/geometry/size.h" 20 #include "ui/gfx/geometry/size.h"
16 #include "ui/gl/gl_surface.h" 21 #include "ui/gl/gl_surface.h"
17 #include "ui/ozone/demo/gl_renderer.h" 22 #include "ui/ozone/demo/gl_renderer.h"
18 #include "ui/ozone/demo/software_renderer.h" 23 #include "ui/ozone/demo/software_renderer.h"
19 #include "ui/ozone/demo/surfaceless_gl_renderer.h" 24 #include "ui/ozone/demo/surfaceless_gl_renderer.h"
25 #include "ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h"
20 #include "ui/ozone/public/ozone_platform.h" 26 #include "ui/ozone/public/ozone_platform.h"
21 #include "ui/ozone/public/ozone_switches.h" 27 #include "ui/ozone/public/ozone_switches.h"
22 #include "ui/ozone/public/ui_thread_gpu.h" 28 #include "ui/ozone/public/ui_thread_gpu.h"
23 #include "ui/platform_window/platform_window.h" 29 #include "ui/platform_window/platform_window.h"
24 #include "ui/platform_window/platform_window_delegate.h" 30 #include "ui/platform_window/platform_window_delegate.h"
25 31
26 const int kTestWindowWidth = 800; 32 const int kTestWindowWidth = 800;
27 const int kTestWindowHeight = 600; 33 const int kTestWindowHeight = 600;
28 34
29 const int kFrameDelayMilliseconds = 16; 35 const int kFrameDelayMilliseconds = 16;
30 36
31 const char kDisableGpu[] = "disable-gpu"; 37 const char kDisableGpu[] = "disable-gpu";
32 38
33 const char kWindowSize[] = "window-size"; 39 const char kWindowSize[] = "window-size";
34 40
41 class DemoWindow;
42
43 class RendererFactory {
44 public:
45 enum RendererType {
46 GL,
47 SURFACELESS_GL,
48 SOFTWARE,
49 };
50
51 RendererFactory();
52 ~RendererFactory();
53
54 bool Initialize();
55 scoped_ptr<ui::Renderer> CreateRenderer(gfx::AcceleratedWidget widget,
56 const gfx::Size& size);
57
58 private:
59 RendererType type_;
60
61 // Helper for applications that do GL on main thread.
62 ui::UiThreadGpu ui_thread_gpu_;
63
64 // Used by the surfaceless renderers to allocate buffers.
65 ui::GpuMemoryBufferFactoryOzoneNativeBuffer buffer_factory_;
66
67 DISALLOW_COPY_AND_ASSIGN(RendererFactory);
68 };
69
70 class WindowManager : public ui::NativeDisplayObserver {
71 public:
72 WindowManager(const base::Closure& quit_closure);
73 ~WindowManager() override;
74
75 void Quit();
76
77 void AddWindow(DemoWindow* window);
78 void RemoveWindow(DemoWindow* window);
79
80 private:
81 void OnGetDisplays(const std::vector<ui::DisplaySnapshot*>& displays);
82 void OnDisplayConfigured(const gfx::Rect& bounds, bool success);
83
84 // ui::NativeDisplayDelegate:
85 void OnConfigurationChanged() override;
86
87 scoped_ptr<ui::NativeDisplayDelegate> delegate_;
88 base::Closure quit_closure_;
89 RendererFactory renderer_factory_;
90 ScopedVector<DemoWindow> windows_;
91
92 DISALLOW_COPY_AND_ASSIGN(WindowManager);
93 };
94
35 class DemoWindow : public ui::PlatformWindowDelegate { 95 class DemoWindow : public ui::PlatformWindowDelegate {
36 public: 96 public:
37 DemoWindow() : widget_(gfx::kNullAcceleratedWidget) { 97 DemoWindow(WindowManager* window_manager,
38 int width = kTestWindowWidth; 98 RendererFactory* renderer_factory,
39 int height = kTestWindowHeight; 99 const gfx::Rect& bounds)
40 sscanf(base::CommandLine::ForCurrentProcess() 100 : window_manager_(window_manager),
41 ->GetSwitchValueASCII(kWindowSize) 101 renderer_factory_(renderer_factory),
42 .c_str(), 102 widget_(gfx::kNullAcceleratedWidget),
43 "%dx%d", &width, &height); 103 weak_ptr_factory_(this) {
44 104 platform_window_ =
45 platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( 105 ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds);
46 this, gfx::Rect(width, height));
47 } 106 }
48 ~DemoWindow() override {} 107 ~DemoWindow() override {}
49 108
50 gfx::AcceleratedWidget GetAcceleratedWidget() { 109 gfx::AcceleratedWidget GetAcceleratedWidget() {
51 // TODO(spang): We should start rendering asynchronously. 110 // TODO(spang): We should start rendering asynchronously.
52 DCHECK_NE(widget_, gfx::kNullAcceleratedWidget) 111 DCHECK_NE(widget_, gfx::kNullAcceleratedWidget)
53 << "Widget not available synchronously"; 112 << "Widget not available synchronously";
54 return widget_; 113 return widget_;
55 } 114 }
56 115
57 gfx::Size GetSize() { return platform_window_->GetBounds().size(); } 116 gfx::Size GetSize() { return platform_window_->GetBounds().size(); }
58 117
59 void Start(const base::Closure& quit_closure) { 118 void Start() {
60 quit_closure_ = quit_closure; 119 base::ThreadTaskRunnerHandle::Get()->PostTask(
61 120 FROM_HERE,
62 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(kDisableGpu) && 121 base::Bind(&DemoWindow::StartOnGpu, weak_ptr_factory_.GetWeakPtr()));
63 gfx::GLSurface::InitializeOneOff() && StartInProcessGpu()) {
64 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
65 switches::kOzoneUseSurfaceless)) {
66 renderer_.reset(
67 new ui::SurfacelessGlRenderer(GetAcceleratedWidget(), GetSize()));
68 } else {
69 renderer_.reset(new ui::GlRenderer(GetAcceleratedWidget(), GetSize()));
70 }
71 } else {
72 renderer_.reset(
73 new ui::SoftwareRenderer(GetAcceleratedWidget(), GetSize()));
74 }
75
76 if (renderer_->Initialize()) {
77 timer_.Start(FROM_HERE,
78 base::TimeDelta::FromMilliseconds(kFrameDelayMilliseconds),
79 renderer_.get(), &ui::Renderer::RenderFrame);
80 } else {
81 LOG(ERROR) << "Failed to create drawing surface";
82 Quit();
83 }
84 } 122 }
85 123
86 void Quit() { 124 void Quit() {
87 StopAnimation(); 125 StopAnimation();
88 quit_closure_.Run(); 126 window_manager_->Quit();
89 } 127 }
90 128
91 // PlatformWindowDelegate: 129 // PlatformWindowDelegate:
92 void OnBoundsChanged(const gfx::Rect& new_bounds) override {} 130 void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
93 void OnDamageRect(const gfx::Rect& damaged_region) override {} 131 void OnDamageRect(const gfx::Rect& damaged_region) override {}
94 void DispatchEvent(ui::Event* event) override { 132 void DispatchEvent(ui::Event* event) override {
95 if (event->IsKeyEvent() && 133 if (event->IsKeyEvent() &&
96 static_cast<ui::KeyEvent*>(event)->code() == ui::DomCode::KEY_Q) 134 static_cast<ui::KeyEvent*>(event)->code() == ui::DomCode::KEY_Q)
97 Quit(); 135 Quit();
98 } 136 }
99 void OnCloseRequest() override { Quit(); } 137 void OnCloseRequest() override { Quit(); }
100 void OnClosed() override {} 138 void OnClosed() override {}
101 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {} 139 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {}
102 void OnLostCapture() override {} 140 void OnLostCapture() override {}
103 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override { 141 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override {
104 DCHECK_NE(widget, gfx::kNullAcceleratedWidget); 142 DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
105 widget_ = widget; 143 widget_ = widget;
106 } 144 }
107 void OnActivationChanged(bool active) override {} 145 void OnActivationChanged(bool active) override {}
108 146
109 private: 147 private:
148 // Since we pretend to have a GPU process, we should also pretend to
149 // initialize the GPU resources via a posted task.
150 void StartOnGpu() {
151 renderer_ =
152 renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize());
153 if (renderer_->Initialize()) {
154 timer_.Start(FROM_HERE,
155 base::TimeDelta::FromMilliseconds(kFrameDelayMilliseconds),
156 renderer_.get(), &ui::Renderer::RenderFrame);
157 }
158 }
110 159
111 void StopAnimation() { timer_.Stop(); } 160 void StopAnimation() { timer_.Stop(); }
112 161
113 bool StartInProcessGpu() { return ui_thread_gpu_.Initialize(); } 162 WindowManager* window_manager_; // Not owned.
163 RendererFactory* renderer_factory_; // Not owned.
114 164
115 scoped_ptr<ui::Renderer> renderer_; 165 scoped_ptr<ui::Renderer> renderer_;
116 166
117 // Timer for animation. 167 // Timer for animation.
118 base::RepeatingTimer<ui::Renderer> timer_; 168 base::RepeatingTimer<ui::Renderer> timer_;
119 169
120 // Window-related state. 170 // Window-related state.
121 scoped_ptr<ui::PlatformWindow> platform_window_; 171 scoped_ptr<ui::PlatformWindow> platform_window_;
122 gfx::AcceleratedWidget widget_; 172 gfx::AcceleratedWidget widget_;
123 173
124 // Helper for applications that do GL on main thread. 174 base::WeakPtrFactory<DemoWindow> weak_ptr_factory_;
125 ui::UiThreadGpu ui_thread_gpu_;
126
127 base::Closure quit_closure_;
128 175
129 DISALLOW_COPY_AND_ASSIGN(DemoWindow); 176 DISALLOW_COPY_AND_ASSIGN(DemoWindow);
130 }; 177 };
131 178
179 ///////////////////////////////////////////////////////////////////////////////
180 // RendererFactory implementation:
181
182 RendererFactory::RendererFactory() : type_(SOFTWARE) {
183 }
184
185 RendererFactory::~RendererFactory() {
186 }
187
188 bool RendererFactory::Initialize() {
189 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
190 if (!command_line->HasSwitch(kDisableGpu) &&
191 gfx::GLSurface::InitializeOneOff() && ui_thread_gpu_.Initialize()) {
192 if (command_line->HasSwitch(switches::kOzoneUseSurfaceless)) {
193 type_ = SURFACELESS_GL;
194 } else {
195 type_ = GL;
196 }
197 } else {
198 type_ = SOFTWARE;
199 }
200
201 return true;
202 }
203
204 scoped_ptr<ui::Renderer> RendererFactory::CreateRenderer(
205 gfx::AcceleratedWidget widget,
206 const gfx::Size& size) {
207 switch (type_) {
208 case GL:
209 return scoped_ptr<ui::Renderer>(new ui::GlRenderer(widget, size));
210 case SURFACELESS_GL:
211 return scoped_ptr<ui::Renderer>(
212 new ui::SurfacelessGlRenderer(widget, size, &buffer_factory_));
213 case SOFTWARE:
214 return scoped_ptr<ui::Renderer>(new ui::SoftwareRenderer(widget, size));
215 }
216
217 return nullptr;
alexst (slow to review) 2015/02/11 15:36:05 Every switch case is handled, I don't think you ne
dnicoara 2015/02/11 16:46:37 The CrOS build complains without this.
218 }
219
220 ///////////////////////////////////////////////////////////////////////////////
221 // WindowManager implementation:
222
223 WindowManager::WindowManager(const base::Closure& quit_closure)
224 : delegate_(
225 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()),
226 quit_closure_(quit_closure) {
227 if (!renderer_factory_.Initialize())
228 LOG(FATAL) << "Failed to initialize renderer factory";
229
230 if (delegate_) {
231 delegate_->AddObserver(this);
232 delegate_->Initialize();
233 OnConfigurationChanged();
234 } else {
235 LOG(WARNING) << "No display delegate; falling back to test window";
236 int width = kTestWindowWidth;
237 int height = kTestWindowHeight;
238 sscanf(base::CommandLine::ForCurrentProcess()
239 ->GetSwitchValueASCII(kWindowSize)
240 .c_str(),
241 "%dx%d", &width, &height);
242
243 DemoWindow* window = new DemoWindow(this, &renderer_factory_,
244 gfx::Rect(gfx::Size(width, height)));
245 window->Start();
246 }
247 }
248
249 WindowManager::~WindowManager() {
250 if (delegate_)
251 delegate_->RemoveObserver(this);
252 }
253
254 void WindowManager::Quit() {
255 quit_closure_.Run();
256 }
257
258 void WindowManager::OnConfigurationChanged() {
259 delegate_->GrabServer();
260 delegate_->GetDisplays(
261 base::Bind(&WindowManager::OnGetDisplays, base::Unretained(this)));
262 }
263
264 void WindowManager::OnGetDisplays(
alexst (slow to review) 2015/02/11 15:36:05 OnDisplaysAquired or soemthing? OnGet.. feels odd
dnicoara 2015/02/11 16:46:37 Done.
265 const std::vector<ui::DisplaySnapshot*>& displays) {
266 windows_.clear();
267
268 gfx::Point origin;
269 for (auto display : displays) {
270 if (!display->native_mode()) {
271 LOG(ERROR) << "Display " << display->display_id()
272 << " doesn't have a native mode";
273 continue;
274 }
275
276 delegate_->Configure(
277 *display, display->native_mode(), origin,
278 base::Bind(&WindowManager::OnDisplayConfigured, base::Unretained(this),
279 gfx::Rect(origin, display->native_mode()->size())));
280 origin.Offset(display->native_mode()->size().width(), 0);
281 }
282 delegate_->UngrabServer();
283 }
284
285 void WindowManager::OnDisplayConfigured(const gfx::Rect& bounds, bool success) {
286 if (success) {
287 scoped_ptr<DemoWindow> window(
288 new DemoWindow(this, &renderer_factory_, bounds));
289 window->Start();
290 windows_.push_back(window.release());
291 } else {
292 LOG(ERROR) << "Failed to configure display at " << bounds.ToString();
293 }
294 }
295
132 int main(int argc, char** argv) { 296 int main(int argc, char** argv) {
133 base::CommandLine::Init(argc, argv); 297 base::CommandLine::Init(argc, argv);
134 base::AtExitManager exit_manager; 298 base::AtExitManager exit_manager;
135 299
136 // Build UI thread message loop. This is used by platform 300 // Build UI thread message loop. This is used by platform
137 // implementations for event polling & running background tasks. 301 // implementations for event polling & running background tasks.
138 base::MessageLoopForUI message_loop; 302 base::MessageLoopForUI message_loop;
139 303
140 ui::OzonePlatform::InitializeForUI(); 304 ui::OzonePlatform::InitializeForUI();
141 ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine() 305 ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()
142 ->SetCurrentLayoutByName("us"); 306 ->SetCurrentLayoutByName("us");
143 307
144 base::RunLoop run_loop; 308 base::RunLoop run_loop;
145 309
146 scoped_ptr<DemoWindow> window(new DemoWindow); 310 WindowManager window_manager(run_loop.QuitClosure());
147 window->Start(run_loop.QuitClosure());
148 311
149 run_loop.Run(); 312 run_loop.Run();
150 313
151 return 0; 314 return 0;
152 } 315 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698