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_manager.h"
9 #include "ui/ozone/platform/drm/gpu/drm_window.h"
10 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
11 #include "ui/ozone/platform/drm/gpu/screen_manager.h"
12 #include "ui/ozone/platform/drm/test/mock_drm_device.h"
16 // Create a basic mode for a 6x4 screen.
17 const drmModeModeInfo kDefaultMode
=
18 {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
20 const uint32_t kPrimaryCrtc
= 1;
21 const uint32_t kPrimaryConnector
= 2;
22 const uint32_t kSecondaryCrtc
= 3;
23 const uint32_t kSecondaryConnector
= 4;
27 class ScreenManagerTest
: public testing::Test
{
29 ScreenManagerTest() {}
30 ~ScreenManagerTest() override
{}
32 gfx::Rect
GetPrimaryBounds() const {
33 return gfx::Rect(0, 0, kDefaultMode
.hdisplay
, kDefaultMode
.vdisplay
);
36 // Secondary is in extended mode, right-of primary.
37 gfx::Rect
GetSecondaryBounds() const {
38 return gfx::Rect(kDefaultMode
.hdisplay
, 0, kDefaultMode
.hdisplay
,
39 kDefaultMode
.vdisplay
);
42 void SetUp() override
{
43 drm_
= new ui::MockDrmDevice();
44 buffer_generator_
.reset(new ui::DrmBufferGenerator());
45 screen_manager_
.reset(new ui::ScreenManager(buffer_generator_
.get()));
47 void TearDown() override
{
48 screen_manager_
.reset();
53 scoped_refptr
<ui::MockDrmDevice
> drm_
;
54 scoped_ptr
<ui::DrmBufferGenerator
> buffer_generator_
;
55 scoped_ptr
<ui::ScreenManager
> screen_manager_
;
58 DISALLOW_COPY_AND_ASSIGN(ScreenManagerTest
);
61 TEST_F(ScreenManagerTest
, CheckWithNoControllers
) {
62 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
65 TEST_F(ScreenManagerTest
, CheckWithValidController
) {
66 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
67 screen_manager_
->ConfigureDisplayController(
68 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
70 ui::HardwareDisplayController
* controller
=
71 screen_manager_
->GetDisplayController(GetPrimaryBounds());
73 EXPECT_TRUE(controller
);
74 EXPECT_TRUE(controller
->HasCrtc(drm_
, kPrimaryCrtc
));
77 TEST_F(ScreenManagerTest
, CheckWithInvalidBounds
) {
78 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
79 screen_manager_
->ConfigureDisplayController(
80 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
83 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
84 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
87 TEST_F(ScreenManagerTest
, CheckForSecondValidController
) {
88 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
89 screen_manager_
->ConfigureDisplayController(
90 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
92 screen_manager_
->AddDisplayController(drm_
, kSecondaryCrtc
,
94 screen_manager_
->ConfigureDisplayController(
95 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetSecondaryBounds().origin(),
98 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
99 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
102 TEST_F(ScreenManagerTest
, CheckControllerAfterItIsRemoved
) {
103 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
104 screen_manager_
->ConfigureDisplayController(
105 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
107 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
109 screen_manager_
->RemoveDisplayController(drm_
, kPrimaryCrtc
);
110 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
113 TEST_F(ScreenManagerTest
, CheckDuplicateConfiguration
) {
114 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
115 screen_manager_
->ConfigureDisplayController(
116 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
118 uint32_t framebuffer
= drm_
->current_framebuffer();
120 screen_manager_
->ConfigureDisplayController(
121 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
124 // Should reuse existing framebuffer.
125 EXPECT_EQ(framebuffer
, drm_
->current_framebuffer());
127 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
128 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
131 TEST_F(ScreenManagerTest
, CheckChangingMode
) {
132 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
133 screen_manager_
->ConfigureDisplayController(
134 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
136 drmModeModeInfo new_mode
= kDefaultMode
;
137 new_mode
.vdisplay
= 10;
138 screen_manager_
->ConfigureDisplayController(
139 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
142 gfx::Rect
new_bounds(0, 0, new_mode
.hdisplay
, new_mode
.vdisplay
);
143 EXPECT_TRUE(screen_manager_
->GetDisplayController(new_bounds
));
144 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
145 drmModeModeInfo mode
=
146 screen_manager_
->GetDisplayController(new_bounds
)->get_mode();
147 EXPECT_EQ(new_mode
.vdisplay
, mode
.vdisplay
);
148 EXPECT_EQ(new_mode
.hdisplay
, mode
.hdisplay
);
151 TEST_F(ScreenManagerTest
, CheckForControllersInMirroredMode
) {
152 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
153 screen_manager_
->ConfigureDisplayController(
154 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
156 screen_manager_
->AddDisplayController(drm_
, kSecondaryCrtc
,
157 kSecondaryConnector
);
158 screen_manager_
->ConfigureDisplayController(
159 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetPrimaryBounds().origin(),
162 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
163 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
166 TEST_F(ScreenManagerTest
, CheckMirrorModeTransitions
) {
167 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
168 screen_manager_
->ConfigureDisplayController(
169 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
171 screen_manager_
->AddDisplayController(drm_
, kSecondaryCrtc
,
172 kSecondaryConnector
);
173 screen_manager_
->ConfigureDisplayController(
174 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetSecondaryBounds().origin(),
177 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
178 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
180 screen_manager_
->ConfigureDisplayController(
181 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
183 screen_manager_
->ConfigureDisplayController(
184 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetPrimaryBounds().origin(),
186 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
187 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
189 screen_manager_
->ConfigureDisplayController(
190 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetSecondaryBounds().origin(),
192 screen_manager_
->ConfigureDisplayController(
193 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetPrimaryBounds().origin(),
195 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
196 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
199 TEST_F(ScreenManagerTest
, MonitorGoneInMirrorMode
) {
200 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
201 screen_manager_
->ConfigureDisplayController(
202 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
204 screen_manager_
->AddDisplayController(drm_
, kSecondaryCrtc
,
205 kSecondaryConnector
);
206 screen_manager_
->ConfigureDisplayController(
207 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetPrimaryBounds().origin(),
210 screen_manager_
->RemoveDisplayController(drm_
, kSecondaryCrtc
);
211 EXPECT_TRUE(screen_manager_
->ConfigureDisplayController(
212 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
215 EXPECT_TRUE(screen_manager_
->GetDisplayController(GetPrimaryBounds()));
216 EXPECT_FALSE(screen_manager_
->GetDisplayController(GetSecondaryBounds()));
219 TEST_F(ScreenManagerTest
, DoNotEnterMirrorModeUnlessSameBounds
) {
220 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
221 screen_manager_
->AddDisplayController(drm_
, kSecondaryCrtc
,
222 kSecondaryConnector
);
224 // Configure displays in extended mode.
225 screen_manager_
->ConfigureDisplayController(
226 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
228 screen_manager_
->ConfigureDisplayController(
229 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetSecondaryBounds().origin(),
232 drmModeModeInfo new_mode
= kDefaultMode
;
233 new_mode
.vdisplay
= 10;
234 // Shouldn't enter mirror mode unless the display bounds are the same.
235 screen_manager_
->ConfigureDisplayController(
236 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetPrimaryBounds().origin(),
240 screen_manager_
->GetDisplayController(GetPrimaryBounds())->IsMirrored());
243 TEST_F(ScreenManagerTest
, ReuseFramebufferIfDisabledThenReEnabled
) {
244 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
245 screen_manager_
->ConfigureDisplayController(
246 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
248 uint32_t framebuffer
= drm_
->current_framebuffer();
250 screen_manager_
->DisableDisplayController(drm_
, kPrimaryCrtc
);
251 EXPECT_EQ(0u, drm_
->current_framebuffer());
253 screen_manager_
->ConfigureDisplayController(
254 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
257 // Should reuse existing framebuffer.
258 EXPECT_EQ(framebuffer
, drm_
->current_framebuffer());
261 TEST_F(ScreenManagerTest
, CheckMirrorModeAfterBeginReEnabled
) {
262 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
263 screen_manager_
->ConfigureDisplayController(
264 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
266 screen_manager_
->DisableDisplayController(drm_
, kPrimaryCrtc
);
268 screen_manager_
->AddDisplayController(drm_
, kSecondaryCrtc
,
269 kSecondaryConnector
);
270 screen_manager_
->ConfigureDisplayController(
271 drm_
, kSecondaryCrtc
, kSecondaryConnector
, GetPrimaryBounds().origin(),
274 ui::HardwareDisplayController
* controller
=
275 screen_manager_
->GetDisplayController(GetPrimaryBounds());
276 EXPECT_TRUE(controller
);
277 EXPECT_FALSE(controller
->IsMirrored());
279 screen_manager_
->ConfigureDisplayController(
280 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
282 EXPECT_TRUE(controller
);
283 EXPECT_TRUE(controller
->IsMirrored());
286 TEST_F(ScreenManagerTest
,
287 CheckProperConfigurationWithDifferentDeviceAndSameCrtc
) {
288 scoped_refptr
<ui::MockDrmDevice
> drm2
= new ui::MockDrmDevice();
290 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
291 screen_manager_
->AddDisplayController(drm2
, kPrimaryCrtc
, kPrimaryConnector
);
293 screen_manager_
->ConfigureDisplayController(
294 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
296 screen_manager_
->ConfigureDisplayController(
297 drm2
, kPrimaryCrtc
, kPrimaryConnector
, GetSecondaryBounds().origin(),
300 ui::HardwareDisplayController
* controller1
=
301 screen_manager_
->GetDisplayController(GetPrimaryBounds());
302 ui::HardwareDisplayController
* controller2
=
303 screen_manager_
->GetDisplayController(GetSecondaryBounds());
305 EXPECT_NE(controller1
, controller2
);
306 EXPECT_EQ(drm_
, controller1
->crtc_controllers()[0]->drm());
307 EXPECT_EQ(drm2
, controller2
->crtc_controllers()[0]->drm());
310 TEST_F(ScreenManagerTest
, CheckControllerToWindowMappingWithSameBounds
) {
311 ui::DrmDeviceManager
device_manager(drm_
);
312 scoped_ptr
<ui::DrmWindow
> window(
313 new ui::DrmWindow(1, &device_manager
, screen_manager_
.get()));
314 window
->Initialize();
315 window
->OnBoundsChanged(GetPrimaryBounds());
316 screen_manager_
->AddWindow(1, window
.Pass());
318 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
319 screen_manager_
->ConfigureDisplayController(
320 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
323 EXPECT_TRUE(screen_manager_
->GetWindow(1)->GetController());
325 window
= screen_manager_
->RemoveWindow(1);
329 TEST_F(ScreenManagerTest
, CheckControllerToWindowMappingWithDifferentBounds
) {
330 ui::DrmDeviceManager
device_manager(drm_
);
331 scoped_ptr
<ui::DrmWindow
> window(
332 new ui::DrmWindow(1, &device_manager
, screen_manager_
.get()));
333 window
->Initialize();
334 gfx::Rect new_bounds
= GetPrimaryBounds();
335 new_bounds
.Inset(0, 0, 1, 1);
336 window
->OnBoundsChanged(new_bounds
);
337 screen_manager_
->AddWindow(1, window
.Pass());
339 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
340 screen_manager_
->ConfigureDisplayController(
341 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
344 EXPECT_FALSE(screen_manager_
->GetWindow(1)->GetController());
346 window
= screen_manager_
->RemoveWindow(1);
350 TEST_F(ScreenManagerTest
,
351 CheckControllerToWindowMappingWithOverlappingWindows
) {
352 ui::DrmDeviceManager
device_manager(drm_
);
353 const size_t kWindowCount
= 2;
354 for (size_t i
= 1; i
< kWindowCount
+ 1; ++i
) {
355 scoped_ptr
<ui::DrmWindow
> window(
356 new ui::DrmWindow(1, &device_manager
, screen_manager_
.get()));
357 window
->Initialize();
358 window
->OnBoundsChanged(GetPrimaryBounds());
359 screen_manager_
->AddWindow(i
, window
.Pass());
362 screen_manager_
->AddDisplayController(drm_
, kPrimaryCrtc
, kPrimaryConnector
);
363 screen_manager_
->ConfigureDisplayController(
364 drm_
, kPrimaryCrtc
, kPrimaryConnector
, GetPrimaryBounds().origin(),
367 bool window1_has_controller
= screen_manager_
->GetWindow(1)->GetController();
368 bool window2_has_controller
= screen_manager_
->GetWindow(2)->GetController();
369 // Only one of the windows can have a controller.
370 EXPECT_TRUE(window1_has_controller
^ window2_has_controller
);
372 for (size_t i
= 1; i
< kWindowCount
+ 1; ++i
) {
373 scoped_ptr
<ui::DrmWindow
> window
= screen_manager_
->RemoveWindow(i
);