Chromium Code Reviews| Index: ui/ozone/demo/ozone_demo.cc |
| diff --git a/ui/ozone/demo/ozone_demo.cc b/ui/ozone/demo/ozone_demo.cc |
| index 32d7fde700b5e46cc1fd03965ce0f80f0cd0e837..5fb43f9e3e72d5dbf809705d6a171553088edf69 100644 |
| --- a/ui/ozone/demo/ozone_demo.cc |
| +++ b/ui/ozone/demo/ozone_demo.cc |
| @@ -4,9 +4,14 @@ |
| #include "base/at_exit.h" |
| #include "base/command_line.h" |
| +#include "base/memory/scoped_vector.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/run_loop.h" |
| +#include "base/thread_task_runner_handle.h" |
| #include "base/timer/timer.h" |
| +#include "ui/display/types/display_snapshot.h" |
| +#include "ui/display/types/native_display_delegate.h" |
| +#include "ui/display/types/native_display_observer.h" |
| #include "ui/events/event.h" |
| #include "ui/events/keycodes/dom3/dom_code.h" |
| #include "ui/events/ozone/layout/keyboard_layout_engine.h" |
| @@ -17,6 +22,7 @@ |
| #include "ui/ozone/demo/gl_renderer.h" |
| #include "ui/ozone/demo/software_renderer.h" |
| #include "ui/ozone/demo/surfaceless_gl_renderer.h" |
| +#include "ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h" |
| #include "ui/ozone/public/ozone_platform.h" |
| #include "ui/ozone/public/ozone_switches.h" |
| #include "ui/ozone/public/ui_thread_gpu.h" |
| @@ -32,18 +38,71 @@ const char kDisableGpu[] = "disable-gpu"; |
| const char kWindowSize[] = "window-size"; |
| -class DemoWindow : public ui::PlatformWindowDelegate { |
| +class DemoWindow; |
| + |
| +class RendererFactory { |
| public: |
| - DemoWindow() : widget_(gfx::kNullAcceleratedWidget) { |
| - int width = kTestWindowWidth; |
| - int height = kTestWindowHeight; |
| - sscanf(base::CommandLine::ForCurrentProcess() |
| - ->GetSwitchValueASCII(kWindowSize) |
| - .c_str(), |
| - "%dx%d", &width, &height); |
| + enum RendererType { |
| + GL, |
| + SURFACELESS_GL, |
| + SOFTWARE, |
| + }; |
| + |
| + RendererFactory(); |
| + ~RendererFactory(); |
| + |
| + bool Initialize(); |
| + scoped_ptr<ui::Renderer> CreateRenderer(gfx::AcceleratedWidget widget, |
| + const gfx::Size& size); |
| + |
| + private: |
| + RendererType type_; |
| + |
| + // Helper for applications that do GL on main thread. |
| + ui::UiThreadGpu ui_thread_gpu_; |
| + |
| + // Used by the surfaceless renderers to allocate buffers. |
| + ui::GpuMemoryBufferFactoryOzoneNativeBuffer buffer_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(RendererFactory); |
| +}; |
| + |
| +class WindowManager : public ui::NativeDisplayObserver { |
| + public: |
| + WindowManager(const base::Closure& quit_closure); |
| + ~WindowManager() override; |
| + |
| + void Quit(); |
| + |
| + void AddWindow(DemoWindow* window); |
| + void RemoveWindow(DemoWindow* window); |
| + |
| + private: |
| + void OnGetDisplays(const std::vector<ui::DisplaySnapshot*>& displays); |
| + void OnDisplayConfigured(const gfx::Rect& bounds, bool success); |
| - platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( |
| - this, gfx::Rect(width, height)); |
| + // ui::NativeDisplayDelegate: |
| + void OnConfigurationChanged() override; |
| + |
| + scoped_ptr<ui::NativeDisplayDelegate> delegate_; |
| + base::Closure quit_closure_; |
| + RendererFactory renderer_factory_; |
| + ScopedVector<DemoWindow> windows_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(WindowManager); |
| +}; |
| + |
| +class DemoWindow : public ui::PlatformWindowDelegate { |
| + public: |
| + DemoWindow(WindowManager* window_manager, |
| + RendererFactory* renderer_factory, |
| + const gfx::Rect& bounds) |
| + : window_manager_(window_manager), |
| + renderer_factory_(renderer_factory), |
| + widget_(gfx::kNullAcceleratedWidget), |
| + weak_ptr_factory_(this) { |
| + platform_window_ = |
| + ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds); |
| } |
| ~DemoWindow() override {} |
| @@ -56,61 +115,52 @@ class DemoWindow : public ui::PlatformWindowDelegate { |
| gfx::Size GetSize() { return platform_window_->GetBounds().size(); } |
| - void Start(const base::Closure& quit_closure) { |
| - quit_closure_ = quit_closure; |
| - |
| - if (!base::CommandLine::ForCurrentProcess()->HasSwitch(kDisableGpu) && |
| - gfx::GLSurface::InitializeOneOff() && StartInProcessGpu()) { |
| - if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| - switches::kOzoneUseSurfaceless)) { |
| - renderer_.reset( |
| - new ui::SurfacelessGlRenderer(GetAcceleratedWidget(), GetSize())); |
| - } else { |
| - renderer_.reset(new ui::GlRenderer(GetAcceleratedWidget(), GetSize())); |
| - } |
| - } else { |
| - renderer_.reset( |
| - new ui::SoftwareRenderer(GetAcceleratedWidget(), GetSize())); |
| - } |
| - |
| - if (renderer_->Initialize()) { |
| - timer_.Start(FROM_HERE, |
| - base::TimeDelta::FromMilliseconds(kFrameDelayMilliseconds), |
| - renderer_.get(), &ui::Renderer::RenderFrame); |
| - } else { |
| - LOG(ERROR) << "Failed to create drawing surface"; |
| - Quit(); |
| - } |
| + void Start() { |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&DemoWindow::StartOnGpu, weak_ptr_factory_.GetWeakPtr())); |
| } |
| void Quit() { |
| StopAnimation(); |
| - quit_closure_.Run(); |
| - } |
| + window_manager_->Quit(); |
| + } |
| // PlatformWindowDelegate: |
| - void OnBoundsChanged(const gfx::Rect& new_bounds) override {} |
| - void OnDamageRect(const gfx::Rect& damaged_region) override {} |
| - void DispatchEvent(ui::Event* event) override { |
| - if (event->IsKeyEvent() && |
| - static_cast<ui::KeyEvent*>(event)->code() == ui::DomCode::KEY_Q) |
| - Quit(); |
| - } |
| - void OnCloseRequest() override { Quit(); } |
| - void OnClosed() override {} |
| - void OnWindowStateChanged(ui::PlatformWindowState new_state) override {} |
| - void OnLostCapture() override {} |
| - void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override { |
| + void OnBoundsChanged(const gfx::Rect& new_bounds) override {} |
| + void OnDamageRect(const gfx::Rect& damaged_region) override {} |
| + void DispatchEvent(ui::Event* event) override { |
| + if (event->IsKeyEvent() && |
| + static_cast<ui::KeyEvent*>(event)->code() == ui::DomCode::KEY_Q) |
| + Quit(); |
| + } |
| + void OnCloseRequest() override { Quit(); } |
| + void OnClosed() override {} |
| + void OnWindowStateChanged(ui::PlatformWindowState new_state) override {} |
| + void OnLostCapture() override {} |
| + void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override { |
| DCHECK_NE(widget, gfx::kNullAcceleratedWidget); |
| widget_ = widget; |
| } |
| void OnActivationChanged(bool active) override {} |
| private: |
| + // Since we pretend to have a GPU process, we should also pretend to |
| + // initialize the GPU resources via a posted task. |
| + void StartOnGpu() { |
| + renderer_ = |
| + renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize()); |
| + if (renderer_->Initialize()) { |
| + timer_.Start(FROM_HERE, |
| + base::TimeDelta::FromMilliseconds(kFrameDelayMilliseconds), |
| + renderer_.get(), &ui::Renderer::RenderFrame); |
| + } |
| + } |
| void StopAnimation() { timer_.Stop(); } |
| - bool StartInProcessGpu() { return ui_thread_gpu_.Initialize(); } |
| + WindowManager* window_manager_; // Not owned. |
| + RendererFactory* renderer_factory_; // Not owned. |
| scoped_ptr<ui::Renderer> renderer_; |
| @@ -121,14 +171,128 @@ class DemoWindow : public ui::PlatformWindowDelegate { |
| scoped_ptr<ui::PlatformWindow> platform_window_; |
| gfx::AcceleratedWidget widget_; |
| - // Helper for applications that do GL on main thread. |
| - ui::UiThreadGpu ui_thread_gpu_; |
| - |
| - base::Closure quit_closure_; |
| + base::WeakPtrFactory<DemoWindow> weak_ptr_factory_; |
| DISALLOW_COPY_AND_ASSIGN(DemoWindow); |
| }; |
| +/////////////////////////////////////////////////////////////////////////////// |
| +// RendererFactory implementation: |
| + |
| +RendererFactory::RendererFactory() : type_(SOFTWARE) { |
| +} |
| + |
| +RendererFactory::~RendererFactory() { |
| +} |
| + |
| +bool RendererFactory::Initialize() { |
| + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
| + if (!command_line->HasSwitch(kDisableGpu) && |
| + gfx::GLSurface::InitializeOneOff() && ui_thread_gpu_.Initialize()) { |
| + if (command_line->HasSwitch(switches::kOzoneUseSurfaceless)) { |
| + type_ = SURFACELESS_GL; |
| + } else { |
| + type_ = GL; |
| + } |
| + } else { |
| + type_ = SOFTWARE; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +scoped_ptr<ui::Renderer> RendererFactory::CreateRenderer( |
| + gfx::AcceleratedWidget widget, |
| + const gfx::Size& size) { |
| + switch (type_) { |
| + case GL: |
| + return scoped_ptr<ui::Renderer>(new ui::GlRenderer(widget, size)); |
| + case SURFACELESS_GL: |
| + return scoped_ptr<ui::Renderer>( |
| + new ui::SurfacelessGlRenderer(widget, size, &buffer_factory_)); |
| + case SOFTWARE: |
| + return scoped_ptr<ui::Renderer>(new ui::SoftwareRenderer(widget, size)); |
| + } |
| + |
| + 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.
|
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| +// WindowManager implementation: |
| + |
| +WindowManager::WindowManager(const base::Closure& quit_closure) |
| + : delegate_( |
| + ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()), |
| + quit_closure_(quit_closure) { |
| + if (!renderer_factory_.Initialize()) |
| + LOG(FATAL) << "Failed to initialize renderer factory"; |
| + |
| + if (delegate_) { |
| + delegate_->AddObserver(this); |
| + delegate_->Initialize(); |
| + OnConfigurationChanged(); |
| + } else { |
| + LOG(WARNING) << "No display delegate; falling back to test window"; |
| + int width = kTestWindowWidth; |
| + int height = kTestWindowHeight; |
| + sscanf(base::CommandLine::ForCurrentProcess() |
| + ->GetSwitchValueASCII(kWindowSize) |
| + .c_str(), |
| + "%dx%d", &width, &height); |
| + |
| + DemoWindow* window = new DemoWindow(this, &renderer_factory_, |
| + gfx::Rect(gfx::Size(width, height))); |
| + window->Start(); |
| + } |
| +} |
| + |
| +WindowManager::~WindowManager() { |
| + if (delegate_) |
| + delegate_->RemoveObserver(this); |
| +} |
| + |
| +void WindowManager::Quit() { |
| + quit_closure_.Run(); |
| +} |
| + |
| +void WindowManager::OnConfigurationChanged() { |
| + delegate_->GrabServer(); |
| + delegate_->GetDisplays( |
| + base::Bind(&WindowManager::OnGetDisplays, base::Unretained(this))); |
| +} |
| + |
| +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.
|
| + const std::vector<ui::DisplaySnapshot*>& displays) { |
| + windows_.clear(); |
| + |
| + gfx::Point origin; |
| + for (auto display : displays) { |
| + if (!display->native_mode()) { |
| + LOG(ERROR) << "Display " << display->display_id() |
| + << " doesn't have a native mode"; |
| + continue; |
| + } |
| + |
| + delegate_->Configure( |
| + *display, display->native_mode(), origin, |
| + base::Bind(&WindowManager::OnDisplayConfigured, base::Unretained(this), |
| + gfx::Rect(origin, display->native_mode()->size()))); |
| + origin.Offset(display->native_mode()->size().width(), 0); |
| + } |
| + delegate_->UngrabServer(); |
| +} |
| + |
| +void WindowManager::OnDisplayConfigured(const gfx::Rect& bounds, bool success) { |
| + if (success) { |
| + scoped_ptr<DemoWindow> window( |
| + new DemoWindow(this, &renderer_factory_, bounds)); |
| + window->Start(); |
| + windows_.push_back(window.release()); |
| + } else { |
| + LOG(ERROR) << "Failed to configure display at " << bounds.ToString(); |
| + } |
| +} |
| + |
| int main(int argc, char** argv) { |
| base::CommandLine::Init(argc, argv); |
| base::AtExitManager exit_manager; |
| @@ -143,8 +307,7 @@ int main(int argc, char** argv) { |
| base::RunLoop run_loop; |
| - scoped_ptr<DemoWindow> window(new DemoWindow); |
| - window->Start(run_loop.QuitClosure()); |
| + WindowManager window_manager(run_loop.QuitClosure()); |
| run_loop.Run(); |