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_
; }
38 uint32_t GetFormat() const override
{ return 0; }
41 ~MockScanoutBuffer() override
{}
45 DISALLOW_COPY_AND_ASSIGN(MockScanoutBuffer
);
50 class HardwareDisplayControllerTest
: public testing::Test
{
52 HardwareDisplayControllerTest() : page_flips_(0) {}
53 ~HardwareDisplayControllerTest() override
{}
55 void SetUp() override
;
56 void TearDown() override
;
58 void PageFlipCallback(gfx::SwapResult
);
61 scoped_ptr
<ui::HardwareDisplayController
> controller_
;
62 scoped_refptr
<ui::MockDrmDevice
> drm_
;
67 DISALLOW_COPY_AND_ASSIGN(HardwareDisplayControllerTest
);
70 void HardwareDisplayControllerTest::SetUp() {
71 std::vector
<uint32_t> crtcs
;
72 crtcs
.push_back(kPrimaryCrtc
);
73 crtcs
.push_back(kSecondaryCrtc
);
74 drm_
= new ui::MockDrmDevice(false, crtcs
, kPlanesPerCrtc
);
75 controller_
.reset(new ui::HardwareDisplayController(
76 scoped_ptr
<ui::CrtcController
>(
77 new ui::CrtcController(drm_
.get(), kPrimaryCrtc
, kPrimaryConnector
)),
81 void HardwareDisplayControllerTest::TearDown() {
86 void HardwareDisplayControllerTest::PageFlipCallback(gfx::SwapResult
) {
90 TEST_F(HardwareDisplayControllerTest
, CheckModesettingResult
) {
91 ui::OverlayPlane
plane(scoped_refptr
<ui::ScanoutBuffer
>(
92 new MockScanoutBuffer(kDefaultModeSize
)));
94 EXPECT_TRUE(controller_
->Modeset(plane
, kDefaultMode
));
95 EXPECT_FALSE(plane
.buffer
->HasOneRef());
98 TEST_F(HardwareDisplayControllerTest
, CheckStateAfterPageFlip
) {
99 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
100 new MockScanoutBuffer(kDefaultModeSize
)));
102 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
104 ui::OverlayPlane
plane2(scoped_refptr
<ui::ScanoutBuffer
>(
105 new MockScanoutBuffer(kDefaultModeSize
)));
106 std::vector
<ui::OverlayPlane
> planes
=
107 std::vector
<ui::OverlayPlane
>(1, plane2
);
108 EXPECT_TRUE(controller_
->SchedulePageFlip(
109 planes
, false, false,
110 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
111 base::Unretained(this))));
112 drm_
->RunCallbacks();
113 EXPECT_TRUE(plane1
.buffer
->HasOneRef());
114 EXPECT_FALSE(plane2
.buffer
->HasOneRef());
116 EXPECT_EQ(1, drm_
->get_page_flip_call_count());
117 EXPECT_EQ(0, drm_
->get_overlay_flip_call_count());
120 TEST_F(HardwareDisplayControllerTest
, CheckStateIfModesetFails
) {
121 drm_
->set_set_crtc_expectation(false);
123 ui::OverlayPlane
plane(scoped_refptr
<ui::ScanoutBuffer
>(
124 new MockScanoutBuffer(kDefaultModeSize
)));
126 EXPECT_FALSE(controller_
->Modeset(plane
, kDefaultMode
));
129 TEST_F(HardwareDisplayControllerTest
, CheckStateIfPageFlipFails
) {
130 drm_
->set_page_flip_expectation(false);
132 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
133 new MockScanoutBuffer(kDefaultModeSize
)));
135 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
137 ui::OverlayPlane
plane2(scoped_refptr
<ui::ScanoutBuffer
>(
138 new MockScanoutBuffer(kDefaultModeSize
)));
139 std::vector
<ui::OverlayPlane
> planes
=
140 std::vector
<ui::OverlayPlane
>(1, plane2
);
141 EXPECT_FALSE(controller_
->SchedulePageFlip(
142 planes
, false, false,
143 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
144 base::Unretained(this))));
145 drm_
->RunCallbacks();
148 EXPECT_FALSE(plane1
.buffer
->HasOneRef());
149 EXPECT_TRUE(plane2
.buffer
->HasOneRef());
152 TEST_F(HardwareDisplayControllerTest
, CheckOverlayPresent
) {
153 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
154 new MockScanoutBuffer(kDefaultModeSize
)));
155 ui::OverlayPlane
plane2(
156 scoped_refptr
<ui::ScanoutBuffer
>(new MockScanoutBuffer(kDefaultModeSize
)),
157 1, gfx::OVERLAY_TRANSFORM_NONE
, gfx::Rect(kDefaultModeSize
),
158 gfx::RectF(kDefaultModeSizeF
));
160 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
162 std::vector
<ui::OverlayPlane
> planes
;
163 planes
.push_back(plane1
);
164 planes
.push_back(plane2
);
166 EXPECT_TRUE(controller_
->SchedulePageFlip(
167 planes
, false, false,
168 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
169 base::Unretained(this))));
170 drm_
->RunCallbacks();
171 EXPECT_EQ(1, drm_
->get_page_flip_call_count());
172 EXPECT_EQ(1, drm_
->get_overlay_flip_call_count());
175 TEST_F(HardwareDisplayControllerTest
, CheckOverlayTestMode
) {
176 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
177 new MockScanoutBuffer(kDefaultModeSize
)));
178 ui::OverlayPlane
plane2(
179 scoped_refptr
<ui::ScanoutBuffer
>(new MockScanoutBuffer(kDefaultModeSize
)),
180 1, gfx::OVERLAY_TRANSFORM_NONE
, gfx::Rect(kDefaultModeSize
),
181 gfx::RectF(kDefaultModeSizeF
));
183 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
185 std::vector
<ui::OverlayPlane
> planes
;
186 planes
.push_back(plane1
);
187 planes
.push_back(plane2
);
189 EXPECT_TRUE(controller_
->SchedulePageFlip(
190 planes
, false, false,
191 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
192 base::Unretained(this))));
193 drm_
->RunCallbacks();
194 EXPECT_EQ(1, drm_
->get_page_flip_call_count());
195 EXPECT_EQ(1, drm_
->get_overlay_flip_call_count());
197 // A test call shouldn't cause new flips, but should succeed.
198 EXPECT_TRUE(controller_
->SchedulePageFlip(
200 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
201 base::Unretained(this))));
202 drm_
->RunCallbacks();
203 EXPECT_EQ(1, drm_
->get_page_flip_call_count());
204 EXPECT_EQ(1, drm_
->get_overlay_flip_call_count());
206 // Regular flips should continue on normally.
207 EXPECT_TRUE(controller_
->SchedulePageFlip(
208 planes
, false, false,
209 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
210 base::Unretained(this))));
211 drm_
->RunCallbacks();
212 EXPECT_EQ(2, drm_
->get_page_flip_call_count());
213 EXPECT_EQ(2, drm_
->get_overlay_flip_call_count());
216 TEST_F(HardwareDisplayControllerTest
, RejectUnderlays
) {
217 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
218 new MockScanoutBuffer(kDefaultModeSize
)));
219 ui::OverlayPlane
plane2(
220 scoped_refptr
<ui::ScanoutBuffer
>(new MockScanoutBuffer(kDefaultModeSize
)),
221 -1, gfx::OVERLAY_TRANSFORM_NONE
, gfx::Rect(kDefaultModeSize
),
222 gfx::RectF(kDefaultModeSizeF
));
224 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
226 std::vector
<ui::OverlayPlane
> planes
;
227 planes
.push_back(plane1
);
228 planes
.push_back(plane2
);
230 EXPECT_FALSE(controller_
->SchedulePageFlip(
231 planes
, false, false,
232 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
233 base::Unretained(this))));
236 TEST_F(HardwareDisplayControllerTest
, PageflipMirroredControllers
) {
237 controller_
->AddCrtc(scoped_ptr
<ui::CrtcController
>(
238 new ui::CrtcController(drm_
.get(), kSecondaryCrtc
, kSecondaryConnector
)));
240 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
241 new MockScanoutBuffer(kDefaultModeSize
)));
242 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
243 EXPECT_EQ(2, drm_
->get_set_crtc_call_count());
245 ui::OverlayPlane
plane2(scoped_refptr
<ui::ScanoutBuffer
>(
246 new MockScanoutBuffer(kDefaultModeSize
)));
247 std::vector
<ui::OverlayPlane
> planes
=
248 std::vector
<ui::OverlayPlane
>(1, plane2
);
249 EXPECT_TRUE(controller_
->SchedulePageFlip(
250 planes
, false, false,
251 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
252 base::Unretained(this))));
253 drm_
->RunCallbacks();
254 EXPECT_EQ(2, drm_
->get_page_flip_call_count());
255 EXPECT_EQ(1, page_flips_
);
258 TEST_F(HardwareDisplayControllerTest
, PlaneStateAfterRemoveCrtc
) {
259 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
260 new MockScanoutBuffer(kDefaultModeSize
)));
261 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
262 std::vector
<ui::OverlayPlane
> planes
=
263 std::vector
<ui::OverlayPlane
>(1, plane1
);
264 EXPECT_TRUE(controller_
->SchedulePageFlip(
265 planes
, false, false,
266 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
267 base::Unretained(this))));
268 drm_
->RunCallbacks();
270 const ui::HardwareDisplayPlane
* owned_plane
= nullptr;
271 for (const auto& plane
: drm_
->plane_manager()->planes())
274 ASSERT_TRUE(owned_plane
!= nullptr);
275 EXPECT_EQ(kPrimaryCrtc
, owned_plane
->owning_crtc());
276 // Removing the crtc should free the plane.
277 scoped_ptr
<ui::CrtcController
> crtc
=
278 controller_
->RemoveCrtc(drm_
, kPrimaryCrtc
);
279 EXPECT_FALSE(owned_plane
->in_use());
282 TEST_F(HardwareDisplayControllerTest
, ModesetWhilePageFlipping
) {
283 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
284 new MockScanoutBuffer(kDefaultModeSize
)));
285 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
286 std::vector
<ui::OverlayPlane
> planes
=
287 std::vector
<ui::OverlayPlane
>(1, plane1
);
288 EXPECT_TRUE(controller_
->SchedulePageFlip(
289 planes
, false, false,
290 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
291 base::Unretained(this))));
293 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
294 drm_
->RunCallbacks();
295 EXPECT_EQ(1, page_flips_
);
298 TEST_F(HardwareDisplayControllerTest
, AddCrtcMidPageFlip
) {
299 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
300 new MockScanoutBuffer(kDefaultModeSize
)));
301 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
302 std::vector
<ui::OverlayPlane
> planes
=
303 std::vector
<ui::OverlayPlane
>(1, plane1
);
304 EXPECT_TRUE(controller_
->SchedulePageFlip(
305 planes
, false, false,
306 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
307 base::Unretained(this))));
309 controller_
->AddCrtc(scoped_ptr
<ui::CrtcController
>(
310 new ui::CrtcController(drm_
.get(), kSecondaryCrtc
, kSecondaryConnector
)));
312 drm_
->RunCallbacks();
313 EXPECT_EQ(1, page_flips_
);
316 TEST_F(HardwareDisplayControllerTest
, RemoveCrtcMidPageFlip
) {
317 ui::OverlayPlane
plane1(scoped_refptr
<ui::ScanoutBuffer
>(
318 new MockScanoutBuffer(kDefaultModeSize
)));
319 EXPECT_TRUE(controller_
->Modeset(plane1
, kDefaultMode
));
320 std::vector
<ui::OverlayPlane
> planes
=
321 std::vector
<ui::OverlayPlane
>(1, plane1
);
322 EXPECT_TRUE(controller_
->SchedulePageFlip(
323 planes
, false, false,
324 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback
,
325 base::Unretained(this))));
327 controller_
->RemoveCrtc(drm_
, kPrimaryCrtc
);
329 EXPECT_EQ(1, page_flips_
);
330 drm_
->RunCallbacks();
331 EXPECT_EQ(1, page_flips_
);