| 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..15d8fc0f344269e54e0211d8bbebc70c3e96c560
|
| --- /dev/null
|
| +++ b/ui/ozone/demo/ozone_demo.cc
|
| @@ -0,0 +1,215 @@
|
| +// 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/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/timer/timer.h"
|
| +#include "third_party/skia/include/core/SkCanvas.h"
|
| +#include "third_party/skia/include/core/SkColor.h"
|
| +#include "ui/gfx/geometry/size.h"
|
| +#include "ui/gl/gl_bindings.h"
|
| +#include "ui/gl/gl_context.h"
|
| +#include "ui/gl/gl_surface.h"
|
| +#include "ui/ozone/public/ozone_platform.h"
|
| +#include "ui/ozone/public/surface_factory_ozone.h"
|
| +#include "ui/ozone/public/surface_ozone_canvas.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 int kFrameDelayMilliseconds = 16;
|
| +
|
| +const int kAnimationSteps = 240;
|
| +
|
| +const char kDisableGpu[] = "disable-gpu";
|
| +
|
| +class DemoWindow : public ui::PlatformWindowDelegate {
|
| + public:
|
| + DemoWindow() : widget_(gfx::kNullAcceleratedWidget), iteration_(0) {
|
| + platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
|
| + this, gfx::Rect(kTestWindowWidth, kTestWindowHeight));
|
| + }
|
| + virtual ~DemoWindow() {}
|
| +
|
| + gfx::AcceleratedWidget GetAcceleratedWidget() {
|
| + // TODO(spang): We should start rendering asynchronously.
|
| + CHECK_NE(widget_, gfx::kNullAcceleratedWidget)
|
| + << "Widget not available synchronously";
|
| + return widget_;
|
| + }
|
| +
|
| + gfx::Size GetSize() { return platform_window_->GetBounds().size(); }
|
| +
|
| + void Start() {
|
| + if (!CommandLine::ForCurrentProcess()->HasSwitch(kDisableGpu) &&
|
| + gfx::GLSurface::InitializeOneOff() && InitializeGLSurface()) {
|
| + StartAnimationGL();
|
| + } else if (InitializeSoftwareSurface()) {
|
| + StartAnimationSoftware();
|
| + } else {
|
| + LOG(ERROR) << "Failed to create drawing surface";
|
| + Quit();
|
| + }
|
| + }
|
| +
|
| + void Quit() {
|
| + StopAnimation();
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE, base::Bind(&base::DeletePointer<DemoWindow>, this));
|
| + }
|
| +
|
| + // PlatformWindowDelegate:
|
| + virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {}
|
| + virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {}
|
| + virtual void DispatchEvent(ui::Event* event) OVERRIDE {}
|
| + virtual void OnCloseRequest() OVERRIDE {
|
| + Quit();
|
| + }
|
| + virtual void OnClosed() OVERRIDE {}
|
| + virtual void OnWindowStateChanged(
|
| + ui::PlatformWindowState new_state) OVERRIDE {}
|
| + virtual void OnLostCapture() OVERRIDE {}
|
| + virtual void OnAcceleratedWidgetAvailable(
|
| + gfx::AcceleratedWidget widget) OVERRIDE {
|
| + CHECK_NE(widget, gfx::kNullAcceleratedWidget);
|
| + widget_ = widget;
|
| + }
|
| + virtual void OnActivationChanged(bool active) OVERRIDE {}
|
| +
|
| + private:
|
| + bool InitializeGLSurface() {
|
| + surface_ = gfx::GLSurface::CreateViewGLSurface(GetAcceleratedWidget());
|
| + if (!surface_) {
|
| + LOG(ERROR) << "Failed to create GL surface";
|
| + return false;
|
| + }
|
| +
|
| + context_ = gfx::GLContext::CreateGLContext(
|
| + NULL, surface_.get(), gfx::PreferIntegratedGpu);
|
| + if (!context_) {
|
| + LOG(ERROR) << "Failed to create GL context";
|
| + surface_ = NULL;
|
| + return false;
|
| + }
|
| +
|
| + surface_->Resize(GetSize());
|
| +
|
| + if (!context_->MakeCurrent(surface_.get())) {
|
| + LOG(ERROR) << "Failed to make GL context current";
|
| + surface_ = NULL;
|
| + context_ = NULL;
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| + }
|
| +
|
| + bool InitializeSoftwareSurface() {
|
| + software_surface_ =
|
| + ui::SurfaceFactoryOzone::GetInstance()->CreateCanvasForWidget(
|
| + GetAcceleratedWidget());
|
| + if (!software_surface_) {
|
| + LOG(ERROR) << "Failed to create software surface";
|
| + return false;
|
| + }
|
| +
|
| + software_surface_->ResizeCanvas(GetSize());
|
| + return true;
|
| + }
|
| +
|
| + void StartAnimationGL() {
|
| + timer_.Start(FROM_HERE,
|
| + base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds),
|
| + this,
|
| + &DemoWindow::RenderFrameGL);
|
| + }
|
| +
|
| + void StartAnimationSoftware() {
|
| + timer_.Start(FROM_HERE,
|
| + base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds),
|
| + this,
|
| + &DemoWindow::RenderFrameSoftware);
|
| + }
|
| +
|
| + void StopAnimation() { timer_.Stop(); }
|
| +
|
| + float NextFraction() {
|
| + float fraction = (sinf(iteration_ * 2 * M_PI / kAnimationSteps) + 1) / 2;
|
| +
|
| + iteration_++;
|
| + iteration_ %= kAnimationSteps;
|
| +
|
| + return fraction;
|
| + }
|
| +
|
| + void RenderFrameGL() {
|
| + float fraction = NextFraction();
|
| + gfx::Size window_size = GetSize();
|
| +
|
| + glViewport(0, 0, window_size.width(), window_size.height());
|
| + glClearColor(1 - fraction, fraction, 0.0, 1.0);
|
| + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
| +
|
| + if (!surface_->SwapBuffers())
|
| + LOG(FATAL) << "Failed to swap buffers";
|
| + }
|
| +
|
| + void RenderFrameSoftware() {
|
| + float fraction = NextFraction();
|
| + gfx::Size window_size = GetSize();
|
| +
|
| + skia::RefPtr<SkCanvas> canvas = software_surface_->GetCanvas();
|
| +
|
| + SkColor color =
|
| + SkColorSetARGB(0xff, 0, 0xff * fraction, 0xff * (1 - fraction));
|
| +
|
| + canvas->clear(color);
|
| +
|
| + software_surface_->PresentCanvas(gfx::Rect(window_size));
|
| + }
|
| +
|
| + // Timer for animation.
|
| + base::RepeatingTimer<DemoWindow> timer_;
|
| +
|
| + // Bits for GL rendering.
|
| + scoped_refptr<gfx::GLSurface> surface_;
|
| + scoped_refptr<gfx::GLContext> context_;
|
| +
|
| + // Bits for software rendeirng.
|
| + scoped_ptr<ui::SurfaceOzoneCanvas> software_surface_;
|
| +
|
| + // Window-related state.
|
| + scoped_ptr<ui::PlatformWindow> platform_window_;
|
| + gfx::AcceleratedWidget widget_;
|
| +
|
| + // Animation state.
|
| + int iteration_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DemoWindow);
|
| +};
|
| +
|
| +int main(int argc, char** argv) {
|
| + CommandLine::Init(argc, argv);
|
| + base::AtExitManager exit_manager;
|
| +
|
| + // Build UI thread message loop. This is used by platform
|
| + // implementations for event polling & running background tasks.
|
| + base::MessageLoopForUI message_loop;
|
| +
|
| + ui::OzonePlatform::InitializeForUI();
|
| +
|
| + DemoWindow* window = new DemoWindow;
|
| + window->Start();
|
| +
|
| + // Run the message loop until there's nothing left to do.
|
| + // TODO(spang): Should we use QuitClosure instead?
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| +
|
| + return 0;
|
| +}
|
|
|