| Index: ui/ozone/demo/ozone_demo.cc
|
| diff --git a/ui/ozone/demo/ozone_demo.cc b/ui/ozone/demo/ozone_demo.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..534b9141bc030777484610d6a9ab5ceb574d6206
|
| --- /dev/null
|
| +++ b/ui/ozone/demo/ozone_demo.cc
|
| @@ -0,0 +1,346 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#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 "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/dom/dom_code.h"
|
| +#include "ui/events/ozone/layout/keyboard_layout_engine.h"
|
| +#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
|
| +#include "ui/gfx/geometry/rect.h"
|
| +#include "ui/gfx/geometry/size.h"
|
| +#include "ui/gl/gl_surface.h"
|
| +#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_gpu_test_helper.h"
|
| +#include "ui/ozone/public/ozone_platform.h"
|
| +#include "ui/ozone/public/ozone_switches.h"
|
| +#include "ui/platform_window/platform_window.h"
|
| +#include "ui/platform_window/platform_window_delegate.h"
|
| +
|
| +const int kTestWindowWidth = 800;
|
| +const int kTestWindowHeight = 600;
|
| +
|
| +const char kDisableGpu[] = "disable-gpu";
|
| +
|
| +const char kWindowSize[] = "window-size";
|
| +
|
| +class DemoWindow;
|
| +
|
| +class RendererFactory {
|
| + public:
|
| + 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_ = SOFTWARE;
|
| +
|
| + // Helper for applications that do GL on main thread.
|
| + ui::OzoneGpuTestHelper gpu_helper_;
|
| +
|
| + // 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 OnDisplaysAquired(const std::vector<ui::DisplaySnapshot*>& displays);
|
| + void OnDisplayConfigured(const gfx::Rect& bounds, bool success);
|
| +
|
| + // ui::NativeDisplayDelegate:
|
| + void OnConfigurationChanged() override;
|
| +
|
| + scoped_ptr<ui::NativeDisplayDelegate> delegate_;
|
| + base::Closure quit_closure_;
|
| + RendererFactory renderer_factory_;
|
| + ScopedVector<DemoWindow> windows_;
|
| +
|
| + // Flags used to keep track of the current state of display configuration.
|
| + //
|
| + // True if configuring the displays. In this case a new display configuration
|
| + // isn't started.
|
| + bool is_configuring_ = false;
|
| +
|
| + // If |is_configuring_| is true and another display configuration event
|
| + // happens, the event is deferred. This is set to true and a display
|
| + // configuration will be scheduled after the current one finishes.
|
| + bool should_configure_ = false;
|
| +
|
| + 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),
|
| + weak_ptr_factory_(this) {
|
| + platform_window_ =
|
| + ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds);
|
| + }
|
| + ~DemoWindow() override {}
|
| +
|
| + gfx::AcceleratedWidget GetAcceleratedWidget() {
|
| + // TODO(spang): We should start rendering asynchronously.
|
| + DCHECK_NE(widget_, gfx::kNullAcceleratedWidget)
|
| + << "Widget not available synchronously";
|
| + return widget_;
|
| + }
|
| +
|
| + gfx::Size GetSize() { return platform_window_->GetBounds().size(); }
|
| +
|
| + void Start() {
|
| + LOG(INFO) << "DemoWindow::Start";
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&DemoWindow::StartOnGpu, weak_ptr_factory_.GetWeakPtr()));
|
| + }
|
| +
|
| + void Quit() {
|
| + 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 {
|
| + LOG(INFO) << "OnAcceleratedWidgetAvailable " << widget;
|
| + 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() {
|
| + LOG(INFO) << "StartOnGPU";
|
| + gfx::GLSurface::InitializeOneOff();
|
| +
|
| + renderer_ =
|
| + renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize());
|
| + renderer_->Initialize();
|
| + }
|
| +
|
| + WindowManager* window_manager_; // Not owned.
|
| + RendererFactory* renderer_factory_; // Not owned.
|
| +
|
| + scoped_ptr<ui::Renderer> renderer_;
|
| +
|
| + // Window-related state.
|
| + scoped_ptr<ui::PlatformWindow> platform_window_;
|
| + gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
|
| +
|
| + base::WeakPtrFactory<DemoWindow> weak_ptr_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DemoWindow);
|
| +};
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// RendererFactory implementation:
|
| +
|
| +RendererFactory::RendererFactory() {
|
| +}
|
| +
|
| +RendererFactory::~RendererFactory() {
|
| +}
|
| +
|
| +bool RendererFactory::Initialize() {
|
| + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
| + if (!command_line->HasSwitch(kDisableGpu) &&
|
| + gpu_helper_.Initialize(base::ThreadTaskRunnerHandle::Get(),
|
| + base::ThreadTaskRunnerHandle::Get())) {
|
| + 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 make_scoped_ptr(new ui::GlRenderer(widget, size));
|
| + case SURFACELESS_GL:
|
| + return make_scoped_ptr(
|
| + new ui::SurfacelessGlRenderer(widget, size, &buffer_factory_));
|
| + case SOFTWARE:
|
| + return make_scoped_ptr(new ui::SoftwareRenderer(widget, size));
|
| + }
|
| +
|
| + return nullptr;
|
| +}
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +// 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";
|
| +
|
| + LOG(INFO) << "WindowManager() " << delegate_;
|
| +
|
| + 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() {
|
| + if (is_configuring_) {
|
| + should_configure_ = true;
|
| + return;
|
| + }
|
| +
|
| + is_configuring_ = true;
|
| + delegate_->GrabServer();
|
| + delegate_->GetDisplays(
|
| + base::Bind(&WindowManager::OnDisplaysAquired, base::Unretained(this)));
|
| +}
|
| +
|
| +void WindowManager::OnDisplaysAquired(
|
| + 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();
|
| + is_configuring_ = false;
|
| +
|
| + if (should_configure_) {
|
| + should_configure_ = false;
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE, base::Bind(&WindowManager::OnConfigurationChanged,
|
| + base::Unretained(this)));
|
| + }
|
| +}
|
| +
|
| +void WindowManager::OnDisplayConfigured(const gfx::Rect& bounds, bool success) {
|
| + LOG(INFO) << "OnDisplayConfigured " << success;
|
| + if (success) {
|
| + scoped_ptr<DemoWindow> window(
|
| + new DemoWindow(this, &renderer_factory_, bounds));
|
| + window->Start();
|
| + windows_.push_back(window.Pass());
|
| + } 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;
|
| +
|
| + // Initialize logging so we can enable VLOG messages.
|
| + logging::LoggingSettings settings;
|
| + logging::InitLogging(settings);
|
| +
|
| + // Build UI thread message loop. This is used by platform
|
| + // implementations for event polling & running background tasks.
|
| + base::MessageLoopForUI message_loop;
|
| +
|
| + ui::OzonePlatform::InitializeForUI();
|
| + LOG(INFO) << "InitializeForUI complete";
|
| +
|
| + ui::OzonePlatform::InitializeForGPU();
|
| + LOG(INFO) << "InitializeForGPU complete";
|
| +
|
| + ui::KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()
|
| + ->SetCurrentLayoutByName("us");
|
| +
|
| + base::RunLoop run_loop;
|
| +
|
| + WindowManager window_manager(run_loop.QuitClosure());
|
| +
|
| + LOG(INFO) << "demo entering run loop";
|
| + run_loop.Run();
|
| + LOG(INFO) << "demo returning from run loop";
|
| +
|
| + return 0;
|
| +}
|
|
|