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.
6 #include "testing/gtest/include/gtest/gtest.h"
7 #include "third_party/skia/include/core/SkCanvas.h"
8 #include "ui/ozone/platform/drm/gpu/crtc_controller.h"
9 #include "ui/ozone/platform/drm/gpu/drm_buffer.h"
10 #include "ui/ozone/platform/drm/gpu/drm_device.h"
11 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
12 #include "ui/ozone/platform/drm/test/mock_drm_device.h"
13 #include "ui/ozone/public/native_pixmap.h"
17 // Create a basic mode for a 6x4 screen.
18 const drmModeModeInfo kDefaultMode
=
19 {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
21 const uint32_t kPrimaryCrtc
= 1;
22 const uint32_t kPrimaryConnector
= 2;
23 const uint32_t kSecondaryCrtc
= 3;
24 const uint32_t kSecondaryConnector
= 4;
25 const size_t kPlanesPerCrtc
= 2;
27 const gfx::Size
kDefaultModeSize(kDefaultMode
.hdisplay
, kDefaultMode
.vdisplay
);
28 const gfx::SizeF
kDefaultModeSizeF(1.0, 1.0);
30 class MockScanoutBuffer
: public ui::ScanoutBuffer
{
32 MockScanoutBuffer(const gfx::Size
& size
) : size_(size
) {}
35 uint32_t GetFramebufferId() const override
{ return 0; }
36 uint32_t GetHandle() const override
{ return 0; }
37 gfx::Size
GetSize() const override
{ return size_
; }
40 ~MockScanoutBuffer() override
{}
44 DISALLOW_COPY_AND_ASSIGN(MockScanoutBuffer
);
49 class HardwareDisplayControllerTest
: public testing::Test
{
51 HardwareDisplayControllerTest() : page_flips_(0) {}
52 ~HardwareDisplayControllerTest() override
{}
54 void SetUp() override
;
55 void TearDown() override
;
57 void PageFlipCallback();
60 scoped_ptr
<ui::HardwareDisplayController
> controller_
;
61 scoped_refptr
<ui::MockDrmDevice
> drm_
;
66 DISALLOW_COPY_AND_ASSIGN(HardwareDisplayControllerTest
);
69 void HardwareDisplayControllerTest::SetUp() {
70 std::vector
<uint32_t> crtcs
;
71 crtcs
.push_back(kPrimaryCrtc
);
72 crtcs
.push_back(kSecondaryCrtc
);
73 drm_
= new ui::MockDrmDevice(false, crtcs
, kPlanesPerCrtc
);
74 controller_
.reset(new ui::HardwareDisplayController(
75 scoped_ptr
<ui::CrtcController
>(new ui::CrtcController(
76 drm_
.get(), kPrimaryCrtc
, kPrimaryConnector
))));
79 void HardwareDisplayControllerTest::TearDown() {
84 void HardwareDisplayControllerTest::PageFlipCallback() {
88 TEST_F(HardwareDisplayControllerTest
, CheckModesettingResult
) {
89 ui::OverlayPlane
plane(scoped_refptr
<ui::ScanoutBuffer
>(
90 new MockScanoutBuffer(kDefaultModeSize
)));
92 EXPECT_TRUE(controller_
->Modeset(plane
, kDefaultMode
));
93 EXPECT_FALSE(plane
.buffer
->HasOneRef());
96 TEST_F(HardwareDisplayControllerTest
, CheckStateAfterPageFlip
) {
97 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
98 new MockScanoutBuffer(kDefaultModeSize
)));
100 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
102 ui::OverlayPlane
plane2(scoped_refptr
<ui::ScanoutBuffer
>(
103 new MockScanoutBuffer(kDefaultModeSize
)));
104 controller_
->QueueOverlayPlane(plane2
);
105 EXPECT_TRUE(controller_
->SchedulePageFlip(
106 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
107 base::Unretained(this))));
108 drm_
->RunCallbacks();
109 EXPECT_TRUE(plane1
.buffer
->HasOneRef());
110 EXPECT_FALSE(plane2
.buffer
->HasOneRef());
112 EXPECT_EQ(1, drm_
->get_page_flip_call_count());
113 EXPECT_EQ(0, drm_
->get_overlay_flip_call_count());
116 TEST_F(HardwareDisplayControllerTest
, CheckStateIfModesetFails
) {
117 drm_
->set_set_crtc_expectation(false);
119 ui::OverlayPlane
plane(scoped_refptr
<ui::ScanoutBuffer
>(
120 new MockScanoutBuffer(kDefaultModeSize
)));
122 EXPECT_FALSE(controller_
->Modeset(plane
, kDefaultMode
));
125 TEST_F(HardwareDisplayControllerTest
, CheckStateIfPageFlipFails
) {
126 drm_
->set_page_flip_expectation(false);
128 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
129 new MockScanoutBuffer(kDefaultModeSize
)));
131 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
133 ui::OverlayPlane
plane2(scoped_refptr
<ui::ScanoutBuffer
>(
134 new MockScanoutBuffer(kDefaultModeSize
)));
135 controller_
->QueueOverlayPlane(plane2
);
136 EXPECT_FALSE(controller_
->SchedulePageFlip(
137 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
138 base::Unretained(this))));
139 drm_
->RunCallbacks();
141 EXPECT_FALSE(plane1
.buffer
->HasOneRef());
142 EXPECT_TRUE(plane2
.buffer
->HasOneRef());
145 TEST_F(HardwareDisplayControllerTest
, VerifyNoDRMCallsWhenDisabled
) {
146 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
147 new MockScanoutBuffer(kDefaultModeSize
)));
149 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
150 controller_
->Disable();
151 ui::OverlayPlane
plane2(scoped_refptr
<ui::ScanoutBuffer
>(
152 new MockScanoutBuffer(kDefaultModeSize
)));
153 controller_
->QueueOverlayPlane(plane2
);
154 EXPECT_TRUE(controller_
->SchedulePageFlip(
155 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
156 base::Unretained(this))));
157 drm_
->RunCallbacks();
158 EXPECT_EQ(0, drm_
->get_page_flip_call_count());
160 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
161 controller_
->QueueOverlayPlane(plane2
);
162 EXPECT_TRUE(controller_
->SchedulePageFlip(
163 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
164 base::Unretained(this))));
165 drm_
->RunCallbacks();
166 EXPECT_EQ(1, drm_
->get_page_flip_call_count());
169 TEST_F(HardwareDisplayControllerTest
, CheckOverlayPresent
) {
170 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
171 new MockScanoutBuffer(kDefaultModeSize
)));
172 ui::OverlayPlane
plane2(
173 scoped_refptr
<ui::ScanoutBuffer
>(new MockScanoutBuffer(kDefaultModeSize
)),
174 1, gfx::OVERLAY_TRANSFORM_NONE
, gfx::Rect(kDefaultModeSize
),
175 gfx::RectF(kDefaultModeSizeF
));
177 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
179 controller_
->QueueOverlayPlane(plane1
);
180 controller_
->QueueOverlayPlane(plane2
);
182 EXPECT_TRUE(controller_
->SchedulePageFlip(
183 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
184 base::Unretained(this))));
185 drm_
->RunCallbacks();
186 EXPECT_EQ(1, drm_
->get_page_flip_call_count());
187 EXPECT_EQ(1, drm_
->get_overlay_flip_call_count());
190 TEST_F(HardwareDisplayControllerTest
, PageflipMirroredControllers
) {
191 controller_
->AddCrtc(scoped_ptr
<ui::CrtcController
>(
192 new ui::CrtcController(drm_
.get(), kSecondaryCrtc
, kSecondaryConnector
)));
194 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
195 new MockScanoutBuffer(kDefaultModeSize
)));
196 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
197 EXPECT_EQ(2, drm_
->get_set_crtc_call_count());
199 ui::OverlayPlane
plane2(scoped_refptr
<ui::ScanoutBuffer
>(
200 new MockScanoutBuffer(kDefaultModeSize
)));
201 controller_
->QueueOverlayPlane(plane2
);
202 EXPECT_TRUE(controller_
->SchedulePageFlip(
203 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
204 base::Unretained(this))));
205 drm_
->RunCallbacks();
206 EXPECT_EQ(2, drm_
->get_page_flip_call_count());
207 EXPECT_EQ(1, page_flips_
);
210 TEST_F(HardwareDisplayControllerTest
, PlaneStateAfterRemoveCrtc
) {
211 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
212 new MockScanoutBuffer(kDefaultModeSize
)));
213 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
214 controller_
->QueueOverlayPlane(plane1
);
215 EXPECT_TRUE(controller_
->SchedulePageFlip(
216 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
217 base::Unretained(this))));
218 drm_
->RunCallbacks();
220 const ui::HardwareDisplayPlane
* owned_plane
= nullptr;
221 for (const auto& plane
: drm_
->plane_manager()->planes())
224 ASSERT_TRUE(owned_plane
!= nullptr);
225 EXPECT_EQ(kPrimaryCrtc
, owned_plane
->owning_crtc());
226 // Removing the crtc should free the plane.
227 scoped_ptr
<ui::CrtcController
> crtc
=
228 controller_
->RemoveCrtc(drm_
, kPrimaryCrtc
);
229 EXPECT_FALSE(owned_plane
->in_use());
232 TEST_F(HardwareDisplayControllerTest
, ModesetWhilePageFlipping
) {
233 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
234 new MockScanoutBuffer(kDefaultModeSize
)));
235 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
236 controller_
->QueueOverlayPlane(plane1
);
237 EXPECT_TRUE(controller_
->SchedulePageFlip(
238 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
239 base::Unretained(this))));
241 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
242 drm_
->RunCallbacks();
243 EXPECT_EQ(1, page_flips_
);
246 TEST_F(HardwareDisplayControllerTest
, AddCrtcMidPageFlip
) {
247 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
248 new MockScanoutBuffer(kDefaultModeSize
)));
249 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
250 controller_
->QueueOverlayPlane(plane1
);
251 EXPECT_TRUE(controller_
->SchedulePageFlip(
252 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
253 base::Unretained(this))));
255 controller_
->AddCrtc(scoped_ptr
<ui::CrtcController
>(
256 new ui::CrtcController(drm_
.get(), kSecondaryCrtc
, kSecondaryConnector
)));
258 drm_
->RunCallbacks();
259 EXPECT_EQ(1, page_flips_
);
262 TEST_F(HardwareDisplayControllerTest
, RemoveCrtcMidPageFlip
) {
263 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
264 new MockScanoutBuffer(kDefaultModeSize
)));
265 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
266 controller_
->QueueOverlayPlane(plane1
);
267 EXPECT_TRUE(controller_
->SchedulePageFlip(
268 false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
269 base::Unretained(this))));
271 controller_
->RemoveCrtc(drm_
, kPrimaryCrtc
);
273 EXPECT_EQ(1, page_flips_
);
274 drm_
->RunCallbacks();
275 EXPECT_EQ(1, page_flips_
);