OLD | NEW |
---|---|
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 } |
OLD | NEW |