Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Unified Diff: ui/ozone/demo/ozone_demo.cc

Issue 805003002: [Ozone-Demo] Add support for NativeDisplayDelegate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ozone-demo2
Patch Set: . Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/ozone/demo/gl_renderer.cc ('k') | ui/ozone/demo/surfaceless_gl_renderer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..4b44c255e0e3fa63b25f3b06476e9c9da9d983b6 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,82 @@ 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 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_;
- platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
- this, gfx::Rect(width, height));
+ // 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_;
+
+ 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 +126,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,18 +182,152 @@ 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;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// WindowManager implementation:
+
+WindowManager::WindowManager(const base::Closure& quit_closure)
+ : delegate_(
+ ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate()),
+ quit_closure_(quit_closure),
+ is_configuring_(false),
+ should_configure_(false) {
+ 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() {
+ 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) {
+ 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;
+ // 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;
@@ -143,8 +338,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();
« no previous file with comments | « ui/ozone/demo/gl_renderer.cc ('k') | ui/ozone/demo/surfaceless_gl_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698