Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / ozone / platform / drm / gpu / screen_manager_unittest.cc
blobf8b59a66a9796a005a98c5fcae10d6ca884e6a81
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 "testing/gtest/include/gtest/gtest.h"
6 #include "ui/ozone/platform/drm/gpu/crtc_controller.h"
7 #include "ui/ozone/platform/drm/gpu/drm_buffer.h"
8 #include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
9 #include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
10 #include "ui/ozone/platform/drm/gpu/drm_window.h"
11 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
12 #include "ui/ozone/platform/drm/gpu/screen_manager.h"
13 #include "ui/ozone/platform/drm/test/mock_drm_device.h"
15 namespace {
17 void EmptySwapCallback(gfx::SwapResult) {
20 // Create a basic mode for a 6x4 screen.
21 const drmModeModeInfo kDefaultMode =
22 {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
24 const uint32_t kPrimaryCrtc = 1;
25 const uint32_t kPrimaryConnector = 2;
26 const uint32_t kSecondaryCrtc = 3;
27 const uint32_t kSecondaryConnector = 4;
29 } // namespace
31 class ScreenManagerTest : public testing::Test {
32 public:
33 ScreenManagerTest() {}
34 ~ScreenManagerTest() override {}
36 gfx::Rect GetPrimaryBounds() const {
37 return gfx::Rect(0, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay);
40 // Secondary is in extended mode, right-of primary.
41 gfx::Rect GetSecondaryBounds() const {
42 return gfx::Rect(kDefaultMode.hdisplay, 0, kDefaultMode.hdisplay,
43 kDefaultMode.vdisplay);
46 void SetUp() override {
47 drm_ = new ui::MockDrmDevice();
48 device_manager_.reset(new ui::DrmDeviceManager(nullptr));
49 buffer_generator_.reset(new ui::DrmBufferGenerator());
50 screen_manager_.reset(new ui::ScreenManager(buffer_generator_.get()));
52 void TearDown() override {
53 screen_manager_.reset();
54 drm_ = nullptr;
57 protected:
58 scoped_refptr<ui::MockDrmDevice> drm_;
59 scoped_ptr<ui::DrmDeviceManager> device_manager_;
60 scoped_ptr<ui::DrmBufferGenerator> buffer_generator_;
61 scoped_ptr<ui::ScreenManager> screen_manager_;
63 private:
64 DISALLOW_COPY_AND_ASSIGN(ScreenManagerTest);
67 TEST_F(ScreenManagerTest, CheckWithNoControllers) {
68 EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
71 TEST_F(ScreenManagerTest, CheckWithValidController) {
72 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
73 screen_manager_->ConfigureDisplayController(
74 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
75 kDefaultMode);
76 ui::HardwareDisplayController* controller =
77 screen_manager_->GetDisplayController(GetPrimaryBounds());
79 EXPECT_TRUE(controller);
80 EXPECT_TRUE(controller->HasCrtc(drm_, kPrimaryCrtc));
83 TEST_F(ScreenManagerTest, CheckWithInvalidBounds) {
84 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
85 screen_manager_->ConfigureDisplayController(
86 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
87 kDefaultMode);
89 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
90 EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
93 TEST_F(ScreenManagerTest, CheckForSecondValidController) {
94 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
95 screen_manager_->ConfigureDisplayController(
96 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
97 kDefaultMode);
98 screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
99 kSecondaryConnector);
100 screen_manager_->ConfigureDisplayController(
101 drm_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(),
102 kDefaultMode);
104 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
105 EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
108 TEST_F(ScreenManagerTest, CheckControllerAfterItIsRemoved) {
109 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
110 screen_manager_->ConfigureDisplayController(
111 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
112 kDefaultMode);
113 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
115 screen_manager_->RemoveDisplayController(drm_, kPrimaryCrtc);
116 EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
119 TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) {
120 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
121 screen_manager_->ConfigureDisplayController(
122 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
123 kDefaultMode);
124 uint32_t framebuffer = drm_->current_framebuffer();
126 screen_manager_->ConfigureDisplayController(
127 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
128 kDefaultMode);
130 // Should not hold onto buffers.
131 EXPECT_NE(framebuffer, drm_->current_framebuffer());
133 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
134 EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
137 TEST_F(ScreenManagerTest, CheckChangingMode) {
138 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
139 screen_manager_->ConfigureDisplayController(
140 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
141 kDefaultMode);
142 drmModeModeInfo new_mode = kDefaultMode;
143 new_mode.vdisplay = 10;
144 screen_manager_->ConfigureDisplayController(
145 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
146 new_mode);
148 gfx::Rect new_bounds(0, 0, new_mode.hdisplay, new_mode.vdisplay);
149 EXPECT_TRUE(screen_manager_->GetDisplayController(new_bounds));
150 EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
151 drmModeModeInfo mode =
152 screen_manager_->GetDisplayController(new_bounds)->get_mode();
153 EXPECT_EQ(new_mode.vdisplay, mode.vdisplay);
154 EXPECT_EQ(new_mode.hdisplay, mode.hdisplay);
157 TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) {
158 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
159 screen_manager_->ConfigureDisplayController(
160 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
161 kDefaultMode);
162 screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
163 kSecondaryConnector);
164 screen_manager_->ConfigureDisplayController(
165 drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
166 kDefaultMode);
168 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
169 EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
172 TEST_F(ScreenManagerTest, CheckMirrorModeTransitions) {
173 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
174 screen_manager_->ConfigureDisplayController(
175 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
176 kDefaultMode);
177 screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
178 kSecondaryConnector);
179 screen_manager_->ConfigureDisplayController(
180 drm_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(),
181 kDefaultMode);
183 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
184 EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
186 screen_manager_->ConfigureDisplayController(
187 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
188 kDefaultMode);
189 screen_manager_->ConfigureDisplayController(
190 drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
191 kDefaultMode);
192 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
193 EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
195 screen_manager_->ConfigureDisplayController(
196 drm_, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(),
197 kDefaultMode);
198 screen_manager_->ConfigureDisplayController(
199 drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
200 kDefaultMode);
201 EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
202 EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
205 TEST_F(ScreenManagerTest, MonitorGoneInMirrorMode) {
206 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
207 screen_manager_->ConfigureDisplayController(
208 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
209 kDefaultMode);
210 screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
211 kSecondaryConnector);
212 screen_manager_->ConfigureDisplayController(
213 drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
214 kDefaultMode);
216 screen_manager_->RemoveDisplayController(drm_, kSecondaryCrtc);
218 ui::HardwareDisplayController* controller =
219 screen_manager_->GetDisplayController(GetPrimaryBounds());
220 EXPECT_TRUE(controller);
221 EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
223 EXPECT_TRUE(controller->HasCrtc(drm_, kPrimaryCrtc));
224 EXPECT_FALSE(controller->HasCrtc(drm_, kSecondaryCrtc));
227 TEST_F(ScreenManagerTest, MonitorDisabledInMirrorMode) {
228 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
229 screen_manager_->ConfigureDisplayController(
230 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
231 kDefaultMode);
232 screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
233 kSecondaryConnector);
234 screen_manager_->ConfigureDisplayController(
235 drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
236 kDefaultMode);
238 screen_manager_->DisableDisplayController(drm_, kSecondaryCrtc);
240 ui::HardwareDisplayController* controller =
241 screen_manager_->GetDisplayController(GetPrimaryBounds());
242 EXPECT_TRUE(controller);
243 EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
245 EXPECT_TRUE(controller->HasCrtc(drm_, kPrimaryCrtc));
246 EXPECT_FALSE(controller->HasCrtc(drm_, kSecondaryCrtc));
249 TEST_F(ScreenManagerTest, DoNotEnterMirrorModeUnlessSameBounds) {
250 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
251 screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
252 kSecondaryConnector);
254 // Configure displays in extended mode.
255 screen_manager_->ConfigureDisplayController(
256 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
257 kDefaultMode);
258 screen_manager_->ConfigureDisplayController(
259 drm_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(),
260 kDefaultMode);
262 drmModeModeInfo new_mode = kDefaultMode;
263 new_mode.vdisplay = 10;
264 // Shouldn't enter mirror mode unless the display bounds are the same.
265 screen_manager_->ConfigureDisplayController(
266 drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
267 new_mode);
269 EXPECT_FALSE(
270 screen_manager_->GetDisplayController(GetPrimaryBounds())->IsMirrored());
273 TEST_F(ScreenManagerTest, ReuseFramebufferIfDisabledThenReEnabled) {
274 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
275 screen_manager_->ConfigureDisplayController(
276 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
277 kDefaultMode);
278 uint32_t framebuffer = drm_->current_framebuffer();
280 screen_manager_->DisableDisplayController(drm_, kPrimaryCrtc);
281 EXPECT_EQ(0u, drm_->current_framebuffer());
283 screen_manager_->ConfigureDisplayController(
284 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
285 kDefaultMode);
287 // Buffers are released when disabled.
288 EXPECT_NE(framebuffer, drm_->current_framebuffer());
291 TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) {
292 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
293 screen_manager_->ConfigureDisplayController(
294 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
295 kDefaultMode);
296 screen_manager_->DisableDisplayController(drm_, kPrimaryCrtc);
298 screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
299 kSecondaryConnector);
300 screen_manager_->ConfigureDisplayController(
301 drm_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(),
302 kDefaultMode);
304 ui::HardwareDisplayController* controller =
305 screen_manager_->GetDisplayController(GetPrimaryBounds());
306 EXPECT_TRUE(controller);
307 EXPECT_FALSE(controller->IsMirrored());
309 screen_manager_->ConfigureDisplayController(
310 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
311 kDefaultMode);
312 EXPECT_TRUE(controller);
313 EXPECT_TRUE(controller->IsMirrored());
316 TEST_F(ScreenManagerTest,
317 CheckProperConfigurationWithDifferentDeviceAndSameCrtc) {
318 scoped_refptr<ui::MockDrmDevice> drm2 = new ui::MockDrmDevice();
320 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
321 screen_manager_->AddDisplayController(drm2, kPrimaryCrtc, kPrimaryConnector);
323 screen_manager_->ConfigureDisplayController(
324 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
325 kDefaultMode);
326 screen_manager_->ConfigureDisplayController(
327 drm2, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(),
328 kDefaultMode);
330 ui::HardwareDisplayController* controller1 =
331 screen_manager_->GetDisplayController(GetPrimaryBounds());
332 ui::HardwareDisplayController* controller2 =
333 screen_manager_->GetDisplayController(GetSecondaryBounds());
335 EXPECT_NE(controller1, controller2);
336 EXPECT_EQ(drm_, controller1->crtc_controllers()[0]->drm());
337 EXPECT_EQ(drm2, controller2->crtc_controllers()[0]->drm());
340 TEST_F(ScreenManagerTest, CheckControllerToWindowMappingWithSameBounds) {
341 scoped_ptr<ui::DrmWindow> window(
342 new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
343 window->Initialize();
344 window->OnBoundsChanged(GetPrimaryBounds());
345 screen_manager_->AddWindow(1, window.Pass());
347 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
348 screen_manager_->ConfigureDisplayController(
349 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
350 kDefaultMode);
352 EXPECT_TRUE(screen_manager_->GetWindow(1)->GetController());
354 window = screen_manager_->RemoveWindow(1);
355 window->Shutdown();
358 TEST_F(ScreenManagerTest, CheckControllerToWindowMappingWithDifferentBounds) {
359 scoped_ptr<ui::DrmWindow> window(
360 new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
361 window->Initialize();
362 gfx::Rect new_bounds = GetPrimaryBounds();
363 new_bounds.Inset(0, 0, 1, 1);
364 window->OnBoundsChanged(new_bounds);
365 screen_manager_->AddWindow(1, window.Pass());
367 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
368 screen_manager_->ConfigureDisplayController(
369 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
370 kDefaultMode);
372 EXPECT_FALSE(screen_manager_->GetWindow(1)->GetController());
374 window = screen_manager_->RemoveWindow(1);
375 window->Shutdown();
378 TEST_F(ScreenManagerTest,
379 CheckControllerToWindowMappingWithOverlappingWindows) {
380 const size_t kWindowCount = 2;
381 for (size_t i = 1; i < kWindowCount + 1; ++i) {
382 scoped_ptr<ui::DrmWindow> window(
383 new ui::DrmWindow(i, device_manager_.get(), screen_manager_.get()));
384 window->Initialize();
385 window->OnBoundsChanged(GetPrimaryBounds());
386 screen_manager_->AddWindow(i, window.Pass());
389 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
390 screen_manager_->ConfigureDisplayController(
391 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
392 kDefaultMode);
394 bool window1_has_controller = screen_manager_->GetWindow(1)->GetController();
395 bool window2_has_controller = screen_manager_->GetWindow(2)->GetController();
396 // Only one of the windows can have a controller.
397 EXPECT_TRUE(window1_has_controller ^ window2_has_controller);
399 for (size_t i = 1; i < kWindowCount + 1; ++i) {
400 scoped_ptr<ui::DrmWindow> window = screen_manager_->RemoveWindow(i);
401 window->Shutdown();
405 TEST_F(ScreenManagerTest, ShouldDissociateWindowOnControllerRemoval) {
406 gfx::AcceleratedWidget window_id = 1;
407 scoped_ptr<ui::DrmWindow> window(new ui::DrmWindow(
408 window_id, device_manager_.get(), screen_manager_.get()));
409 window->Initialize();
410 window->OnBoundsChanged(GetPrimaryBounds());
411 screen_manager_->AddWindow(window_id, window.Pass());
413 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
414 screen_manager_->ConfigureDisplayController(
415 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
416 kDefaultMode);
418 EXPECT_TRUE(screen_manager_->GetWindow(window_id)->GetController());
420 screen_manager_->RemoveDisplayController(drm_, kPrimaryCrtc);
422 EXPECT_FALSE(screen_manager_->GetWindow(window_id)->GetController());
424 window = screen_manager_->RemoveWindow(1);
425 window->Shutdown();
428 TEST_F(ScreenManagerTest, EnableControllerWhenWindowHasNoBuffer) {
429 scoped_ptr<ui::DrmWindow> window(
430 new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
431 window->Initialize();
432 window->OnBoundsChanged(GetPrimaryBounds());
433 screen_manager_->AddWindow(1, window.Pass());
435 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
436 screen_manager_->ConfigureDisplayController(
437 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
438 kDefaultMode);
440 EXPECT_TRUE(screen_manager_->GetWindow(1)->GetController());
441 // There is a buffer after initial config.
442 uint32_t framebuffer = drm_->current_framebuffer();
443 EXPECT_NE(0U, framebuffer);
445 screen_manager_->ConfigureDisplayController(
446 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
447 kDefaultMode);
449 // There is a new buffer after we configured with the same mode but no
450 // pending frames on the window.
451 EXPECT_NE(framebuffer, drm_->current_framebuffer());
453 window = screen_manager_->RemoveWindow(1);
454 window->Shutdown();
457 TEST_F(ScreenManagerTest, EnableControllerWhenWindowHasBuffer) {
458 scoped_ptr<ui::DrmWindow> window(
459 new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
460 window->Initialize();
461 window->OnBoundsChanged(GetPrimaryBounds());
462 scoped_refptr<ui::ScanoutBuffer> buffer =
463 buffer_generator_->Create(drm_, GetPrimaryBounds().size());
464 window->QueueOverlayPlane(ui::OverlayPlane(buffer));
465 window->SchedulePageFlip(false /* is_sync */, base::Bind(&EmptySwapCallback));
466 screen_manager_->AddWindow(1, window.Pass());
468 screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
469 screen_manager_->ConfigureDisplayController(
470 drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
471 kDefaultMode);
473 EXPECT_EQ(buffer->GetFramebufferId(), drm_->current_framebuffer());
475 window = screen_manager_->RemoveWindow(1);
476 window->Shutdown();