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) override { |
| 149 LOG(INFO) << "OnAcceleratedWidgetAvailable " << widget; |
| 150 DCHECK_NE(widget, gfx::kNullAcceleratedWidget); |
| 151 widget_ = widget; |
| 152 } |
| 153 void OnActivationChanged(bool active) override {} |
| 154 |
| 155 private: |
| 156 // Since we pretend to have a GPU process, we should also pretend to |
| 157 // initialize the GPU resources via a posted task. |
| 158 void StartOnGpu() { |
| 159 LOG(INFO) << "StartOnGPU"; |
| 160 gfx::GLSurface::InitializeOneOff(); |
| 161 |
| 162 renderer_ = |
| 163 renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize()); |
| 164 renderer_->Initialize(); |
| 165 } |
| 166 |
| 167 WindowManager* window_manager_; // Not owned. |
| 168 RendererFactory* renderer_factory_; // Not owned. |
| 169 |
| 170 scoped_ptr<ui::Renderer> renderer_; |
| 171 |
| 172 // Window-related state. |
| 173 scoped_ptr<ui::PlatformWindow> platform_window_; |
| 174 gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget; |
| 175 |
| 176 base::WeakPtrFactory<DemoWindow> weak_ptr_factory_; |
| 177 |
| 178 DISALLOW_COPY_AND_ASSIGN(DemoWindow); |
| 179 }; |
| 180 |
| 181 /////////////////////////////////////////////////////////////////////////////// |
| 182 // RendererFactory implementation: |
| 183 |
| 184 RendererFactory::RendererFactory() { |
| 185 } |
| 186 |
| 187 RendererFactory::~RendererFactory() { |
| 188 } |
| 189 |
| 190 bool RendererFactory::Initialize() { |
| 191 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| 192 if (!command_line->HasSwitch(kDisableGpu) && |
| 193 gpu_helper_.Initialize(base::ThreadTaskRunnerHandle::Get(), |
| 194 base::ThreadTaskRunnerHandle::Get())) { |
| 195 if (command_line->HasSwitch(switches::kOzoneUseSurfaceless)) { |
| 196 type_ = SURFACELESS_GL; |
| 197 } else { |
| 198 type_ = GL; |
| 199 } |
| 200 } else { |
| 201 type_ = SOFTWARE; |
| 202 } |
| 203 |
| 204 return true; |
| 205 } |
| 206 |
| 207 scoped_ptr<ui::Renderer> RendererFactory::CreateRenderer( |
| 208 gfx::AcceleratedWidget widget, |
| 209 const gfx::Size& size) { |
| 210 switch (type_) { |
| 211 case GL: |
| 212 return make_scoped_ptr(new ui::GlRenderer(widget, size)); |
| 213 case SURFACELESS_GL: |
| 214 return make_scoped_ptr( |
| 215 new ui::SurfacelessGlRenderer(widget, size, &buffer_factory_)); |
| 216 case SOFTWARE: |
| 217 return make_scoped_ptr(new ui::SoftwareRenderer(widget, size)); |
| 218 } |
| 219 |
| 220 return nullptr; |
| 221 } |
| 222 |
| 223 /////////////////////////////////////////////////////////////////////////////// |
| 224 // WindowManager implementation: |
| 225 |
| 226 WindowManager::WindowManager(const base::Closure& quit_closure) |
| 227 : delegate_( |
| 228 ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()), |
| 229 quit_closure_(quit_closure) { |
| 230 if (!renderer_factory_.Initialize()) |
| 231 LOG(FATAL) << "Failed to initialize renderer factory"; |
| 232 |
| 233 LOG(INFO) << "WindowManager() " << delegate_; |
| 234 |
| 235 if (delegate_) { |
| 236 delegate_->AddObserver(this); |
| 237 delegate_->Initialize(); |
| 238 OnConfigurationChanged(); |
| 239 } else { |
| 240 LOG(WARNING) << "No display delegate; falling back to test window"; |
| 241 int width = kTestWindowWidth; |
| 242 int height = kTestWindowHeight; |
| 243 sscanf(base::CommandLine::ForCurrentProcess() |
| 244 ->GetSwitchValueASCII(kWindowSize) |
| 245 .c_str(), |
| 246 "%dx%d", &width, &height); |
| 247 |
| 248 DemoWindow* window = new DemoWindow(this, &renderer_factory_, |
| 249 gfx::Rect(gfx::Size(width, height))); |
| 250 window->Start(); |
| 251 } |
| 252 } |
| 253 |
| 254 WindowManager::~WindowManager() { |
| 255 if (delegate_) |
| 256 delegate_->RemoveObserver(this); |
| 257 } |
| 258 |
| 259 void WindowManager::Quit() { |
| 260 quit_closure_.Run(); |
| 261 } |
| 262 |
| 263 void WindowManager::OnConfigurationChanged() { |
| 264 if (is_configuring_) { |
| 265 should_configure_ = true; |
| 266 return; |
| 267 } |
| 268 |
| 269 is_configuring_ = true; |
| 270 delegate_->GrabServer(); |
| 271 delegate_->GetDisplays( |
| 272 base::Bind(&WindowManager::OnDisplaysAquired, base::Unretained(this))); |
| 273 } |
| 274 |
| 275 void WindowManager::OnDisplaysAquired( |
| 276 const std::vector<ui::DisplaySnapshot*>& displays) { |
| 277 windows_.clear(); |
| 278 |
| 279 gfx::Point origin; |
| 280 for (auto display : displays) { |
| 281 if (!display->native_mode()) { |
| 282 LOG(ERROR) << "Display " << display->display_id() |
| 283 << " doesn't have a native mode"; |
| 284 continue; |
| 285 } |
| 286 |
| 287 delegate_->Configure( |
| 288 *display, display->native_mode(), origin, |
| 289 base::Bind(&WindowManager::OnDisplayConfigured, base::Unretained(this), |
| 290 gfx::Rect(origin, display->native_mode()->size()))); |
| 291 origin.Offset(display->native_mode()->size().width(), 0); |
| 292 } |
| 293 delegate_->UngrabServer(); |
| 294 is_configuring_ = false; |
| 295 |
| 296 if (should_configure_) { |
| 297 should_configure_ = false; |
| 298 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 299 FROM_HERE, base::Bind(&WindowManager::OnConfigurationChanged, |
| 300 base::Unretained(this))); |
| 301 } |
| 302 } |
| 303 |
| 304 void WindowManager::OnDisplayConfigured(const gfx::Rect& bounds, bool success) { |
| 305 LOG(INFO) << "OnDisplayConfigured " << success; |
| 306 if (success) { |
| 307 scoped_ptr<DemoWindow> window( |
| 308 new DemoWindow(this, &renderer_factory_, bounds)); |
| 309 window->Start(); |
| 310 windows_.push_back(window.Pass()); |
| 311 } else { |
| 312 LOG(ERROR) << "Failed to configure display at " << bounds.ToString(); |
| 313 } |
| 314 } |
| 315 |
| 316 int main(int argc, char** argv) { |
| 317 base::CommandLine::Init(argc, argv); |
| 318 base::AtExitManager exit_manager; |
| 319 |
| 320 // Initialize logging so we can enable VLOG messages. |
| 321 logging::LoggingSettings settings; |
| 322 logging::InitLogging(settings); |
| 323 |
| 324 // Build UI thread message loop. This is used by platform |
| 325 // implementations for event polling & running background tasks. |
| 326 base::MessageLoopForUI message_loop; |
| 327 |
| 328 ui::OzonePlatform::InitializeForUI(); |
| 329 LOG(INFO) << "InitializeForUI complete"; |
| 330 |
| 331 ui::OzonePlatform::InitializeForGPU(); |
| 332 LOG(INFO) << "InitializeForGPU complete"; |
| 333 |
| 334 ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine() |
| 335 ->SetCurrentLayoutByName("us"); |
| 336 |
| 337 base::RunLoop run_loop; |
| 338 |
| 339 WindowManager window_manager(run_loop.QuitClosure()); |
| 340 |
| 341 LOG(INFO) << "demo entering run loop"; |
| 342 run_loop.Run(); |
| 343 LOG(INFO) << "demo returning from run loop"; |
| 344 |
| 345 return 0; |
| 346 } |
OLD | NEW |