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/message_loop/message_loop.h" 6#include "cc/output/compositor_frame.h" 7#include "content/browser/compositor/browser_compositor_output_surface_proxy.h" 8#include "content/browser/compositor/software_browser_compositor_output_surface.h" 9#include "testing/gtest/include/gtest/gtest.h" 10#include "ui/compositor/compositor.h" 11#include "ui/compositor/test/context_factories_for_test.h" 12#include "ui/gfx/vsync_provider.h" 13 14namespace { 15 16class FakeVSyncProvider : public gfx::VSyncProvider { 17 public: 18 FakeVSyncProvider() : call_count_(0) {} 19 virtual ~FakeVSyncProvider() {} 20 21 virtual void GetVSyncParameters(const UpdateVSyncCallback& callback) 22 OVERRIDE { 23 callback.Run(timebase_, interval_); 24 call_count_++; 25 } 26 27 int call_count() const { return call_count_; } 28 29 void set_timebase(base::TimeTicks timebase) { timebase_ = timebase; } 30 void set_interval(base::TimeDelta interval) { interval_ = interval; } 31 32 private: 33 base::TimeTicks timebase_; 34 base::TimeDelta interval_; 35 36 int call_count_; 37 38 DISALLOW_COPY_AND_ASSIGN(FakeVSyncProvider); 39}; 40 41class FakeSoftwareOutputDevice : public cc::SoftwareOutputDevice { 42 public: 43 FakeSoftwareOutputDevice() : vsync_provider_(new FakeVSyncProvider()) {} 44 virtual ~FakeSoftwareOutputDevice() {} 45 46 virtual gfx::VSyncProvider* GetVSyncProvider() OVERRIDE { 47 return vsync_provider_.get(); 48 } 49 50 private: 51 scoped_ptr<gfx::VSyncProvider> vsync_provider_; 52 53 DISALLOW_COPY_AND_ASSIGN(FakeSoftwareOutputDevice); 54}; 55 56} // namespace 57 58class SoftwareBrowserCompositorOutputSurfaceTest : public testing::Test { 59 public: 60 SoftwareBrowserCompositorOutputSurfaceTest(); 61 virtual ~SoftwareBrowserCompositorOutputSurfaceTest(); 62 63 virtual void SetUp() OVERRIDE; 64 virtual void TearDown() OVERRIDE; 65 66 scoped_ptr<content::BrowserCompositorOutputSurface> CreateSurface( 67 scoped_ptr<cc::SoftwareOutputDevice> device); 68 69 protected: 70 scoped_ptr<content::BrowserCompositorOutputSurface> output_surface_; 71 72 scoped_ptr<base::MessageLoop> message_loop_; 73 scoped_ptr<ui::Compositor> compositor_; 74 75 IDMap<content::BrowserCompositorOutputSurface> surface_map_; 76 scoped_refptr<content::BrowserCompositorOutputSurfaceProxy> surface_proxy_; 77 78 DISALLOW_COPY_AND_ASSIGN(SoftwareBrowserCompositorOutputSurfaceTest); 79}; 80 81SoftwareBrowserCompositorOutputSurfaceTest:: 82 SoftwareBrowserCompositorOutputSurfaceTest() { 83 // |message_loop_| is not used, but the main thread still has to exist for the 84 // compositor to use. 85 message_loop_.reset(new base::MessageLoopForUI); 86} 87 88SoftwareBrowserCompositorOutputSurfaceTest:: 89 ~SoftwareBrowserCompositorOutputSurfaceTest() {} 90 91void SoftwareBrowserCompositorOutputSurfaceTest::SetUp() { 92 bool enable_pixel_output = false; 93 ui::ContextFactory* context_factory = 94 ui::InitializeContextFactoryForTests(enable_pixel_output); 95 96 compositor_.reset(new ui::Compositor(gfx::kNullAcceleratedWidget, 97 context_factory, 98 base::MessageLoopProxy::current())); 99 surface_proxy_ = 100 new content::BrowserCompositorOutputSurfaceProxy(&surface_map_); 101} 102 103void SoftwareBrowserCompositorOutputSurfaceTest::TearDown() { 104 output_surface_.reset(); 105 compositor_.reset(); 106 107 EXPECT_TRUE(surface_map_.IsEmpty()); 108 109 surface_map_.Clear(); 110 ui::TerminateContextFactoryForTests(); 111} 112 113scoped_ptr<content::BrowserCompositorOutputSurface> 114SoftwareBrowserCompositorOutputSurfaceTest::CreateSurface( 115 scoped_ptr<cc::SoftwareOutputDevice> device) { 116 return scoped_ptr<content::BrowserCompositorOutputSurface>( 117 new content::SoftwareBrowserCompositorOutputSurface( 118 surface_proxy_, 119 device.Pass(), 120 1, 121 &surface_map_, 122 compositor_->vsync_manager())); 123} 124 125TEST_F(SoftwareBrowserCompositorOutputSurfaceTest, NoVSyncProvider) { 126 scoped_ptr<cc::SoftwareOutputDevice> software_device( 127 new cc::SoftwareOutputDevice()); 128 output_surface_ = CreateSurface(software_device.Pass()); 129 130 cc::CompositorFrame frame; 131 output_surface_->SwapBuffers(&frame); 132 133 EXPECT_EQ(NULL, output_surface_->software_device()->GetVSyncProvider()); 134} 135 136TEST_F(SoftwareBrowserCompositorOutputSurfaceTest, VSyncProviderUpdates) { 137 scoped_ptr<cc::SoftwareOutputDevice> software_device( 138 new FakeSoftwareOutputDevice()); 139 output_surface_ = CreateSurface(software_device.Pass()); 140 141 FakeVSyncProvider* vsync_provider = static_cast<FakeVSyncProvider*>( 142 output_surface_->software_device()->GetVSyncProvider()); 143 EXPECT_EQ(0, vsync_provider->call_count()); 144 145 cc::CompositorFrame frame; 146 output_surface_->SwapBuffers(&frame); 147 148 EXPECT_EQ(1, vsync_provider->call_count()); 149} 150