Atomic: Notify Watcher to observe device fd
[chromium-blink-merge.git] / ui / ozone / platform / drm / gpu / hardware_display_controller_unittest.cc
blob761438ef80b04ab81fe117e4ee9623ddb52c4153
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.
5 #include "base/bind.h"
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"
15 namespace {
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 {
31 public:
32 MockScanoutBuffer(const gfx::Size& size) : size_(size) {}
34 // ScanoutBuffer:
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; }
40 private:
41 ~MockScanoutBuffer() override {}
43 gfx::Size size_;
45 DISALLOW_COPY_AND_ASSIGN(MockScanoutBuffer);
48 } // namespace
50 class HardwareDisplayControllerTest : public testing::Test {
51 public:
52 HardwareDisplayControllerTest() : page_flips_(0) {}
53 ~HardwareDisplayControllerTest() override {}
55 void SetUp() override;
56 void TearDown() override;
58 void PageFlipCallback(gfx::SwapResult);
60 protected:
61 scoped_ptr<ui::HardwareDisplayController> controller_;
62 scoped_refptr<ui::MockDrmDevice> drm_;
64 int page_flips_;
66 private:
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)),
78 gfx::Point()));
81 void HardwareDisplayControllerTest::TearDown() {
82 controller_.reset();
83 drm_ = nullptr;
86 void HardwareDisplayControllerTest::PageFlipCallback(gfx::SwapResult) {
87 page_flips_++;
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();
146 planes.clear();
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(
199 planes, false, true,
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())
272 if (plane->in_use())
273 owned_plane = plane;
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_);