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