• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 "testing/gtest/include/gtest/gtest.h"
6 #include "ui/gfx/ozone/dri/dri_skbitmap.h"
7 #include "ui/gfx/ozone/dri/dri_surface.h"
8 #include "ui/gfx/ozone/dri/dri_wrapper.h"
9 #include "ui/gfx/ozone/dri/hardware_display_controller.h"
10 
11 namespace {
12 
13 // Create a basic mode for a 6x4 screen.
14 const drmModeModeInfo kDefaultMode =
15     {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
16 
17 // Mock file descriptor ID.
18 const int kFd = 3;
19 
20 // Mock connector ID.
21 const uint32_t kConnectorId = 1;
22 
23 // Mock CRTC ID.
24 const uint32_t kCrtcId = 1;
25 
26 const uint32_t kDPMSPropertyId = 1;
27 
28 // The real DriWrapper makes actual DRM calls which we can't use in unit tests.
29 class MockDriWrapper : public gfx::DriWrapper {
30  public:
MockDriWrapper(int fd)31   MockDriWrapper(int fd) : DriWrapper(""),
32                                 get_crtc_call_count_(0),
33                                 free_crtc_call_count_(0),
34                                 restore_crtc_call_count_(0),
35                                 add_framebuffer_call_count_(0),
36                                 remove_framebuffer_call_count_(0),
37                                 set_crtc_expectation_(true),
38                                 add_framebuffer_expectation_(true),
39                                 page_flip_expectation_(true) {
40     fd_ = fd;
41   }
42 
~MockDriWrapper()43   virtual ~MockDriWrapper() { fd_ = -1; }
44 
GetCrtc(uint32_t crtc_id)45   virtual drmModeCrtc* GetCrtc(uint32_t crtc_id) OVERRIDE {
46     get_crtc_call_count_++;
47     return new drmModeCrtc;
48   }
49 
FreeCrtc(drmModeCrtc * crtc)50   virtual void FreeCrtc(drmModeCrtc* crtc) OVERRIDE {
51     free_crtc_call_count_++;
52     delete crtc;
53   }
54 
SetCrtc(uint32_t crtc_id,uint32_t framebuffer,uint32_t * connectors,drmModeModeInfo * mode)55   virtual bool SetCrtc(uint32_t crtc_id,
56                        uint32_t framebuffer,
57                        uint32_t* connectors,
58                        drmModeModeInfo* mode) OVERRIDE {
59     return set_crtc_expectation_;
60   }
61 
SetCrtc(drmModeCrtc * crtc,uint32_t * connectors)62   virtual bool SetCrtc(drmModeCrtc* crtc, uint32_t* connectors) OVERRIDE {
63     restore_crtc_call_count_++;
64     return true;
65   }
66 
AddFramebuffer(const drmModeModeInfo & mode,uint8_t depth,uint8_t bpp,uint32_t stride,uint32_t handle,uint32_t * framebuffer)67   virtual bool AddFramebuffer(const drmModeModeInfo& mode,
68                               uint8_t depth,
69                               uint8_t bpp,
70                               uint32_t stride,
71                               uint32_t handle,
72                               uint32_t* framebuffer) OVERRIDE {
73     add_framebuffer_call_count_++;
74     return add_framebuffer_expectation_;
75   }
76 
RemoveFramebuffer(uint32_t framebuffer)77   virtual bool RemoveFramebuffer(uint32_t framebuffer) OVERRIDE {
78     remove_framebuffer_call_count_++;
79     return true;
80   }
81 
PageFlip(uint32_t crtc_id,uint32_t framebuffer,void * data)82   virtual bool PageFlip(uint32_t crtc_id,
83                         uint32_t framebuffer,
84                         void* data) OVERRIDE {
85     return page_flip_expectation_;
86   }
87 
ConnectorSetProperty(uint32_t connector_id,uint32_t property_id,uint64_t value)88   virtual bool ConnectorSetProperty(uint32_t connector_id,
89                                     uint32_t property_id,
90                                     uint64_t value) OVERRIDE { return true; }
91 
get_get_crtc_call_count() const92   int get_get_crtc_call_count() const {
93     return get_crtc_call_count_;
94   }
95 
get_free_crtc_call_count() const96   int get_free_crtc_call_count() const {
97     return free_crtc_call_count_;
98   }
99 
get_restore_crtc_call_count() const100   int get_restore_crtc_call_count() const {
101     return restore_crtc_call_count_;
102   }
103 
get_add_framebuffer_call_count() const104   int get_add_framebuffer_call_count() const {
105     return add_framebuffer_call_count_;
106   }
107 
get_remove_framebuffer_call_count() const108   int get_remove_framebuffer_call_count() const {
109     return remove_framebuffer_call_count_;
110   }
111 
set_set_crtc_expectation(bool state)112   void set_set_crtc_expectation(bool state) {
113     set_crtc_expectation_ = state;
114   }
115 
set_add_framebuffer_expectation(bool state)116   void set_add_framebuffer_expectation(bool state) {
117     add_framebuffer_expectation_ = state;
118   }
119 
set_page_flip_expectation(bool state)120   void set_page_flip_expectation(bool state) {
121     page_flip_expectation_ = state;
122   }
123 
124  private:
125   int get_crtc_call_count_;
126   int free_crtc_call_count_;
127   int restore_crtc_call_count_;
128   int add_framebuffer_call_count_;
129   int remove_framebuffer_call_count_;
130 
131   bool set_crtc_expectation_;
132   bool add_framebuffer_expectation_;
133   bool page_flip_expectation_;
134 
135   DISALLOW_COPY_AND_ASSIGN(MockDriWrapper);
136 };
137 
138 class MockDriSkBitmap : public gfx::DriSkBitmap {
139  public:
MockDriSkBitmap(int fd)140   MockDriSkBitmap(int fd) : DriSkBitmap(fd) {}
~MockDriSkBitmap()141   virtual ~MockDriSkBitmap() {}
142 
Initialize()143   virtual bool Initialize() OVERRIDE {
144     return allocPixels();
145   }
146  private:
147   DISALLOW_COPY_AND_ASSIGN(MockDriSkBitmap);
148 };
149 
150 class MockDriSurface : public gfx::DriSurface {
151  public:
MockDriSurface(gfx::HardwareDisplayController * controller)152   MockDriSurface(gfx::HardwareDisplayController* controller)
153       : DriSurface(controller) {}
~MockDriSurface()154   virtual ~MockDriSurface() {}
155 
156  private:
CreateBuffer()157   virtual gfx::DriSkBitmap* CreateBuffer() OVERRIDE {
158     return new MockDriSkBitmap(kFd);
159   }
160   DISALLOW_COPY_AND_ASSIGN(MockDriSurface);
161 };
162 
163 }  // namespace
164 
165 class HardwareDisplayControllerTest : public testing::Test {
166  public:
HardwareDisplayControllerTest()167   HardwareDisplayControllerTest() {}
~HardwareDisplayControllerTest()168   virtual ~HardwareDisplayControllerTest() {}
169 
170   virtual void SetUp() OVERRIDE;
171   virtual void TearDown() OVERRIDE;
172  protected:
173   scoped_ptr<gfx::HardwareDisplayController> controller_;
174   scoped_ptr<MockDriWrapper> drm_;
175 
176  private:
177   DISALLOW_COPY_AND_ASSIGN(HardwareDisplayControllerTest);
178 };
179 
SetUp()180 void HardwareDisplayControllerTest::SetUp() {
181   controller_.reset(new gfx::HardwareDisplayController());
182   drm_.reset(new MockDriWrapper(kFd));
183 }
184 
TearDown()185 void HardwareDisplayControllerTest::TearDown() {
186   controller_.reset();
187   drm_.reset();
188 }
189 
TEST_F(HardwareDisplayControllerTest,CheckInitialState)190 TEST_F(HardwareDisplayControllerTest, CheckInitialState) {
191   EXPECT_EQ(gfx::HardwareDisplayController::UNASSOCIATED,
192             controller_->get_state());
193 }
194 
TEST_F(HardwareDisplayControllerTest,CheckStateAfterControllerIsInitialized)195 TEST_F(HardwareDisplayControllerTest,
196        CheckStateAfterControllerIsInitialized) {
197   controller_->SetControllerInfo(
198       drm_.get(), kConnectorId, kCrtcId, kDPMSPropertyId, kDefaultMode);
199 
200   EXPECT_EQ(1, drm_->get_get_crtc_call_count());
201   EXPECT_EQ(gfx::HardwareDisplayController::UNINITIALIZED,
202             controller_->get_state());
203 }
204 
TEST_F(HardwareDisplayControllerTest,CheckStateAfterSurfaceIsBound)205 TEST_F(HardwareDisplayControllerTest, CheckStateAfterSurfaceIsBound) {
206   controller_->SetControllerInfo(
207       drm_.get(), kConnectorId, kCrtcId, kDPMSPropertyId, kDefaultMode);
208   scoped_ptr<gfx::DriSurface> surface(
209       new MockDriSurface(controller_.get()));
210 
211   EXPECT_TRUE(surface->Initialize());
212   EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
213 
214   EXPECT_EQ(2, drm_->get_add_framebuffer_call_count());
215   EXPECT_EQ(gfx::HardwareDisplayController::SURFACE_INITIALIZED,
216             controller_->get_state());
217 }
218 
TEST_F(HardwareDisplayControllerTest,CheckStateIfBindingFails)219 TEST_F(HardwareDisplayControllerTest, CheckStateIfBindingFails) {
220   drm_->set_add_framebuffer_expectation(false);
221 
222   controller_->SetControllerInfo(
223       drm_.get(), kConnectorId, kCrtcId, kDPMSPropertyId, kDefaultMode);
224   scoped_ptr<gfx::DriSurface> surface(
225       new MockDriSurface(controller_.get()));
226 
227   EXPECT_TRUE(surface->Initialize());
228   EXPECT_FALSE(controller_->BindSurfaceToController(surface.Pass()));
229 
230   EXPECT_EQ(1, drm_->get_add_framebuffer_call_count());
231   EXPECT_EQ(gfx::HardwareDisplayController::FAILED,
232             controller_->get_state());
233 }
234 
TEST_F(HardwareDisplayControllerTest,CheckStateAfterPageFlip)235 TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) {
236   controller_->SetControllerInfo(
237       drm_.get(), kConnectorId, kCrtcId, kDPMSPropertyId, kDefaultMode);
238   scoped_ptr<gfx::DriSurface> surface(
239       new MockDriSurface(controller_.get()));
240 
241   EXPECT_TRUE(surface->Initialize());
242   EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
243 
244   controller_->SchedulePageFlip();
245 
246   EXPECT_EQ(gfx::HardwareDisplayController::INITIALIZED,
247             controller_->get_state());
248 }
249 
TEST_F(HardwareDisplayControllerTest,CheckStateIfModesetFails)250 TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) {
251   drm_->set_set_crtc_expectation(false);
252 
253   controller_->SetControllerInfo(
254       drm_.get(), kConnectorId, kCrtcId, kDPMSPropertyId, kDefaultMode);
255   scoped_ptr<gfx::DriSurface> surface(
256       new MockDriSurface(controller_.get()));
257 
258   EXPECT_TRUE(surface->Initialize());
259   EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
260 
261   controller_->SchedulePageFlip();
262 
263   EXPECT_EQ(gfx::HardwareDisplayController::FAILED,
264             controller_->get_state());
265 }
266 
TEST_F(HardwareDisplayControllerTest,CheckStateIfPageFlipFails)267 TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) {
268   drm_->set_page_flip_expectation(false);
269 
270   controller_->SetControllerInfo(
271       drm_.get(), kConnectorId, kCrtcId, kDPMSPropertyId, kDefaultMode);
272   scoped_ptr<gfx::DriSurface> surface(
273       new MockDriSurface(controller_.get()));
274 
275   EXPECT_TRUE(surface->Initialize());
276   EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
277 
278   controller_->SchedulePageFlip();
279 
280   EXPECT_EQ(gfx::HardwareDisplayController::FAILED,
281             controller_->get_state());
282 }
283 
TEST_F(HardwareDisplayControllerTest,CheckProperDestruction)284 TEST_F(HardwareDisplayControllerTest, CheckProperDestruction) {
285   controller_->SetControllerInfo(
286       drm_.get(), kConnectorId, kCrtcId, kDPMSPropertyId, kDefaultMode);
287   scoped_ptr<gfx::DriSurface> surface(
288       new MockDriSurface(controller_.get()));
289 
290   EXPECT_TRUE(surface->Initialize());
291   EXPECT_TRUE(controller_->BindSurfaceToController(surface.Pass()));
292 
293   EXPECT_EQ(gfx::HardwareDisplayController::SURFACE_INITIALIZED,
294             controller_->get_state());
295 
296   controller_.reset();
297 
298   EXPECT_EQ(2, drm_->get_remove_framebuffer_call_count());
299   EXPECT_EQ(1, drm_->get_restore_crtc_call_count());
300   EXPECT_EQ(1, drm_->get_free_crtc_call_count());
301 }
302