OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 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/platform_window/platform_window.h" |
| 20 #include "ui/platform_window/platform_window_delegate.h" |
| 21 |
| 22 const int kTestWindowWidth = 800; |
| 23 const int kTestWindowHeight = 600; |
| 24 |
| 25 const int kFrameDelayMilliseconds = 16; |
| 26 |
| 27 const int kAnimationSteps = 240; |
| 28 |
| 29 const char kDisableGpu[] = "disable-gpu"; |
| 30 |
| 31 class DemoWindow : public ui::PlatformWindowDelegate { |
| 32 public: |
| 33 DemoWindow() : widget_(gfx::kNullAcceleratedWidget), iteration_(0) { |
| 34 platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( |
| 35 this, gfx::Rect(kTestWindowWidth, kTestWindowHeight)); |
| 36 } |
| 37 virtual ~DemoWindow() {} |
| 38 |
| 39 gfx::AcceleratedWidget GetAcceleratedWidget() { |
| 40 // TODO(spang): We should start rendering asynchronously. |
| 41 CHECK_NE(widget_, gfx::kNullAcceleratedWidget) |
| 42 << "Widget not available synchronously"; |
| 43 return widget_; |
| 44 } |
| 45 |
| 46 gfx::Size GetSize() { return platform_window_->GetBounds().size(); } |
| 47 |
| 48 void Start() { |
| 49 if (!CommandLine::ForCurrentProcess()->HasSwitch(kDisableGpu) && |
| 50 gfx::GLSurface::InitializeOneOff() && InitializeGLSurface()) { |
| 51 StartAnimationGL(); |
| 52 } else if (InitializeSoftwareSurface()) { |
| 53 StartAnimationSoftware(); |
| 54 } else { |
| 55 LOG(ERROR) << "Failed to create drawing surface"; |
| 56 Quit(); |
| 57 } |
| 58 } |
| 59 |
| 60 void Quit() { |
| 61 StopAnimation(); |
| 62 base::MessageLoop::current()->PostTask( |
| 63 FROM_HERE, base::Bind(&base::DeletePointer<DemoWindow>, this)); |
| 64 } |
| 65 |
| 66 // PlatformWindowDelegate: |
| 67 virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {} |
| 68 virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {} |
| 69 virtual void DispatchEvent(ui::Event* event) OVERRIDE {} |
| 70 virtual void OnCloseRequest() OVERRIDE { |
| 71 Quit(); |
| 72 } |
| 73 virtual void OnClosed() OVERRIDE {} |
| 74 virtual void OnWindowStateChanged( |
| 75 ui::PlatformWindowState new_state) OVERRIDE {} |
| 76 virtual void OnLostCapture() OVERRIDE {} |
| 77 virtual void OnAcceleratedWidgetAvailable( |
| 78 gfx::AcceleratedWidget widget) OVERRIDE { |
| 79 CHECK_NE(widget, gfx::kNullAcceleratedWidget); |
| 80 widget_ = widget; |
| 81 } |
| 82 virtual void OnActivationChanged(bool active) OVERRIDE {} |
| 83 |
| 84 private: |
| 85 bool InitializeGLSurface() { |
| 86 surface_ = gfx::GLSurface::CreateViewGLSurface(GetAcceleratedWidget()); |
| 87 if (!surface_) { |
| 88 LOG(ERROR) << "Failed to create GL surface"; |
| 89 return false; |
| 90 } |
| 91 |
| 92 context_ = gfx::GLContext::CreateGLContext( |
| 93 NULL, surface_.get(), gfx::PreferIntegratedGpu); |
| 94 if (!context_) { |
| 95 LOG(ERROR) << "Failed to create GL context"; |
| 96 surface_ = NULL; |
| 97 return false; |
| 98 } |
| 99 |
| 100 surface_->Resize(GetSize()); |
| 101 |
| 102 if (!context_->MakeCurrent(surface_.get())) { |
| 103 LOG(ERROR) << "Failed to make GL context current"; |
| 104 surface_ = NULL; |
| 105 context_ = NULL; |
| 106 return false; |
| 107 } |
| 108 |
| 109 return true; |
| 110 } |
| 111 |
| 112 bool InitializeSoftwareSurface() { |
| 113 software_surface_ = |
| 114 ui::SurfaceFactoryOzone::GetInstance()->CreateCanvasForWidget( |
| 115 GetAcceleratedWidget()); |
| 116 if (!software_surface_) { |
| 117 LOG(ERROR) << "Failed to create software surface"; |
| 118 return false; |
| 119 } |
| 120 |
| 121 software_surface_->ResizeCanvas(GetSize()); |
| 122 return true; |
| 123 } |
| 124 |
| 125 void StartAnimationGL() { |
| 126 timer_.Start(FROM_HERE, |
| 127 base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds), |
| 128 this, |
| 129 &DemoWindow::RenderFrameGL); |
| 130 } |
| 131 |
| 132 void StartAnimationSoftware() { |
| 133 timer_.Start(FROM_HERE, |
| 134 base::TimeDelta::FromMicroseconds(kFrameDelayMilliseconds), |
| 135 this, |
| 136 &DemoWindow::RenderFrameSoftware); |
| 137 } |
| 138 |
| 139 void StopAnimation() { timer_.Stop(); } |
| 140 |
| 141 float NextFraction() { |
| 142 float fraction = (sinf(iteration_ * 2 * M_PI / kAnimationSteps) + 1) / 2; |
| 143 |
| 144 iteration_++; |
| 145 iteration_ %= kAnimationSteps; |
| 146 |
| 147 return fraction; |
| 148 } |
| 149 |
| 150 void RenderFrameGL() { |
| 151 float fraction = NextFraction(); |
| 152 gfx::Size window_size = GetSize(); |
| 153 |
| 154 glViewport(0, 0, window_size.width(), window_size.height()); |
| 155 glClearColor(1 - fraction, fraction, 0.0, 1.0); |
| 156 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| 157 |
| 158 if (!surface_->SwapBuffers()) |
| 159 LOG(FATAL) << "Failed to swap buffers"; |
| 160 } |
| 161 |
| 162 void RenderFrameSoftware() { |
| 163 float fraction = NextFraction(); |
| 164 gfx::Size window_size = GetSize(); |
| 165 |
| 166 skia::RefPtr<SkCanvas> canvas = software_surface_->GetCanvas(); |
| 167 |
| 168 SkColor color = |
| 169 SkColorSetARGB(0xff, 0, 0xff * fraction, 0xff * (1 - fraction)); |
| 170 |
| 171 canvas->clear(color); |
| 172 |
| 173 software_surface_->PresentCanvas(gfx::Rect(window_size)); |
| 174 } |
| 175 |
| 176 // Timer for animation. |
| 177 base::RepeatingTimer<DemoWindow> timer_; |
| 178 |
| 179 // Bits for GL rendering. |
| 180 scoped_refptr<gfx::GLSurface> surface_; |
| 181 scoped_refptr<gfx::GLContext> context_; |
| 182 |
| 183 // Bits for software rendeirng. |
| 184 scoped_ptr<ui::SurfaceOzoneCanvas> software_surface_; |
| 185 |
| 186 // Window-related state. |
| 187 scoped_ptr<ui::PlatformWindow> platform_window_; |
| 188 gfx::AcceleratedWidget widget_; |
| 189 |
| 190 // Animation state. |
| 191 int iteration_; |
| 192 |
| 193 DISALLOW_COPY_AND_ASSIGN(DemoWindow); |
| 194 }; |
| 195 |
| 196 int main(int argc, char** argv) { |
| 197 CommandLine::Init(argc, argv); |
| 198 base::AtExitManager exit_manager; |
| 199 |
| 200 // Build UI thread message loop. This is used by platform |
| 201 // implementations for event polling & running background tasks. |
| 202 base::MessageLoopForUI message_loop; |
| 203 |
| 204 ui::OzonePlatform::InitializeForUI(); |
| 205 |
| 206 DemoWindow* window = new DemoWindow; |
| 207 window->Start(); |
| 208 |
| 209 // Run the message loop until there's nothing left to do. |
| 210 // TODO(spang): Should we use QuitClosure instead? |
| 211 base::RunLoop run_loop; |
| 212 run_loop.RunUntilIdle(); |
| 213 |
| 214 return 0; |
| 215 } |
OLD | NEW |