| OLD | NEW |
| (Empty) | |
| 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. |
| 4 |
| 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/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h" |
| 25 #include "ui/ozone/public/ozone_gpu_test_helper.h" |
| 26 #include "ui/ozone/public/ozone_platform.h" |
| 27 #include "ui/ozone/public/ozone_switches.h" |
| 28 #include "ui/platform_window/platform_window.h" |
| 29 #include "ui/platform_window/platform_window_delegate.h" |
| 30 |
| 31 const int kTestWindowWidth = 800; |
| 32 const int kTestWindowHeight = 600; |
| 33 |
| 34 const char kDisableGpu[] = "disable-gpu"; |
| 35 |
| 36 const char kWindowSize[] = "window-size"; |
| 37 |
| 38 class DemoWindow; |
| 39 |
| 40 class RendererFactory { |
| 41 public: |
| 42 enum RendererType { |
| 43 GL, |
| 44 SURFACELESS_GL, |
| 45 SOFTWARE, |
| 46 }; |
| 47 |
| 48 RendererFactory(); |
| 49 ~RendererFactory(); |
| 50 |
| 51 bool Initialize(); |
| 52 scoped_ptr<ui::Renderer> CreateRenderer(gfx::AcceleratedWidget widget, |
| 53 const gfx::Size& size); |
| 54 |
| 55 private: |
| 56 RendererType type_ = SOFTWARE; |
| 57 |
| 58 // Helper for applications that do GL on main thread. |
| 59 ui::OzoneGpuTestHelper gpu_helper_; |
| 60 |
| 61 // Used by the surfaceless renderers to allocate buffers. |
| 62 ui::GpuMemoryBufferFactoryOzoneNativeBuffer buffer_factory_; |
| 63 |
| 64 DISALLOW_COPY_AND_ASSIGN(RendererFactory); |
| 65 }; |
| 66 |
| 67 class WindowManager : public ui::NativeDisplayObserver { |
| 68 public: |
| 69 WindowManager(const base::Closure& quit_closure); |
| 70 ~WindowManager() override; |
| 71 |
| 72 void Quit(); |
| 73 |
| 74 void AddWindow(DemoWindow* window); |
| 75 void RemoveWindow(DemoWindow* window); |
| 76 |
| 77 private: |
| 78 void OnDisplaysAquired(const std::vector<ui::DisplaySnapshot*>& displays); |
| 79 void OnDisplayConfigured(const gfx::Rect& bounds, bool success); |
| 80 |
| 81 // ui::NativeDisplayDelegate: |
| 82 void OnConfigurationChanged() override; |
| 83 |
| 84 scoped_ptr<ui::NativeDisplayDelegate> delegate_; |
| 85 base::Closure quit_closure_; |
| 86 RendererFactory renderer_factory_; |
| 87 ScopedVector<DemoWindow> windows_; |
| 88 |
| 89 // Flags used to keep track of the current state of display configuration. |
| 90 // |
| 91 // True if configuring the displays. In this case a new display configuration |
| 92 // isn't started. |
| 93 bool is_configuring_ = false; |
| 94 |
| 95 // If |is_configuring_| is true and another display configuration event |
| 96 // happens, the event is deferred. This is set to true and a display |
| 97 // configuration will be scheduled after the current one finishes. |
| 98 bool should_configure_ = false; |
| 99 |
| 100 DISALLOW_COPY_AND_ASSIGN(WindowManager); |
| 101 }; |
| 102 |
| 103 class DemoWindow : public ui::PlatformWindowDelegate { |
| 104 public: |
| 105 DemoWindow(WindowManager* window_manager, |
| 106 RendererFactory* renderer_factory, |
| 107 const gfx::Rect& bounds) |
| 108 : window_manager_(window_manager), |
| 109 renderer_factory_(renderer_factory), |
| 110 weak_ptr_factory_(this) { |
| 111 platform_window_ = |
| 112 ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds); |
| 113 } |
| 114 ~DemoWindow() override {} |
| 115 |
| 116 gfx::AcceleratedWidget GetAcceleratedWidget() { |
| 117 // TODO(spang): We should start rendering asynchronously. |
| 118 DCHECK_NE(widget_, gfx::kNullAcceleratedWidget) |
| 119 << "Widget not available synchronously"; |
| 120 return widget_; |
| 121 } |
| 122 |
| 123 gfx::Size GetSize() { return platform_window_->GetBounds().size(); } |
| 124 |
| 125 void Start() { |
| 126 LOG(INFO) << "DemoWindow::Start"; |
| 127 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 128 FROM_HERE, |
| 129 base::Bind(&DemoWindow::StartOnGpu, weak_ptr_factory_.GetWeakPtr())); |
| 130 } |
| 131 |
| 132 void Quit() { |
| 133 window_manager_->Quit(); |
| 134 } |
| 135 |
| 136 // PlatformWindowDelegate: |
| 137 void OnBoundsChanged(const gfx::Rect& new_bounds) override {} |
| 138 void OnDamageRect(const gfx::Rect& damaged_region) override {} |
| 139 void DispatchEvent(ui::Event* event) override { |
| 140 if (event->IsKeyEvent() && |
| 141 static_cast<ui::KeyEvent*>(event)->code() == ui::DomCode::KEY_Q) |
| 142 Quit(); |
| 143 } |
| 144 void OnCloseRequest() override { Quit(); } |
| 145 void OnClosed() override {} |
| 146 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {} |
| 147 void OnLostCapture() override {} |
| 148 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget, |
| 149 float device_pixel_ratio) override { |
| 150 LOG(INFO) << "OnAcceleratedWidgetAvailable " << widget; |
| 151 DCHECK_NE(widget, gfx::kNullAcceleratedWidget); |
| 152 widget_ = widget; |
| 153 } |
| 154 void OnActivationChanged(bool active) override {} |
| 155 |
| 156 private: |
| 157 // Since we pretend to have a GPU process, we should also pretend to |
| 158 // initialize the GPU resources via a posted task. |
| 159 void StartOnGpu() { |
| 160 LOG(INFO) << "StartOnGPU"; |
| 161 gfx::GLSurface::InitializeOneOff(); |
| 162 |
| 163 renderer_ = |
| 164 renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize()); |
| 165 renderer_->Initialize(); |
| 166 } |
| 167 |
| 168 WindowManager* window_manager_; // Not owned. |
| 169 RendererFactory* renderer_factory_; // Not owned. |
| 170 |
| 171 scoped_ptr<ui::Renderer> renderer_; |
| 172 |
| 173 // Window-related state. |
| 174 scoped_ptr<ui::PlatformWindow> platform_window_; |
| 175 gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget; |
| 176 |
| 177 base::WeakPtrFactory<DemoWindow> weak_ptr_factory_; |
| 178 |
| 179 DISALLOW_COPY_AND_ASSIGN(DemoWindow); |
| 180 }; |
| 181 |
| 182 /////////////////////////////////////////////////////////////////////////////// |
| 183 // RendererFactory implementation: |
| 184 |
| 185 RendererFactory::RendererFactory() { |
| 186 } |
| 187 |
| 188 RendererFactory::~RendererFactory() { |
| 189 } |
| 190 |
| 191 bool RendererFactory::Initialize() { |
| 192 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 193 if (!command_line->HasSwitch(kDisableGpu) && |
| 194 gpu_helper_.Initialize(base::ThreadTaskRunnerHandle::Get(), |
| 195 base::ThreadTaskRunnerHandle::Get())) { |
| 196 if (command_line->HasSwitch(switches::kOzoneUseSurfaceless)) { |
| 197 type_ = SURFACELESS_GL; |
| 198 } else { |
| 199 type_ = GL; |
| 200 } |
| 201 } else { |
| 202 type_ = SOFTWARE; |
| 203 } |
| 204 |
| 205 return true; |
| 206 } |
| 207 |
| 208 scoped_ptr<ui::Renderer> RendererFactory::CreateRenderer( |
| 209 gfx::AcceleratedWidget widget, |
| 210 const gfx::Size& size) { |
| 211 switch (type_) { |
| 212 case GL: |
| 213 return make_scoped_ptr(new ui::GlRenderer(widget, size)); |
| 214 case SURFACELESS_GL: |
| 215 return make_scoped_ptr( |
| 216 new ui::SurfacelessGlRenderer(widget, size, &buffer_factory_)); |
| 217 case SOFTWARE: |
| 218 return make_scoped_ptr(new ui::SoftwareRenderer(widget, size)); |
| 219 } |
| 220 |
| 221 return nullptr; |
| 222 } |
| 223 |
| 224 /////////////////////////////////////////////////////////////////////////////// |
| 225 // WindowManager implementation: |
| 226 |
| 227 WindowManager::WindowManager(const base::Closure& quit_closure) |
| 228 : delegate_( |
| 229 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()), |
| 230 quit_closure_(quit_closure) { |
| 231 if (!renderer_factory_.Initialize()) |
| 232 LOG(FATAL) << "Failed to initialize renderer factory"; |
| 233 |
| 234 LOG(INFO) << "WindowManager() " << delegate_; |
| 235 |
| 236 if (delegate_) { |
| 237 delegate_->AddObserver(this); |
| 238 delegate_->Initialize(); |
| 239 OnConfigurationChanged(); |
| 240 } else { |
| 241 LOG(WARNING) << "No display delegate; falling back to test window"; |
| 242 int width = kTestWindowWidth; |
| 243 int height = kTestWindowHeight; |
| 244 sscanf(base::CommandLine::ForCurrentProcess() |
| 245 ->GetSwitchValueASCII(kWindowSize) |
| 246 .c_str(), |
| 247 "%dx%d", &width, &height); |
| 248 |
| 249 DemoWindow* window = new DemoWindow(this, &renderer_factory_, |
| 250 gfx::Rect(gfx::Size(width, height))); |
| 251 window->Start(); |
| 252 } |
| 253 } |
| 254 |
| 255 WindowManager::~WindowManager() { |
| 256 if (delegate_) |
| 257 delegate_->RemoveObserver(this); |
| 258 } |
| 259 |
| 260 void WindowManager::Quit() { |
| 261 quit_closure_.Run(); |
| 262 } |
| 263 |
| 264 void WindowManager::OnConfigurationChanged() { |
| 265 if (is_configuring_) { |
| 266 should_configure_ = true; |
| 267 return; |
| 268 } |
| 269 |
| 270 is_configuring_ = true; |
| 271 delegate_->GrabServer(); |
| 272 delegate_->GetDisplays( |
| 273 base::Bind(&WindowManager::OnDisplaysAquired, base::Unretained(this))); |
| 274 } |
| 275 |
| 276 void WindowManager::OnDisplaysAquired( |
| 277 const std::vector<ui::DisplaySnapshot*>& displays) { |
| 278 windows_.clear(); |
| 279 |
| 280 gfx::Point origin; |
| 281 for (auto display : displays) { |
| 282 if (!display->native_mode()) { |
| 283 LOG(ERROR) << "Display " << display->display_id() |
| 284 << " doesn't have a native mode"; |
| 285 continue; |
| 286 } |
| 287 |
| 288 delegate_->Configure( |
| 289 *display, display->native_mode(), origin, |
| 290 base::Bind(&WindowManager::OnDisplayConfigured, base::Unretained(this), |
| 291 gfx::Rect(origin, display->native_mode()->size()))); |
| 292 origin.Offset(display->native_mode()->size().width(), 0); |
| 293 } |
| 294 delegate_->UngrabServer(); |
| 295 is_configuring_ = false; |
| 296 |
| 297 if (should_configure_) { |
| 298 should_configure_ = false; |
| 299 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 300 FROM_HERE, base::Bind(&WindowManager::OnConfigurationChanged, |
| 301 base::Unretained(this))); |
| 302 } |
| 303 } |
| 304 |
| 305 void WindowManager::OnDisplayConfigured(const gfx::Rect& bounds, bool success) { |
| 306 LOG(INFO) << "OnDisplayConfigured " << success; |
| 307 if (success) { |
| 308 scoped_ptr<DemoWindow> window( |
| 309 new DemoWindow(this, &renderer_factory_, bounds)); |
| 310 window->Start(); |
| 311 windows_.push_back(window.Pass()); |
| 312 } else { |
| 313 LOG(ERROR) << "Failed to configure display at " << bounds.ToString(); |
| 314 } |
| 315 } |
| 316 |
| 317 int main(int argc, char** argv) { |
| 318 base::CommandLine::Init(argc, argv); |
| 319 base::AtExitManager exit_manager; |
| 320 |
| 321 // Initialize logging so we can enable VLOG messages. |
| 322 logging::LoggingSettings settings; |
| 323 logging::InitLogging(settings); |
| 324 |
| 325 // Build UI thread message loop. This is used by platform |
| 326 // implementations for event polling & running background tasks. |
| 327 base::MessageLoopForUI message_loop; |
| 328 |
| 329 ui::OzonePlatform::InitializeForUI(); |
| 330 LOG(INFO) << "InitializeForUI complete"; |
| 331 |
| 332 ui::OzonePlatform::InitializeForGPU(); |
| 333 LOG(INFO) << "InitializeForGPU complete"; |
| 334 |
| 335 ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine() |
| 336 ->SetCurrentLayoutByName("us"); |
| 337 |
| 338 base::RunLoop run_loop; |
| 339 |
| 340 WindowManager window_manager(run_loop.QuitClosure()); |
| 341 |
| 342 LOG(INFO) << "demo entering run loop"; |
| 343 run_loop.Run(); |
| 344 LOG(INFO) << "demo returning from run loop"; |
| 345 |
| 346 return 0; |
| 347 } |
| OLD | NEW |