Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / ui / ozone / demo / ozone_demo.cc
blob2d4dbf428696da6a38175d8a94ae827e43339a47
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.
5 #include "base/at_exit.h"
6 #include "base/command_line.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/timer/timer.h"
10 #include "third_party/skia/include/core/SkCanvas.h"
11 #include "third_party/skia/include/core/SkColor.h"
12 #include "ui/gfx/geometry/size.h"
13 #include "ui/gl/gl_bindings.h"
14 #include "ui/gl/gl_context.h"
15 #include "ui/gl/gl_surface.h"
16 #include "ui/ozone/public/ozone_platform.h"
17 #include "ui/ozone/public/surface_factory_ozone.h"
18 #include "ui/ozone/public/surface_ozone_canvas.h"
19 #include "ui/ozone/public/ui_thread_gpu.h"
20 #include "ui/platform_window/platform_window.h"
21 #include "ui/platform_window/platform_window_delegate.h"
23 const int kTestWindowWidth = 800;
24 const int kTestWindowHeight = 600;
26 const int kFrameDelayMilliseconds = 16;
28 const int kAnimationSteps = 240;
30 const char kDisableGpu[] = "disable-gpu";
32 class DemoWindow : public ui::PlatformWindowDelegate {
33 public:
34 DemoWindow() : widget_(gfx::kNullAcceleratedWidget), iteration_(0) {
35 platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
36 this, gfx::Rect(kTestWindowWidth, kTestWindowHeight));
38 ~DemoWindow() override {}
40 gfx::AcceleratedWidget GetAcceleratedWidget() {
41 // TODO(spang): We should start rendering asynchronously.
42 DCHECK_NE(widget_, gfx::kNullAcceleratedWidget)
43 << "Widget not available synchronously";
44 return widget_;
47 gfx::Size GetSize() { return platform_window_->GetBounds().size(); }
49 void Start() {
50 if (!CommandLine::ForCurrentProcess()->HasSwitch(kDisableGpu) &&
51 gfx::GLSurface::InitializeOneOff() && StartInProcessGpu() &&
52 InitializeGLSurface()) {
53 StartAnimationGL();
54 } else if (InitializeSoftwareSurface()) {
55 StartAnimationSoftware();
56 } else {
57 LOG(ERROR) << "Failed to create drawing surface";
58 Quit();
62 void Quit() {
63 StopAnimation();
64 base::MessageLoop::current()->PostTask(
65 FROM_HERE, base::Bind(&base::DeletePointer<DemoWindow>, this));
68 // PlatformWindowDelegate:
69 void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
70 void OnDamageRect(const gfx::Rect& damaged_region) override {}
71 void DispatchEvent(ui::Event* event) override {}
72 void OnCloseRequest() override { Quit(); }
73 void OnClosed() override {}
74 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {}
75 void OnLostCapture() override {}
76 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override {
77 DCHECK_NE(widget, gfx::kNullAcceleratedWidget);
78 widget_ = widget;
80 void OnActivationChanged(bool active) override {}
82 private:
83 bool InitializeGLSurface() {
84 surface_ = gfx::GLSurface::CreateViewGLSurface(GetAcceleratedWidget());
85 if (!surface_.get()) {
86 LOG(ERROR) << "Failed to create GL surface";
87 return false;
90 context_ = gfx::GLContext::CreateGLContext(
91 NULL, surface_.get(), gfx::PreferIntegratedGpu);
92 if (!context_.get()) {
93 LOG(ERROR) << "Failed to create GL context";
94 surface_ = NULL;
95 return false;
98 surface_->Resize(GetSize());
100 if (!context_->MakeCurrent(surface_.get())) {
101 LOG(ERROR) << "Failed to make GL context current";
102 surface_ = NULL;
103 context_ = NULL;
104 return false;
107 return true;
110 bool InitializeSoftwareSurface() {
111 software_surface_ =
112 ui::SurfaceFactoryOzone::GetInstance()->CreateCanvasForWidget(
113 GetAcceleratedWidget());
114 if (!software_surface_) {
115 LOG(ERROR) << "Failed to create software surface";
116 return false;
119 software_surface_->ResizeCanvas(GetSize());
120 return true;
123 void StartAnimationGL() {
124 timer_.Start(FROM_HERE,
125 base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds),
126 this,
127 &DemoWindow::RenderFrameGL);
130 void StartAnimationSoftware() {
131 timer_.Start(FROM_HERE,
132 base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds),
133 this,
134 &DemoWindow::RenderFrameSoftware);
137 void StopAnimation() { timer_.Stop(); }
139 float NextFraction() {
140 float fraction = (sinf(iteration_ * 2 * M_PI / kAnimationSteps) + 1) / 2;
142 iteration_++;
143 iteration_ %= kAnimationSteps;
145 return fraction;
148 void RenderFrameGL() {
149 float fraction = NextFraction();
150 gfx::Size window_size = GetSize();
152 glViewport(0, 0, window_size.width(), window_size.height());
153 glClearColor(1 - fraction, fraction, 0.0, 1.0);
154 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
156 if (!surface_->SwapBuffers())
157 LOG(FATAL) << "Failed to swap buffers";
160 void RenderFrameSoftware() {
161 float fraction = NextFraction();
162 gfx::Size window_size = GetSize();
164 skia::RefPtr<SkCanvas> canvas = software_surface_->GetCanvas();
166 SkColor color =
167 SkColorSetARGB(0xff, 0, 0xff * fraction, 0xff * (1 - fraction));
169 canvas->clear(color);
171 software_surface_->PresentCanvas(gfx::Rect(window_size));
174 bool StartInProcessGpu() { return ui_thread_gpu_.Initialize(); }
176 // Timer for animation.
177 base::RepeatingTimer<DemoWindow> timer_;
179 // Bits for GL rendering.
180 scoped_refptr<gfx::GLSurface> surface_;
181 scoped_refptr<gfx::GLContext> context_;
183 // Bits for software rendeirng.
184 scoped_ptr<ui::SurfaceOzoneCanvas> software_surface_;
186 // Window-related state.
187 scoped_ptr<ui::PlatformWindow> platform_window_;
188 gfx::AcceleratedWidget widget_;
190 // Helper for applications that do GL on main thread.
191 ui::UiThreadGpu ui_thread_gpu_;
193 // Animation state.
194 int iteration_;
196 DISALLOW_COPY_AND_ASSIGN(DemoWindow);
199 int main(int argc, char** argv) {
200 CommandLine::Init(argc, argv);
201 base::AtExitManager exit_manager;
203 // Build UI thread message loop. This is used by platform
204 // implementations for event polling & running background tasks.
205 base::MessageLoopForUI message_loop;
207 ui::OzonePlatform::InitializeForUI();
209 DemoWindow* window = new DemoWindow;
210 window->Start();
212 // Run the message loop until there's nothing left to do.
213 // TODO(spang): Should we use QuitClosure instead?
214 base::RunLoop run_loop;
215 run_loop.RunUntilIdle();
217 return 0;