Add ICU message format support
[chromium-blink-merge.git] / ui / ozone / demo / ozone_demo.cc
blob5e55b6bc776b2a8b8ab24221ca9125df43311d7f
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.
5 #include "base/at_exit.h"
6 #include "base/command_line.h"
7 #include "base/memory/scoped_vector.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "ui/display/types/display_snapshot.h"
12 #include "ui/display/types/native_display_delegate.h"
13 #include "ui/display/types/native_display_observer.h"
14 #include "ui/events/event.h"
15 #include "ui/events/keycodes/dom/dom_code.h"
16 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
17 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
18 #include "ui/gfx/geometry/rect.h"
19 #include "ui/gfx/geometry/size.h"
20 #include "ui/gl/gl_surface.h"
21 #include "ui/ozone/demo/gl_renderer.h"
22 #include "ui/ozone/demo/software_renderer.h"
23 #include "ui/ozone/demo/surfaceless_gl_renderer.h"
24 #include "ui/ozone/public/ozone_gpu_test_helper.h"
25 #include "ui/ozone/public/ozone_platform.h"
26 #include "ui/ozone/public/ozone_switches.h"
27 #include "ui/platform_window/platform_window.h"
28 #include "ui/platform_window/platform_window_delegate.h"
30 const int kTestWindowWidth = 800;
31 const int kTestWindowHeight = 600;
33 const char kDisableGpu[] = "disable-gpu";
35 const char kWindowSize[] = "window-size";
37 class DemoWindow;
39 class RendererFactory {
40 public:
41 enum RendererType {
42 GL,
43 SURFACELESS_GL,
44 SOFTWARE,
47 RendererFactory();
48 ~RendererFactory();
50 bool Initialize();
51 scoped_ptr<ui::Renderer> CreateRenderer(gfx::AcceleratedWidget widget,
52 const gfx::Size& size);
54 private:
55 RendererType type_ = SOFTWARE;
57 // Helper for applications that do GL on main thread.
58 ui::OzoneGpuTestHelper gpu_helper_;
60 DISALLOW_COPY_AND_ASSIGN(RendererFactory);
63 class WindowManager : public ui::NativeDisplayObserver {
64 public:
65 WindowManager(const base::Closure& quit_closure);
66 ~WindowManager() override;
68 void Quit();
70 void AddWindow(DemoWindow* window);
71 void RemoveWindow(DemoWindow* window);
73 private:
74 void OnDisplaysAquired(const std::vector<ui::DisplaySnapshot*>& displays);
75 void OnDisplayConfigured(const gfx::Rect& bounds, bool success);
77 // ui::NativeDisplayDelegate:
78 void OnConfigurationChanged() override;
80 scoped_ptr<ui::NativeDisplayDelegate> delegate_;
81 base::Closure quit_closure_;
82 RendererFactory renderer_factory_;
83 ScopedVector<DemoWindow> windows_;
85 // Flags used to keep track of the current state of display configuration.
87 // True if configuring the displays. In this case a new display configuration
88 // isn't started.
89 bool is_configuring_ = false;
91 // If |is_configuring_| is true and another display configuration event
92 // happens, the event is deferred. This is set to true and a display
93 // configuration will be scheduled after the current one finishes.
94 bool should_configure_ = false;
96 DISALLOW_COPY_AND_ASSIGN(WindowManager);
99 class DemoWindow : public ui::PlatformWindowDelegate {
100 public:
101 DemoWindow(WindowManager* window_manager,
102 RendererFactory* renderer_factory,
103 const gfx::Rect& bounds)
104 : window_manager_(window_manager),
105 renderer_factory_(renderer_factory),
106 weak_ptr_factory_(this) {
107 platform_window_ =
108 ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds);
110 ~DemoWindow() override {}
112 gfx::AcceleratedWidget GetAcceleratedWidget() {
113 // TODO(spang): We should start rendering asynchronously.
114 DCHECK_NE(widget_, gfx::kNullAcceleratedWidget)
115 << "Widget not available synchronously";
116 return widget_;
119 gfx::Size GetSize() { return platform_window_->GetBounds().size(); }
121 void Start() {
122 base::ThreadTaskRunnerHandle::Get()->PostTask(
123 FROM_HERE,
124 base::Bind(&DemoWindow::StartOnGpu, weak_ptr_factory_.GetWeakPtr()));
127 void Quit() {
128 window_manager_->Quit();
131 // PlatformWindowDelegate:
132 void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
133 void OnDamageRect(const gfx::Rect& damaged_region) override {}
134 void DispatchEvent(ui::Event* event) override {
135 if (event->IsKeyEvent() &&
136 static_cast<ui::KeyEvent*>(event)->code() == ui::DomCode::KEY_Q)
137 Quit();
139 void OnCloseRequest() override { Quit(); }
140 void OnClosed() override {}
141 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {}
142 void OnLostCapture() override {}
143 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget,
144 float device_pixel_ratio) override {
145 DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
146 widget_ = widget;
148 void OnActivationChanged(bool active) override {}
150 private:
151 // Since we pretend to have a GPU process, we should also pretend to
152 // initialize the GPU resources via a posted task.
153 void StartOnGpu() {
154 renderer_ =
155 renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize());
156 renderer_->Initialize();
159 WindowManager* window_manager_; // Not owned.
160 RendererFactory* renderer_factory_; // Not owned.
162 scoped_ptr<ui::Renderer> renderer_;
164 // Window-related state.
165 scoped_ptr<ui::PlatformWindow> platform_window_;
166 gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
168 base::WeakPtrFactory<DemoWindow> weak_ptr_factory_;
170 DISALLOW_COPY_AND_ASSIGN(DemoWindow);
173 ///////////////////////////////////////////////////////////////////////////////
174 // RendererFactory implementation:
176 RendererFactory::RendererFactory() {
179 RendererFactory::~RendererFactory() {
182 bool RendererFactory::Initialize() {
183 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
184 if (!command_line->HasSwitch(kDisableGpu) &&
185 gfx::GLSurface::InitializeOneOff() &&
186 gpu_helper_.Initialize(base::ThreadTaskRunnerHandle::Get(),
187 base::ThreadTaskRunnerHandle::Get())) {
188 if (command_line->HasSwitch(switches::kOzoneUseSurfaceless)) {
189 type_ = SURFACELESS_GL;
190 } else {
191 type_ = GL;
193 } else {
194 type_ = SOFTWARE;
197 return true;
200 scoped_ptr<ui::Renderer> RendererFactory::CreateRenderer(
201 gfx::AcceleratedWidget widget,
202 const gfx::Size& size) {
203 switch (type_) {
204 case GL:
205 return make_scoped_ptr(new ui::GlRenderer(widget, size));
206 case SURFACELESS_GL:
207 return make_scoped_ptr(new ui::SurfacelessGlRenderer(widget, size));
208 case SOFTWARE:
209 return make_scoped_ptr(new ui::SoftwareRenderer(widget, size));
212 return nullptr;
215 ///////////////////////////////////////////////////////////////////////////////
216 // WindowManager implementation:
218 WindowManager::WindowManager(const base::Closure& quit_closure)
219 : delegate_(
220 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()),
221 quit_closure_(quit_closure) {
222 if (!renderer_factory_.Initialize())
223 LOG(FATAL) << "Failed to initialize renderer factory";
225 if (delegate_) {
226 delegate_->AddObserver(this);
227 delegate_->Initialize();
228 OnConfigurationChanged();
229 } else {
230 LOG(WARNING) << "No display delegate; falling back to test window";
231 int width = kTestWindowWidth;
232 int height = kTestWindowHeight;
233 sscanf(base::CommandLine::ForCurrentProcess()
234 ->GetSwitchValueASCII(kWindowSize)
235 .c_str(),
236 "%dx%d", &width, &height);
238 DemoWindow* window = new DemoWindow(this, &renderer_factory_,
239 gfx::Rect(gfx::Size(width, height)));
240 window->Start();
244 WindowManager::~WindowManager() {
245 if (delegate_)
246 delegate_->RemoveObserver(this);
249 void WindowManager::Quit() {
250 quit_closure_.Run();
253 void WindowManager::OnConfigurationChanged() {
254 if (is_configuring_) {
255 should_configure_ = true;
256 return;
259 is_configuring_ = true;
260 delegate_->GrabServer();
261 delegate_->GetDisplays(
262 base::Bind(&WindowManager::OnDisplaysAquired, base::Unretained(this)));
265 void WindowManager::OnDisplaysAquired(
266 const std::vector<ui::DisplaySnapshot*>& displays) {
267 windows_.clear();
269 gfx::Point origin;
270 for (auto display : displays) {
271 if (!display->native_mode()) {
272 LOG(ERROR) << "Display " << display->display_id()
273 << " doesn't have a native mode";
274 continue;
277 delegate_->Configure(
278 *display, display->native_mode(), origin,
279 base::Bind(&WindowManager::OnDisplayConfigured, base::Unretained(this),
280 gfx::Rect(origin, display->native_mode()->size())));
281 origin.Offset(display->native_mode()->size().width(), 0);
283 delegate_->UngrabServer();
284 is_configuring_ = false;
286 if (should_configure_) {
287 should_configure_ = false;
288 base::ThreadTaskRunnerHandle::Get()->PostTask(
289 FROM_HERE, base::Bind(&WindowManager::OnConfigurationChanged,
290 base::Unretained(this)));
294 void WindowManager::OnDisplayConfigured(const gfx::Rect& bounds, bool success) {
295 if (success) {
296 scoped_ptr<DemoWindow> window(
297 new DemoWindow(this, &renderer_factory_, bounds));
298 window->Start();
299 windows_.push_back(window.Pass());
300 } else {
301 LOG(ERROR) << "Failed to configure display at " << bounds.ToString();
305 int main(int argc, char** argv) {
306 base::CommandLine::Init(argc, argv);
307 base::AtExitManager exit_manager;
309 // Initialize logging so we can enable VLOG messages.
310 logging::LoggingSettings settings;
311 logging::InitLogging(settings);
313 // Build UI thread message loop. This is used by platform
314 // implementations for event polling & running background tasks.
315 base::MessageLoopForUI message_loop;
317 ui::OzonePlatform::InitializeForUI();
318 ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()
319 ->SetCurrentLayoutByName("us");
321 base::RunLoop run_loop;
323 WindowManager window_manager(run_loop.QuitClosure());
325 run_loop.Run();
327 return 0;