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.
4 
5 #include <drm_fourcc.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <xf86drm.h>
9 #include <memory>
10 #include <utility>
11 
12 #include "base/callback_helpers.h"
13 #include "base/files/platform_file.h"
14 #include "base/macros.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gfx/geometry/point.h"
17 #include "ui/gfx/gpu_fence.h"
18 #include "ui/gfx/linux/gbm_buffer.h"
19 #include "ui/gfx/linux/test/mock_gbm_device.h"
20 #include "ui/ozone/platform/drm/common/drm_util.h"
21 #include "ui/ozone/platform/drm/gpu/crtc_controller.h"
22 #include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
23 #include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
24 #include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
25 #include "ui/ozone/platform/drm/gpu/drm_window.h"
26 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
27 #include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
28 #include "ui/ozone/platform/drm/gpu/screen_manager.h"
29 
30 namespace ui {
31 namespace {
32 
33 // Create a basic mode for a 6x4 screen.
34 const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4,     0,
35                                       0, 0, 0, 0, 0, 0, {'\0'}};
36 
37 const uint32_t kPrimaryDisplayId = 1;
38 const uint32_t kSecondaryDisplayId = 2;
39 
40 constexpr uint32_t kCrtcIdBase = 100;
41 constexpr uint32_t kPrimaryCrtc = kCrtcIdBase;
42 constexpr uint32_t kSecondaryCrtc = kCrtcIdBase + 1;
43 
44 constexpr uint32_t kConnectorIdBase = 200;
45 constexpr uint32_t kPrimaryConnector = kConnectorIdBase;
46 constexpr uint32_t kSecondaryConnector = kConnectorIdBase + 1;
47 constexpr uint32_t kPlaneIdBase = 300;
48 constexpr uint32_t kInFormatsBlobPropIdBase = 400;
49 
50 constexpr uint32_t kTypePropId = 3010;
51 constexpr uint32_t kInFormatsPropId = 3011;
52 
ConstructMode(uint16_t hdisplay,uint16_t vdisplay)53 drmModeModeInfo ConstructMode(uint16_t hdisplay, uint16_t vdisplay) {
54   return {0, hdisplay, 0, 0, 0, 0, vdisplay, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
55 }
56 
57 }  // namespace
58 
59 class ScreenManagerTest : public testing::Test {
60  public:
61   struct PlaneState {
62     std::vector<uint32_t> formats;
63   };
64 
65   struct CrtcState {
66     std::vector<PlaneState> planes;
67   };
68 
69   ScreenManagerTest() = default;
70   ~ScreenManagerTest() override = default;
71 
GetPrimaryBounds() const72   gfx::Rect GetPrimaryBounds() const {
73     return gfx::Rect(0, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay);
74   }
75 
76   // Secondary is in extended mode, right-of primary.
GetSecondaryBounds() const77   gfx::Rect GetSecondaryBounds() const {
78     return gfx::Rect(kDefaultMode.hdisplay, 0, kDefaultMode.hdisplay,
79                      kDefaultMode.vdisplay);
80   }
81 
InitializeDrmState(ui::MockDrmDevice * drm,const std::vector<CrtcState> & crtc_states,bool is_atomic=true)82   void InitializeDrmState(ui::MockDrmDevice* drm,
83                           const std::vector<CrtcState>& crtc_states,
84                           bool is_atomic = true) {
85     std::vector<ui::MockDrmDevice::CrtcProperties> crtc_properties(
86         crtc_states.size());
87     std::map<uint32_t, std::string> crtc_property_names = {
88         {1000, "ACTIVE"},
89         {1001, "MODE_ID"},
90     };
91 
92     std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(3);
93     std::map<uint32_t, std::string> connector_property_names = {
94         {2000, "CRTC_ID"},
95     };
96     for (size_t i = 0; i < connector_properties.size(); ++i) {
97       connector_properties[i].id = kPrimaryConnector + i;
98       for (const auto& pair : connector_property_names) {
99         connector_properties[i].properties.push_back(
100             {/* .id = */ pair.first, /* .value = */ 0});
101       }
102     }
103 
104     std::vector<ui::MockDrmDevice::PlaneProperties> plane_properties;
105     std::map<uint32_t, std::string> plane_property_names = {
106         // Add all required properties.
107         {3000, "CRTC_ID"},
108         {3001, "CRTC_X"},
109         {3002, "CRTC_Y"},
110         {3003, "CRTC_W"},
111         {3004, "CRTC_H"},
112         {3005, "FB_ID"},
113         {3006, "SRC_X"},
114         {3007, "SRC_Y"},
115         {3008, "SRC_W"},
116         {3009, "SRC_H"},
117         // Defines some optional properties we use for convenience.
118         {kTypePropId, "type"},
119         {kInFormatsPropId, "IN_FORMATS"},
120     };
121 
122     uint32_t plane_id = kPlaneIdBase;
123     uint32_t property_id = kInFormatsBlobPropIdBase;
124 
125     for (size_t crtc_idx = 0; crtc_idx < crtc_states.size(); ++crtc_idx) {
126       crtc_properties[crtc_idx].id = kPrimaryCrtc + crtc_idx;
127       for (const auto& pair : crtc_property_names) {
128         crtc_properties[crtc_idx].properties.push_back(
129             {/* .id = */ pair.first, /* .value = */ 0});
130       }
131 
132       std::vector<ui::MockDrmDevice::PlaneProperties> crtc_plane_properties(
133           crtc_states[crtc_idx].planes.size());
134       for (size_t plane_idx = 0;
135            plane_idx < crtc_states[crtc_idx].planes.size(); ++plane_idx) {
136         crtc_plane_properties[plane_idx].id = plane_id++;
137         crtc_plane_properties[plane_idx].crtc_mask = 1 << crtc_idx;
138 
139         for (const auto& pair : plane_property_names) {
140           uint64_t value = 0;
141           if (pair.first == kTypePropId) {
142             value = plane_idx == 0 ? DRM_PLANE_TYPE_PRIMARY
143                                    : DRM_PLANE_TYPE_OVERLAY;
144           } else if (pair.first == kInFormatsPropId) {
145             value = property_id++;
146             drm->SetPropertyBlob(ui::MockDrmDevice::AllocateInFormatsBlob(
147                 value, crtc_states[crtc_idx].planes[plane_idx].formats,
148                 std::vector<drm_format_modifier>()));
149           }
150 
151           crtc_plane_properties[plane_idx].properties.push_back(
152               {/* .id = */ pair.first, /* .value = */ value});
153         }
154       }
155 
156       plane_properties.insert(plane_properties.end(),
157                               crtc_plane_properties.begin(),
158                               crtc_plane_properties.end());
159     }
160 
161     std::map<uint32_t, std::string> property_names;
162     property_names.insert(crtc_property_names.begin(),
163                           crtc_property_names.end());
164     property_names.insert(connector_property_names.begin(),
165                           connector_property_names.end());
166     property_names.insert(plane_property_names.begin(),
167                           plane_property_names.end());
168     drm->InitializeState(crtc_properties, connector_properties,
169                          plane_properties, property_names, is_atomic);
170   }
171 
InitializeDrmStateWithDefault(ui::MockDrmDevice * drm,bool is_atomic=true)172   void InitializeDrmStateWithDefault(ui::MockDrmDevice* drm,
173                                      bool is_atomic = true) {
174     // A Sample of CRTC states.
175     std::vector<CrtcState> crtc_states = {
176         {/* .planes = */
177          {
178              {/* .formats = */ {DRM_FORMAT_XRGB8888}},
179          }},
180         {/* .planes = */
181          {
182              {/* .formats = */ {DRM_FORMAT_XRGB8888}},
183          }},
184     };
185     InitializeDrmState(drm, crtc_states, is_atomic);
186   }
187 
SetUp()188   void SetUp() override {
189     auto gbm = std::make_unique<ui::MockGbmDevice>();
190     drm_ = new ui::MockDrmDevice(std::move(gbm));
191     device_manager_ = std::make_unique<ui::DrmDeviceManager>(nullptr);
192     screen_manager_ = std::make_unique<ui::ScreenManager>();
193   }
194 
TearDown()195   void TearDown() override {
196     screen_manager_.reset();
197     drm_ = nullptr;
198   }
199 
CreateBuffer(uint32_t format,const gfx::Size & size)200   scoped_refptr<DrmFramebuffer> CreateBuffer(uint32_t format,
201                                              const gfx::Size& size) {
202     return CreateBufferWithModifier(format, DRM_FORMAT_MOD_NONE, size);
203   }
204 
CreateBufferWithModifier(uint32_t format,uint64_t format_modifier,const gfx::Size & size)205   scoped_refptr<DrmFramebuffer> CreateBufferWithModifier(
206       uint32_t format,
207       uint64_t format_modifier,
208       const gfx::Size& size) {
209     std::vector<uint64_t> modifiers;
210     if (format_modifier != DRM_FORMAT_MOD_NONE)
211       modifiers.push_back(format_modifier);
212     auto buffer = drm_->gbm_device()->CreateBufferWithModifiers(
213         format, size, GBM_BO_USE_SCANOUT, modifiers);
214     return DrmFramebuffer::AddFramebuffer(drm_, buffer.get(), size, modifiers);
215   }
216 
217  protected:
218   scoped_refptr<ui::MockDrmDevice> drm_;
219   std::unique_ptr<ui::DrmDeviceManager> device_manager_;
220   std::unique_ptr<ui::ScreenManager> screen_manager_;
221 
222  private:
223   DISALLOW_COPY_AND_ASSIGN(ScreenManagerTest);
224 };
225 
TEST_F(ScreenManagerTest,CheckWithNoControllers)226 TEST_F(ScreenManagerTest, CheckWithNoControllers) {
227   EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
228   EXPECT_EQ(drm_->get_test_modeset_count(), 0);
229   EXPECT_EQ(drm_->get_commit_modeset_count(), 0);
230   EXPECT_EQ(drm_->get_commit_count(), 0);
231 }
232 
TEST_F(ScreenManagerTest,CheckWithValidController)233 TEST_F(ScreenManagerTest, CheckWithValidController) {
234   InitializeDrmStateWithDefault(drm_.get());
235 
236   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
237 
238   ScreenManager::ControllerConfigsList controllers_to_enable;
239   controllers_to_enable.emplace_back(
240       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
241       GetPrimaryBounds().origin(),
242       std::make_unique<drmModeModeInfo>(kDefaultMode));
243   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
244   EXPECT_EQ(drm_->get_test_modeset_count(), 1);
245   EXPECT_EQ(drm_->get_commit_modeset_count(), 1);
246 
247   ui::HardwareDisplayController* controller =
248       screen_manager_->GetDisplayController(GetPrimaryBounds());
249 
250   EXPECT_TRUE(controller);
251   EXPECT_TRUE(controller->HasCrtc(drm_, kPrimaryCrtc));
252 }
253 
TEST_F(ScreenManagerTest,CheckWithInvalidBounds)254 TEST_F(ScreenManagerTest, CheckWithInvalidBounds) {
255   InitializeDrmStateWithDefault(drm_.get());
256 
257   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
258 
259   ScreenManager::ControllerConfigsList controllers_to_enable;
260   controllers_to_enable.emplace_back(
261       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
262       GetPrimaryBounds().origin(),
263       std::make_unique<drmModeModeInfo>(kDefaultMode));
264   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
265 
266   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
267   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
268 }
269 
TEST_F(ScreenManagerTest,CheckForSecondValidController)270 TEST_F(ScreenManagerTest, CheckForSecondValidController) {
271   InitializeDrmStateWithDefault(drm_.get());
272 
273   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
274   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
275                                         kSecondaryConnector);
276 
277   ScreenManager::ControllerConfigsList controllers_to_enable;
278   controllers_to_enable.emplace_back(
279       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
280       GetPrimaryBounds().origin(),
281       std::make_unique<drmModeModeInfo>(kDefaultMode));
282   drmModeModeInfo secondary_mode = kDefaultMode;
283   controllers_to_enable.emplace_back(
284       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
285       GetSecondaryBounds().origin(),
286       std::make_unique<drmModeModeInfo>(secondary_mode));
287   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
288 
289   EXPECT_EQ(drm_->get_test_modeset_count(), 1);
290   EXPECT_EQ(drm_->get_commit_modeset_count(), 2);
291 
292   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
293   EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
294 }
295 
TEST_F(ScreenManagerTest,CheckControllerAfterItIsRemoved)296 TEST_F(ScreenManagerTest, CheckControllerAfterItIsRemoved) {
297   InitializeDrmStateWithDefault(drm_.get());
298 
299   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
300 
301   ScreenManager::ControllerConfigsList controllers_to_enable;
302   controllers_to_enable.emplace_back(
303       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
304       GetPrimaryBounds().origin(),
305       std::make_unique<drmModeModeInfo>(kDefaultMode));
306   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
307 
308   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
309 
310   ScreenManager::CrtcsWithDrmList controllers_to_remove;
311   controllers_to_remove.emplace_back(kPrimaryCrtc, drm_);
312   screen_manager_->RemoveDisplayControllers(controllers_to_remove);
313   EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
314 }
315 
TEST_F(ScreenManagerTest,CheckControllerAfterDisabled)316 TEST_F(ScreenManagerTest, CheckControllerAfterDisabled) {
317   InitializeDrmStateWithDefault(drm_.get());
318   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
319 
320   // Enable
321   {
322     ScreenManager::ControllerConfigsList controllers_to_enable;
323     controllers_to_enable.emplace_back(
324         kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
325         GetPrimaryBounds().origin(),
326         std::make_unique<drmModeModeInfo>(kDefaultMode));
327     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
328   }
329 
330   int test_modeset_count_before_disable = drm_->get_test_modeset_count();
331   int commit_modeset_count_before_disable = drm_->get_commit_modeset_count();
332   // Disable
333   ScreenManager::ControllerConfigsList controllers_to_enable;
334   controllers_to_enable.emplace_back(kPrimaryDisplayId, drm_, kPrimaryCrtc,
335                                      kPrimaryConnector, gfx::Point(), nullptr);
336   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
337 
338   EXPECT_EQ(drm_->get_test_modeset_count(),
339             test_modeset_count_before_disable + 1);
340   EXPECT_EQ(drm_->get_commit_modeset_count(),
341             commit_modeset_count_before_disable + 1);
342 
343   EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
344 }
345 
TEST_F(ScreenManagerTest,CheckMultipleControllersAfterBeingRemoved)346 TEST_F(ScreenManagerTest, CheckMultipleControllersAfterBeingRemoved) {
347   InitializeDrmStateWithDefault(drm_.get());
348 
349   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
350   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
351                                         kSecondaryConnector);
352 
353   ScreenManager::ControllerConfigsList controllers_to_enable;
354   controllers_to_enable.emplace_back(
355       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
356       GetPrimaryBounds().origin(),
357       std::make_unique<drmModeModeInfo>(kDefaultMode));
358   controllers_to_enable.emplace_back(
359       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
360       GetSecondaryBounds().origin(),
361       std::make_unique<drmModeModeInfo>(kDefaultMode));
362   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
363 
364   int modeset_count_after_enable = drm_->get_commit_modeset_count();
365   ScreenManager::CrtcsWithDrmList controllers_to_remove;
366   controllers_to_remove.emplace_back(kPrimaryCrtc, drm_);
367   controllers_to_remove.emplace_back(kSecondaryCrtc, drm_);
368   screen_manager_->RemoveDisplayControllers(controllers_to_remove);
369 
370   // Removed displays are disabled in only 1 modeset commit.
371   EXPECT_EQ(drm_->get_commit_modeset_count(), modeset_count_after_enable + 1);
372 
373   EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
374   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
375 }
376 
TEST_F(ScreenManagerTest,CheckMultipleControllersAfterBeingDisabled)377 TEST_F(ScreenManagerTest, CheckMultipleControllersAfterBeingDisabled) {
378   InitializeDrmStateWithDefault(drm_.get());
379   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
380   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
381                                         kSecondaryConnector);
382   // Enable
383   {
384     ScreenManager::ControllerConfigsList controllers_to_enable;
385     controllers_to_enable.emplace_back(
386         kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
387         GetPrimaryBounds().origin(),
388         std::make_unique<drmModeModeInfo>(kDefaultMode));
389     controllers_to_enable.emplace_back(
390         kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
391         GetSecondaryBounds().origin(),
392         std::make_unique<drmModeModeInfo>(kDefaultMode));
393     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
394   }
395 
396   int test_modeset_count_before_disable = drm_->get_test_modeset_count();
397   int commit_modeset_count_before_disable = drm_->get_commit_modeset_count();
398   // Disable
399   ScreenManager::ControllerConfigsList controllers_to_enable;
400   controllers_to_enable.emplace_back(kPrimaryDisplayId, drm_, kPrimaryCrtc,
401                                      kPrimaryConnector, gfx::Point(), nullptr);
402   controllers_to_enable.emplace_back(kSecondaryDisplayId, drm_, kSecondaryCrtc,
403                                      kSecondaryConnector, gfx::Point(),
404                                      nullptr);
405   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
406 
407   EXPECT_EQ(drm_->get_test_modeset_count(),
408             test_modeset_count_before_disable + 1);
409   EXPECT_EQ(drm_->get_commit_modeset_count(),
410             commit_modeset_count_before_disable + 2);
411 
412   EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
413   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
414 }
415 
TEST_F(ScreenManagerTest,CheckDuplicateConfiguration)416 TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) {
417   InitializeDrmStateWithDefault(drm_.get(), /*is_atomic*/ false);
418 
419   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
420 
421   ScreenManager::ControllerConfigsList controllers_to_enable;
422   controllers_to_enable.emplace_back(
423       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
424       GetPrimaryBounds().origin(),
425       std::make_unique<drmModeModeInfo>(kDefaultMode));
426   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
427 
428   uint32_t framebuffer = drm_->current_framebuffer();
429 
430   controllers_to_enable.clear();
431   controllers_to_enable.emplace_back(
432       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
433       GetPrimaryBounds().origin(),
434       std::make_unique<drmModeModeInfo>(kDefaultMode));
435   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
436 
437   // Should not hold onto buffers.
438   EXPECT_NE(framebuffer, drm_->current_framebuffer());
439 
440   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
441   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
442 }
443 
TEST_F(ScreenManagerTest,CheckChangingMode)444 TEST_F(ScreenManagerTest, CheckChangingMode) {
445   InitializeDrmStateWithDefault(drm_.get());
446 
447   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
448 
449   // Modeset with default mode.
450   {
451     ScreenManager::ControllerConfigsList controllers_to_enable;
452     controllers_to_enable.emplace_back(
453         kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
454         GetPrimaryBounds().origin(),
455         std::make_unique<drmModeModeInfo>(kDefaultMode));
456     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
457   }
458   auto new_mode = kDefaultMode;
459   new_mode.vdisplay = new_mode.vdisplay++;
460   // Modeset with a changed Mode.
461   {
462     ScreenManager::ControllerConfigsList controllers_to_enable;
463     controllers_to_enable.emplace_back(
464         kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
465         GetPrimaryBounds().origin(),
466         std::make_unique<drmModeModeInfo>(new_mode));
467     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
468   }
469 
470   gfx::Rect new_bounds(0, 0, new_mode.hdisplay, new_mode.vdisplay);
471   EXPECT_TRUE(screen_manager_->GetDisplayController(new_bounds));
472   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
473   drmModeModeInfo mode = screen_manager_->GetDisplayController(new_bounds)
474                              ->crtc_controllers()[0]
475                              ->mode();
476   EXPECT_EQ(new_mode.vdisplay, mode.vdisplay);
477   EXPECT_EQ(new_mode.hdisplay, mode.hdisplay);
478 }
479 
TEST_F(ScreenManagerTest,CheckForControllersInMirroredMode)480 TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) {
481   InitializeDrmStateWithDefault(drm_.get());
482 
483   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
484   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
485                                         kSecondaryConnector);
486 
487   ScreenManager::ControllerConfigsList controllers_to_enable;
488   controllers_to_enable.emplace_back(
489       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
490       GetPrimaryBounds().origin(),
491       std::make_unique<drmModeModeInfo>(kDefaultMode));
492   drmModeModeInfo secondary_mode = kDefaultMode;
493   controllers_to_enable.emplace_back(
494       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
495       GetPrimaryBounds().origin(),
496       std::make_unique<drmModeModeInfo>(secondary_mode));
497   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
498 
499   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
500   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
501 }
502 
TEST_F(ScreenManagerTest,CheckMirrorModeTransitions)503 TEST_F(ScreenManagerTest, CheckMirrorModeTransitions) {
504   std::vector<CrtcState> crtc_states = {
505       {
506           /* .planes = */
507           {
508               {/* .formats = */ {DRM_FORMAT_XRGB8888}},
509               {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
510           },
511       },
512       {
513           /* .planes = */
514           {
515               {/* .formats = */ {DRM_FORMAT_XRGB8888}},
516               {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
517           },
518       },
519   };
520   InitializeDrmState(drm_.get(), crtc_states);
521 
522   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
523   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
524                                         kSecondaryConnector);
525 
526   ScreenManager::ControllerConfigsList controllers_to_enable;
527   controllers_to_enable.emplace_back(
528       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
529       GetPrimaryBounds().origin(),
530       std::make_unique<drmModeModeInfo>(kDefaultMode));
531   drmModeModeInfo secondary_mode = kDefaultMode;
532   controllers_to_enable.emplace_back(
533       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
534       GetSecondaryBounds().origin(),
535       std::make_unique<drmModeModeInfo>(secondary_mode));
536   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
537 
538   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
539   EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
540 
541   controllers_to_enable.clear();
542   drmModeModeInfo transition1_primary_mode = kDefaultMode;
543   controllers_to_enable.emplace_back(
544       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
545       GetPrimaryBounds().origin(),
546       std::make_unique<drmModeModeInfo>(transition1_primary_mode));
547   drmModeModeInfo transition1_secondary_mode = kDefaultMode;
548   controllers_to_enable.emplace_back(
549       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
550       GetPrimaryBounds().origin(),
551       std::make_unique<drmModeModeInfo>(transition1_secondary_mode));
552   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
553 
554   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
555   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
556 
557   controllers_to_enable.clear();
558   drmModeModeInfo transition2_primary_mode = kDefaultMode;
559   controllers_to_enable.emplace_back(
560       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
561       GetSecondaryBounds().origin(),
562       std::make_unique<drmModeModeInfo>(transition2_primary_mode));
563   drmModeModeInfo transition2_secondary_mode = kDefaultMode;
564   controllers_to_enable.emplace_back(
565       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
566       GetPrimaryBounds().origin(),
567       std::make_unique<drmModeModeInfo>(transition2_secondary_mode));
568   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
569 
570   EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds()));
571   EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
572 }
573 
574 // Make sure we're using each display's mode when doing mirror mode otherwise
575 // the timings may be off.
TEST_F(ScreenManagerTest,CheckMirrorModeModesettingWithDisplaysMode)576 TEST_F(ScreenManagerTest, CheckMirrorModeModesettingWithDisplaysMode) {
577   InitializeDrmStateWithDefault(drm_.get());
578 
579   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
580   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
581                                         kSecondaryConnector);
582 
583   ScreenManager::ControllerConfigsList controllers_to_enable;
584   controllers_to_enable.emplace_back(
585       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
586       GetPrimaryBounds().origin(),
587       std::make_unique<drmModeModeInfo>(kDefaultMode));
588   // Copy the mode and use the copy so we can tell what mode the CRTC was
589   // configured with. The clock value is modified so we can tell which mode is
590   // being used.
591   drmModeModeInfo secondary_mode = kDefaultMode;
592   secondary_mode.clock++;
593   controllers_to_enable.emplace_back(
594       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
595       GetPrimaryBounds().origin(),
596       std::make_unique<drmModeModeInfo>(secondary_mode));
597   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
598 
599   ui::HardwareDisplayController* controller =
600       screen_manager_->GetDisplayController(GetPrimaryBounds());
601   for (const auto& crtc : controller->crtc_controllers()) {
602     if (crtc->crtc() == kPrimaryCrtc)
603       EXPECT_EQ(kDefaultMode.clock, crtc->mode().clock);
604     else if (crtc->crtc() == kSecondaryCrtc)
605       EXPECT_EQ(secondary_mode.clock, crtc->mode().clock);
606     else
607       NOTREACHED();
608   }
609 }
610 
TEST_F(ScreenManagerTest,MonitorGoneInMirrorMode)611 TEST_F(ScreenManagerTest, MonitorGoneInMirrorMode) {
612   InitializeDrmStateWithDefault(drm_.get());
613 
614   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
615   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
616                                         kSecondaryConnector);
617 
618   ScreenManager::ControllerConfigsList controllers_to_enable;
619   controllers_to_enable.emplace_back(
620       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
621       GetPrimaryBounds().origin(),
622       std::make_unique<drmModeModeInfo>(kDefaultMode));
623   drmModeModeInfo secondary_mode = kDefaultMode;
624   controllers_to_enable.emplace_back(
625       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
626       GetPrimaryBounds().origin(),
627       std::make_unique<drmModeModeInfo>(secondary_mode));
628   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
629 
630   ScreenManager::CrtcsWithDrmList controllers_to_remove;
631   controllers_to_remove.emplace_back(kSecondaryCrtc, drm_);
632   screen_manager_->RemoveDisplayControllers(controllers_to_remove);
633 
634   ui::HardwareDisplayController* controller =
635       screen_manager_->GetDisplayController(GetPrimaryBounds());
636   EXPECT_TRUE(controller);
637   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
638 
639   EXPECT_TRUE(controller->HasCrtc(drm_, kPrimaryCrtc));
640   EXPECT_FALSE(controller->HasCrtc(drm_, kSecondaryCrtc));
641 }
642 
TEST_F(ScreenManagerTest,MonitorDisabledInMirrorMode)643 TEST_F(ScreenManagerTest, MonitorDisabledInMirrorMode) {
644   InitializeDrmStateWithDefault(drm_.get());
645 
646   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
647   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
648                                         kSecondaryConnector);
649 
650   ScreenManager::ControllerConfigsList controllers_to_enable;
651   controllers_to_enable.emplace_back(
652       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
653       GetPrimaryBounds().origin(),
654       std::make_unique<drmModeModeInfo>(kDefaultMode));
655   drmModeModeInfo secondary_mode = kDefaultMode;
656   controllers_to_enable.emplace_back(
657       kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
658       GetPrimaryBounds().origin(),
659       std::make_unique<drmModeModeInfo>(secondary_mode));
660   // Disable display Controller.
661   controllers_to_enable.emplace_back(0, drm_, kSecondaryCrtc, 0, gfx::Point(),
662                                      nullptr);
663   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
664 
665   ui::HardwareDisplayController* controller =
666       screen_manager_->GetDisplayController(GetPrimaryBounds());
667   EXPECT_TRUE(controller);
668   EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds()));
669 
670   EXPECT_TRUE(controller->HasCrtc(drm_, kPrimaryCrtc));
671   EXPECT_FALSE(controller->HasCrtc(drm_, kSecondaryCrtc));
672 }
673 
TEST_F(ScreenManagerTest,DoNotEnterMirrorModeUnlessSameBounds)674 TEST_F(ScreenManagerTest, DoNotEnterMirrorModeUnlessSameBounds) {
675   InitializeDrmStateWithDefault(drm_.get());
676 
677   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
678   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
679                                         kSecondaryConnector);
680 
681   // Configure displays in extended mode.
682   {
683     ScreenManager::ControllerConfigsList controllers_to_enable;
684     controllers_to_enable.emplace_back(
685         kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
686         GetPrimaryBounds().origin(),
687         std::make_unique<drmModeModeInfo>(kDefaultMode));
688     drmModeModeInfo secondary_mode = kDefaultMode;
689     controllers_to_enable.emplace_back(
690         kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
691         GetSecondaryBounds().origin(),
692         std::make_unique<drmModeModeInfo>(secondary_mode));
693     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
694   }
695 
696   {
697     auto new_mode = std::make_unique<drmModeModeInfo>(kDefaultMode);
698     new_mode->vdisplay = 10;
699     // Shouldn't enter mirror mode unless the display bounds are the same.
700     ScreenManager::ControllerConfigsList controllers_to_enable;
701     controllers_to_enable.emplace_back(
702         kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
703         GetPrimaryBounds().origin(), std::move(new_mode));
704     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
705   }
706 
707   EXPECT_FALSE(
708       screen_manager_->GetDisplayController(GetPrimaryBounds())->IsMirrored());
709 }
710 
TEST_F(ScreenManagerTest,ReuseFramebufferIfDisabledThenReEnabled)711 TEST_F(ScreenManagerTest, ReuseFramebufferIfDisabledThenReEnabled) {
712   InitializeDrmStateWithDefault(drm_.get(), /*is_atomic=*/false);
713 
714   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
715   ScreenManager::ControllerConfigsList controllers_to_enable;
716   controllers_to_enable.emplace_back(
717       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
718       GetPrimaryBounds().origin(),
719       std::make_unique<drmModeModeInfo>(kDefaultMode));
720   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
721 
722   uint32_t framebuffer = drm_->current_framebuffer();
723 
724   controllers_to_enable.clear();
725   // Disable display controller.
726   controllers_to_enable.emplace_back(0, drm_, kPrimaryCrtc, 0, gfx::Point(),
727                                      nullptr);
728   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
729   EXPECT_EQ(0u, drm_->current_framebuffer());
730 
731   controllers_to_enable.clear();
732   drmModeModeInfo reenable_mode = kDefaultMode;
733   controllers_to_enable.emplace_back(
734       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
735       GetPrimaryBounds().origin(),
736       std::make_unique<drmModeModeInfo>(reenable_mode));
737   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
738 
739   // Buffers are released when disabled.
740   EXPECT_NE(framebuffer, drm_->current_framebuffer());
741 }
742 
TEST_F(ScreenManagerTest,CheckMirrorModeAfterBeginReEnabled)743 TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) {
744   InitializeDrmStateWithDefault(drm_.get());
745 
746   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
747   screen_manager_->AddDisplayController(drm_, kSecondaryCrtc,
748                                         kSecondaryConnector);
749   {
750     ScreenManager::ControllerConfigsList controllers_to_enable;
751     controllers_to_enable.emplace_back(
752         kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
753         GetPrimaryBounds().origin(),
754         std::make_unique<drmModeModeInfo>(kDefaultMode));
755     drmModeModeInfo secondary_mode = kDefaultMode;
756     controllers_to_enable.emplace_back(
757         kSecondaryDisplayId, drm_, kSecondaryCrtc, kSecondaryConnector,
758         GetPrimaryBounds().origin(),
759         std::make_unique<drmModeModeInfo>(secondary_mode));
760     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
761   }
762   {
763     ScreenManager::ControllerConfigsList controllers_to_enable;
764     controllers_to_enable.emplace_back(0, drm_, kPrimaryCrtc, 0, gfx::Point(),
765                                        nullptr);
766     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
767   }
768 
769   ui::HardwareDisplayController* controller =
770       screen_manager_->GetDisplayController(GetPrimaryBounds());
771   EXPECT_TRUE(controller);
772   EXPECT_FALSE(controller->IsMirrored());
773 
774   {
775     ScreenManager::ControllerConfigsList controllers_to_enable;
776     drmModeModeInfo reenable_mode = kDefaultMode;
777     controllers_to_enable.emplace_back(
778         kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
779         GetPrimaryBounds().origin(),
780         std::make_unique<drmModeModeInfo>(reenable_mode));
781     screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
782   }
783 
784   EXPECT_TRUE(controller);
785   EXPECT_TRUE(controller->IsMirrored());
786 }
787 
TEST_F(ScreenManagerTest,ConfigureOnDifferentDrmDevices)788 TEST_F(ScreenManagerTest, ConfigureOnDifferentDrmDevices) {
789   auto gbm_device = std::make_unique<ui::MockGbmDevice>();
790   scoped_refptr<ui::MockDrmDevice> drm2 =
791       new ui::MockDrmDevice(std::move(gbm_device));
792 
793   InitializeDrmStateWithDefault(drm_.get(), /*is_atomic=*/false);
794   std::vector<CrtcState> crtc_states = {
795       {/* .planes = */
796        {
797            {/* .formats = */ {DRM_FORMAT_XRGB8888}},
798        }},
799       {/* .planes = */
800        {
801            {/* .formats = */ {DRM_FORMAT_XRGB8888}},
802        }},
803       {/* .planes = */
804        {
805            {/* .formats = */ {DRM_FORMAT_XRGB8888}},
806        }}};
807   InitializeDrmState(drm2.get(), crtc_states, /*is_atomic=*/false);
808 
809   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
810   screen_manager_->AddDisplayController(drm2, kSecondaryCrtc,
811                                         kSecondaryConnector);
812   screen_manager_->AddDisplayController(drm2, kSecondaryCrtc + 1,
813                                         kSecondaryConnector + 1);
814 
815   ScreenManager::ControllerConfigsList controllers_to_enable;
816   controllers_to_enable.emplace_back(
817       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
818       GetPrimaryBounds().origin(),
819       std::make_unique<drmModeModeInfo>(kDefaultMode));
820   drmModeModeInfo secondary_mode = kDefaultMode;
821   controllers_to_enable.emplace_back(
822       kSecondaryDisplayId, drm2, kSecondaryCrtc, kSecondaryConnector,
823       GetSecondaryBounds().origin(),
824       std::make_unique<drmModeModeInfo>(secondary_mode));
825   drmModeModeInfo secondary_mode2 = kDefaultMode;
826   controllers_to_enable.emplace_back(
827       kSecondaryDisplayId + 1, drm2, kSecondaryCrtc + 1,
828       kSecondaryConnector + 1, GetSecondaryBounds().origin(),
829       std::make_unique<drmModeModeInfo>(secondary_mode2));
830   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
831 
832   EXPECT_EQ(drm_->get_set_crtc_call_count(), 1);
833   EXPECT_EQ(drm2->get_set_crtc_call_count(), 2);
834 }
835 
TEST_F(ScreenManagerTest,CheckProperConfigurationWithDifferentDeviceAndSameCrtc)836 TEST_F(ScreenManagerTest,
837        CheckProperConfigurationWithDifferentDeviceAndSameCrtc) {
838   auto gbm_device = std::make_unique<ui::MockGbmDevice>();
839   scoped_refptr<ui::MockDrmDevice> drm2 =
840       new ui::MockDrmDevice(std::move(gbm_device));
841 
842   InitializeDrmStateWithDefault(drm_.get());
843   InitializeDrmStateWithDefault(drm2.get());
844 
845   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
846   screen_manager_->AddDisplayController(drm2, kPrimaryCrtc, kPrimaryConnector);
847 
848   ScreenManager::ControllerConfigsList controllers_to_enable;
849   controllers_to_enable.emplace_back(
850       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
851       GetPrimaryBounds().origin(),
852       std::make_unique<drmModeModeInfo>(kDefaultMode));
853   drmModeModeInfo secondary_mode = kDefaultMode;
854   controllers_to_enable.emplace_back(
855       kSecondaryDisplayId, drm2, kPrimaryCrtc, kPrimaryConnector,
856       GetSecondaryBounds().origin(),
857       std::make_unique<drmModeModeInfo>(secondary_mode));
858   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
859 
860   ui::HardwareDisplayController* controller1 =
861       screen_manager_->GetDisplayController(GetPrimaryBounds());
862   ui::HardwareDisplayController* controller2 =
863       screen_manager_->GetDisplayController(GetSecondaryBounds());
864 
865   EXPECT_NE(controller1, controller2);
866   EXPECT_EQ(drm_, controller1->crtc_controllers()[0]->drm());
867   EXPECT_EQ(drm2, controller2->crtc_controllers()[0]->drm());
868 }
869 
TEST_F(ScreenManagerTest,CheckControllerToWindowMappingWithSameBounds)870 TEST_F(ScreenManagerTest, CheckControllerToWindowMappingWithSameBounds) {
871   InitializeDrmStateWithDefault(drm_.get());
872 
873   std::unique_ptr<ui::DrmWindow> window(
874       new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
875   window->Initialize();
876   window->SetBounds(GetPrimaryBounds());
877   screen_manager_->AddWindow(1, std::move(window));
878 
879   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
880   ScreenManager::ControllerConfigsList controllers_to_enable;
881   controllers_to_enable.emplace_back(
882       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
883       GetPrimaryBounds().origin(),
884       std::make_unique<drmModeModeInfo>(kDefaultMode));
885   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
886 
887   EXPECT_TRUE(screen_manager_->GetWindow(1)->GetController());
888 
889   window = screen_manager_->RemoveWindow(1);
890   window->Shutdown();
891 }
892 
TEST_F(ScreenManagerTest,CheckControllerToWindowMappingWithDifferentBounds)893 TEST_F(ScreenManagerTest, CheckControllerToWindowMappingWithDifferentBounds) {
894   InitializeDrmStateWithDefault(drm_.get());
895 
896   std::unique_ptr<ui::DrmWindow> window(
897       new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
898   window->Initialize();
899   gfx::Rect new_bounds = GetPrimaryBounds();
900   new_bounds.Inset(0, 0, 1, 1);
901   window->SetBounds(new_bounds);
902   screen_manager_->AddWindow(1, std::move(window));
903 
904   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
905   ScreenManager::ControllerConfigsList controllers_to_enable;
906   controllers_to_enable.emplace_back(
907       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
908       GetPrimaryBounds().origin(),
909       std::make_unique<drmModeModeInfo>(kDefaultMode));
910   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
911 
912   EXPECT_FALSE(screen_manager_->GetWindow(1)->GetController());
913 
914   window = screen_manager_->RemoveWindow(1);
915   window->Shutdown();
916 }
917 
TEST_F(ScreenManagerTest,CheckControllerToWindowMappingWithOverlappingWindows)918 TEST_F(ScreenManagerTest,
919        CheckControllerToWindowMappingWithOverlappingWindows) {
920   InitializeDrmStateWithDefault(drm_.get());
921 
922   const size_t kWindowCount = 2;
923   for (size_t i = 1; i < kWindowCount + 1; ++i) {
924     std::unique_ptr<ui::DrmWindow> window(
925         new ui::DrmWindow(i, device_manager_.get(), screen_manager_.get()));
926     window->Initialize();
927     window->SetBounds(GetPrimaryBounds());
928     screen_manager_->AddWindow(i, std::move(window));
929   }
930 
931   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
932   ScreenManager::ControllerConfigsList controllers_to_enable;
933   controllers_to_enable.emplace_back(
934       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
935       GetPrimaryBounds().origin(),
936       std::make_unique<drmModeModeInfo>(kDefaultMode));
937   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
938 
939   bool window1_has_controller = screen_manager_->GetWindow(1)->GetController();
940   bool window2_has_controller = screen_manager_->GetWindow(2)->GetController();
941   // Only one of the windows can have a controller.
942   EXPECT_TRUE(window1_has_controller ^ window2_has_controller);
943 
944   for (size_t i = 1; i < kWindowCount + 1; ++i) {
945     std::unique_ptr<ui::DrmWindow> window = screen_manager_->RemoveWindow(i);
946     window->Shutdown();
947   }
948 }
949 
TEST_F(ScreenManagerTest,ShouldDissociateWindowOnControllerRemoval)950 TEST_F(ScreenManagerTest, ShouldDissociateWindowOnControllerRemoval) {
951   InitializeDrmStateWithDefault(drm_.get());
952 
953   gfx::AcceleratedWidget window_id = 1;
954   std::unique_ptr<ui::DrmWindow> window(new ui::DrmWindow(
955       window_id, device_manager_.get(), screen_manager_.get()));
956   window->Initialize();
957   window->SetBounds(GetPrimaryBounds());
958   screen_manager_->AddWindow(window_id, std::move(window));
959 
960   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
961   ScreenManager::ControllerConfigsList controllers_to_enable;
962   controllers_to_enable.emplace_back(
963       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
964       GetPrimaryBounds().origin(),
965       std::make_unique<drmModeModeInfo>(kDefaultMode));
966   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
967 
968   EXPECT_TRUE(screen_manager_->GetWindow(window_id)->GetController());
969 
970   ScreenManager::CrtcsWithDrmList controllers_to_remove;
971   controllers_to_remove.emplace_back(kPrimaryCrtc, drm_);
972   screen_manager_->RemoveDisplayControllers(controllers_to_remove);
973 
974   EXPECT_FALSE(screen_manager_->GetWindow(window_id)->GetController());
975 
976   window = screen_manager_->RemoveWindow(1);
977   window->Shutdown();
978 }
979 
TEST_F(ScreenManagerTest,EnableControllerWhenWindowHasNoBuffer)980 TEST_F(ScreenManagerTest, EnableControllerWhenWindowHasNoBuffer) {
981   InitializeDrmStateWithDefault(drm_.get(), /*is_atomic=*/false);
982 
983   std::unique_ptr<ui::DrmWindow> window(
984       new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
985   window->Initialize();
986   window->SetBounds(GetPrimaryBounds());
987   screen_manager_->AddWindow(1, std::move(window));
988 
989   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
990   ScreenManager::ControllerConfigsList controllers_to_enable;
991   controllers_to_enable.emplace_back(
992       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
993       GetPrimaryBounds().origin(),
994       std::make_unique<drmModeModeInfo>(kDefaultMode));
995   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
996 
997   EXPECT_TRUE(screen_manager_->GetWindow(1)->GetController());
998   // There is a buffer after initial config.
999   uint32_t framebuffer = drm_->current_framebuffer();
1000   EXPECT_NE(0U, framebuffer);
1001 
1002   controllers_to_enable.clear();
1003   controllers_to_enable.emplace_back(
1004       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
1005       GetPrimaryBounds().origin(),
1006       std::make_unique<drmModeModeInfo>(kDefaultMode));
1007   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
1008 
1009   // There is a new buffer after we configured with the same mode but no
1010   // pending frames on the window.
1011   EXPECT_NE(framebuffer, drm_->current_framebuffer());
1012 
1013   window = screen_manager_->RemoveWindow(1);
1014   window->Shutdown();
1015 }
1016 
TEST_F(ScreenManagerTest,EnableControllerWhenWindowHasBuffer)1017 TEST_F(ScreenManagerTest, EnableControllerWhenWindowHasBuffer) {
1018   InitializeDrmStateWithDefault(drm_.get(), /*is_atomic=*/false);
1019 
1020   std::unique_ptr<ui::DrmWindow> window(
1021       new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
1022   window->Initialize();
1023   window->SetBounds(GetPrimaryBounds());
1024   scoped_refptr<DrmFramebuffer> buffer =
1025       CreateBuffer(DRM_FORMAT_XRGB8888, GetPrimaryBounds().size());
1026   ui::DrmOverlayPlaneList planes;
1027   planes.push_back(ui::DrmOverlayPlane(buffer, nullptr));
1028   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
1029                            base::DoNothing());
1030   screen_manager_->AddWindow(1, std::move(window));
1031 
1032   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
1033   ScreenManager::ControllerConfigsList controllers_to_enable;
1034   controllers_to_enable.emplace_back(
1035       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
1036       GetPrimaryBounds().origin(),
1037       std::make_unique<drmModeModeInfo>(kDefaultMode));
1038   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
1039 
1040   EXPECT_EQ(buffer->opaque_framebuffer_id(), drm_->current_framebuffer());
1041 
1042   window = screen_manager_->RemoveWindow(1);
1043   window->Shutdown();
1044 }
1045 
1046 // See crbug.com/868010
TEST_F(ScreenManagerTest,DISABLED_RejectBufferWithIncompatibleModifiers)1047 TEST_F(ScreenManagerTest, DISABLED_RejectBufferWithIncompatibleModifiers) {
1048   std::unique_ptr<ui::DrmWindow> window(
1049       new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
1050   window->Initialize();
1051   window->SetBounds(GetPrimaryBounds());
1052   auto buffer = CreateBufferWithModifier(
1053       DRM_FORMAT_XRGB8888, I915_FORMAT_MOD_X_TILED, GetPrimaryBounds().size());
1054   ui::DrmOverlayPlaneList planes;
1055   planes.push_back(ui::DrmOverlayPlane(buffer, nullptr));
1056   window->SchedulePageFlip(std::move(planes), base::DoNothing(),
1057                            base::DoNothing());
1058   screen_manager_->AddWindow(1, std::move(window));
1059 
1060   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
1061   ScreenManager::ControllerConfigsList controllers_to_enable;
1062   controllers_to_enable.emplace_back(
1063       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
1064       GetPrimaryBounds().origin(),
1065       std::make_unique<drmModeModeInfo>(kDefaultMode));
1066   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
1067 
1068   // ScreenManager::GetModesetBuffer (called to get a buffer to
1069   // modeset the new controller) should reject the buffer with
1070   // I915_FORMAT_MOD_X_TILED modifier we created above and the two
1071   // framebuffer IDs should be different.
1072   EXPECT_NE(buffer->framebuffer_id(), drm_->current_framebuffer());
1073   EXPECT_NE(buffer->opaque_framebuffer_id(), drm_->current_framebuffer());
1074 
1075   window = screen_manager_->RemoveWindow(1);
1076   window->Shutdown();
1077 }
1078 
TEST_F(ScreenManagerTest,ConfigureDisplayControllerShouldModesetOnce)1079 TEST_F(ScreenManagerTest, ConfigureDisplayControllerShouldModesetOnce) {
1080   InitializeDrmStateWithDefault(drm_.get(), /*is_atomic=*/false);
1081 
1082   std::unique_ptr<ui::DrmWindow> window(
1083       new ui::DrmWindow(1, device_manager_.get(), screen_manager_.get()));
1084   window->Initialize();
1085   window->SetBounds(GetPrimaryBounds());
1086   screen_manager_->AddWindow(1, std::move(window));
1087 
1088   screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
1089   ScreenManager::ControllerConfigsList controllers_to_enable;
1090   controllers_to_enable.emplace_back(
1091       kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
1092       GetPrimaryBounds().origin(),
1093       std::make_unique<drmModeModeInfo>(kDefaultMode));
1094   screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
1095 
1096   // When a window that had no controller becomes associated with a new
1097   // controller, expect the crtc to be modeset once.
1098   EXPECT_EQ(drm_->get_set_crtc_call_count(), 1);
1099 
1100   window = screen_manager_->RemoveWindow(1);
1101   window->Shutdown();
1102 }
1103 
TEST_F(ScreenManagerTest,ShouldNotHardwareMirrorDifferentDrmDevices)1104 TEST_F(ScreenManagerTest, ShouldNotHardwareMirrorDifferentDrmDevices) {
1105   auto gbm_device1 = std::make_unique<MockGbmDevice>();
1106   auto drm_device1 =
1107       base::MakeRefCounted<MockDrmDevice>(std::move(gbm_device1));
1108   InitializeDrmStateWithDefault(drm_device1.get());
1109 
1110   auto gbm_device2 = std::make_unique<MockGbmDevice>();
1111   auto drm_device2 =
1112       base::MakeRefCounted<MockDrmDevice>(std::move(gbm_device2));
1113   InitializeDrmStateWithDefault(drm_device2.get());
1114 
1115   DrmDeviceManager drm_device_manager(nullptr);
1116   ScreenManager screen_manager;
1117 
1118   constexpr uint32_t kCrtc1 = kPrimaryCrtc;
1119   constexpr uint32_t kConnector1 = kPrimaryConnector;
1120   constexpr uint32_t kCrtc2 = kSecondaryCrtc;
1121   constexpr uint32_t kConnector2 = kSecondaryConnector;
1122 
1123   drmModeModeInfo k1920x1080Screen = ConstructMode(1920, 1080);
1124   std::unique_ptr<drmModeModeInfo> primary_mode =
1125       std::make_unique<drmModeModeInfo>(k1920x1080Screen);
1126   std::unique_ptr<drmModeModeInfo> secondary_mode =
1127       std::make_unique<drmModeModeInfo>(k1920x1080Screen);
1128 
1129   // Two displays on different DRM devices must not join a mirror pair.
1130   //
1131   // However, they may have the same bounds in a transitional state.
1132   //
1133   // This scenario generates the same sequence of display configuration
1134   // events as a panther (kernel 3.8.11) chromebox with two identical
1135   // 1080p displays connected, one of them via a DisplayLink adapter.
1136 
1137   // Both displays connect at startup.
1138   {
1139     auto window1 =
1140         std::make_unique<DrmWindow>(1, &drm_device_manager, &screen_manager);
1141     window1->Initialize();
1142     screen_manager.AddWindow(1, std::move(window1));
1143     screen_manager.GetWindow(1)->SetBounds(gfx::Rect(0, 0, 1920, 1080));
1144     screen_manager.AddDisplayController(drm_device1, kCrtc1, kConnector1);
1145     screen_manager.AddDisplayController(drm_device2, kCrtc2, kConnector2);
1146 
1147     ScreenManager::ControllerConfigsList controllers_to_enable;
1148     std::unique_ptr<drmModeModeInfo> primary_mode =
1149         std::make_unique<drmModeModeInfo>(k1920x1080Screen);
1150     std::unique_ptr<drmModeModeInfo> secondary_mode =
1151         std::make_unique<drmModeModeInfo>(k1920x1080Screen);
1152     controllers_to_enable.emplace_back(kPrimaryDisplayId, drm_device1, kCrtc1,
1153                                        kConnector1, gfx::Point(0, 0),
1154                                        std::move(primary_mode));
1155     controllers_to_enable.emplace_back(kSecondaryDisplayId, drm_device2, kCrtc2,
1156                                        kConnector2, gfx::Point(0, 1140),
1157                                        std::move(secondary_mode));
1158     screen_manager.ConfigureDisplayControllers(controllers_to_enable);
1159 
1160     auto window2 =
1161         std::make_unique<DrmWindow>(2, &drm_device_manager, &screen_manager);
1162     window2->Initialize();
1163     screen_manager.AddWindow(2, std::move(window2));
1164     screen_manager.GetWindow(2)->SetBounds(gfx::Rect(0, 1140, 1920, 1080));
1165   }
1166 
1167   // Displays are stacked vertically, window per display.
1168   {
1169     HardwareDisplayController* controller1 =
1170         screen_manager.GetWindow(1)->GetController();
1171     HardwareDisplayController* controller2 =
1172         screen_manager.GetWindow(2)->GetController();
1173     EXPECT_NE(controller1, controller2);
1174     EXPECT_TRUE(controller1->HasCrtc(drm_device1, kCrtc1));
1175     EXPECT_TRUE(controller2->HasCrtc(drm_device2, kCrtc2));
1176   }
1177 
1178   // Disconnect first display. Second display moves to origin.
1179   {
1180     ScreenManager::CrtcsWithDrmList controllers_to_remove;
1181     controllers_to_remove.emplace_back(kCrtc1, drm_device1);
1182     screen_manager.RemoveDisplayControllers(controllers_to_remove);
1183 
1184     ScreenManager::ControllerConfigsList controllers_to_enable;
1185     std::unique_ptr<drmModeModeInfo> secondary_mode =
1186         std::make_unique<drmModeModeInfo>(k1920x1080Screen);
1187     controllers_to_enable.emplace_back(kSecondaryDisplayId, drm_device2, kCrtc2,
1188                                        kConnector2, gfx::Point(0, 0),
1189                                        std::move(secondary_mode));
1190     screen_manager.ConfigureDisplayControllers(controllers_to_enable);
1191 
1192     screen_manager.GetWindow(1)->SetBounds(gfx::Rect(0, 0, 1920, 1080));
1193     screen_manager.GetWindow(1)->SetBounds(gfx::Rect(0, 0, 1920, 1080));
1194     screen_manager.RemoveWindow(2)->Shutdown();
1195   }
1196 
1197   // Reconnect first display. Original configuration restored.
1198   {
1199     screen_manager.AddDisplayController(drm_device1, kCrtc1, kConnector1);
1200     ScreenManager::ControllerConfigsList controllers_to_enable;
1201     std::unique_ptr<drmModeModeInfo> primary_mode =
1202         std::make_unique<drmModeModeInfo>(k1920x1080Screen);
1203     controllers_to_enable.emplace_back(kPrimaryDisplayId, drm_device1, kCrtc1,
1204                                        kConnector1, gfx::Point(0, 0),
1205                                        std::move(primary_mode));
1206     screen_manager.ConfigureDisplayControllers(controllers_to_enable);
1207     // At this point, both displays are in the same location.
1208     {
1209       HardwareDisplayController* controller =
1210           screen_manager.GetWindow(1)->GetController();
1211       EXPECT_FALSE(controller->IsMirrored());
1212       // We don't really care which crtc it has, but it should have just
1213       EXPECT_EQ(1U, controller->crtc_controllers().size());
1214       EXPECT_TRUE(controller->HasCrtc(drm_device1, kCrtc1) ||
1215                   controller->HasCrtc(drm_device2, kCrtc2));
1216     }
1217     controllers_to_enable.clear();
1218     std::unique_ptr<drmModeModeInfo> secondary_mode =
1219         std::make_unique<drmModeModeInfo>(k1920x1080Screen);
1220     controllers_to_enable.emplace_back(kSecondaryDisplayId, drm_device2, kCrtc2,
1221                                        kConnector2, gfx::Point(0, 1140),
1222                                        std::move(secondary_mode));
1223     screen_manager.ConfigureDisplayControllers(controllers_to_enable);
1224     auto window3 =
1225         std::make_unique<DrmWindow>(3, &drm_device_manager, &screen_manager);
1226     window3->Initialize();
1227     screen_manager.AddWindow(3, std::move(window3));
1228     screen_manager.GetWindow(3)->SetBounds(gfx::Rect(0, 0, 1920, 1080));
1229     screen_manager.GetWindow(1)->SetBounds(gfx::Rect(0, 1140, 1920, 1080));
1230     screen_manager.GetWindow(1)->SetBounds(gfx::Rect(0, 0, 1920, 1080));
1231     screen_manager.GetWindow(3)->SetBounds(gfx::Rect(0, 1140, 1920, 1080));
1232   }
1233 
1234   // Everything is restored.
1235   {
1236     HardwareDisplayController* controller1 =
1237         screen_manager.GetWindow(1)->GetController();
1238     HardwareDisplayController* controller3 =
1239         screen_manager.GetWindow(3)->GetController();
1240     EXPECT_NE(controller1, controller3);
1241     EXPECT_TRUE(controller1->HasCrtc(drm_device1, kCrtc1));
1242     EXPECT_TRUE(controller3->HasCrtc(drm_device2, kCrtc2));
1243   }
1244 
1245   // Cleanup.
1246   screen_manager.RemoveWindow(1)->Shutdown();
1247   screen_manager.RemoveWindow(3)->Shutdown();
1248 }
1249 
1250 // crbug.com/888553
TEST_F(ScreenManagerTest,ShouldNotUnbindFramebufferOnJoiningMirror)1251 TEST_F(ScreenManagerTest, ShouldNotUnbindFramebufferOnJoiningMirror) {
1252   auto gbm_device = std::make_unique<MockGbmDevice>();
1253   auto drm_device = base::MakeRefCounted<MockDrmDevice>(std::move(gbm_device));
1254   InitializeDrmStateWithDefault(drm_device.get(), /*is_atomic=*/false);
1255 
1256   DrmDeviceManager drm_device_manager(nullptr);
1257   ScreenManager screen_manager;
1258 
1259   constexpr uint32_t kCrtc1 = kPrimaryCrtc;
1260   constexpr uint32_t kConnector1 = kPrimaryConnector;
1261   constexpr uint32_t kCrtc2 = kSecondaryCrtc;
1262   constexpr uint32_t kConnector2 = kSecondaryConnector;
1263 
1264   constexpr drmModeModeInfo k1080p60Screen = {
1265       /* clock= */ 148500,
1266       /* hdisplay= */ 1920,
1267       /* hsync_start= */ 2008,
1268       /* hsync_end= */ 2052,
1269       /* htotal= */ 2200,
1270       /* hskew= */ 0,
1271       /* vdisplay= */ 1080,
1272       /* vsync_start= */ 1084,
1273       /* vsync_end= */ 1089,
1274       /* vtotal= */ 1125,
1275       /* vscan= */ 0,
1276       /* vrefresh= */ 60,
1277       /* flags= */ 0xa,
1278       /* type= */ 64,
1279       /* name= */ "1920x1080",
1280   };
1281 
1282   // Both displays connect at startup.
1283   {
1284     auto window1 =
1285         std::make_unique<DrmWindow>(1, &drm_device_manager, &screen_manager);
1286     window1->Initialize();
1287     screen_manager.AddWindow(1, std::move(window1));
1288     screen_manager.GetWindow(1)->SetBounds(gfx::Rect(0, 0, 1920, 1080));
1289     screen_manager.AddDisplayController(drm_device, kCrtc1, kConnector1);
1290     screen_manager.AddDisplayController(drm_device, kCrtc2, kConnector2);
1291 
1292     ScreenManager::ControllerConfigsList controllers_to_enable;
1293     std::unique_ptr<drmModeModeInfo> primary_mode =
1294         std::make_unique<drmModeModeInfo>(k1080p60Screen);
1295     std::unique_ptr<drmModeModeInfo> secondary_mode =
1296         std::make_unique<drmModeModeInfo>(k1080p60Screen);
1297     controllers_to_enable.emplace_back(kPrimaryDisplayId, drm_device, kCrtc1,
1298                                        kConnector1, gfx::Point(0, 0),
1299                                        std::move(primary_mode));
1300     controllers_to_enable.emplace_back(kSecondaryDisplayId, drm_device, kCrtc2,
1301                                        kConnector2, gfx::Point(0, 0),
1302                                        std::move(secondary_mode));
1303     screen_manager.ConfigureDisplayControllers(controllers_to_enable);
1304   }
1305 
1306   EXPECT_NE(0u, drm_device->GetFramebufferForCrtc(kCrtc1));
1307   EXPECT_NE(0u, drm_device->GetFramebufferForCrtc(kCrtc2));
1308 
1309   // Cleanup.
1310   screen_manager.RemoveWindow(1)->Shutdown();
1311 }
1312 
1313 }  // namespace ui
1314