diff options
author | dnicoara <dnicoara@chromium.org> | 2015-02-11 14:46:51 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-11 22:47:25 +0000 |
commit | e09319a1f3bac481f20b4bf282acec9f72e755cf (patch) | |
tree | 88926fd9ff13762295c7d5cd2ea0ae726e41e79b /ui/ozone | |
parent | be70d17c270047a27a04767ea107e181aaa3b24d (diff) | |
download | chromium_src-e09319a1f3bac481f20b4bf282acec9f72e755cf.zip chromium_src-e09319a1f3bac481f20b4bf282acec9f72e755cf.tar.gz chromium_src-e09319a1f3bac481f20b4bf282acec9f72e755cf.tar.bz2 |
[Ozone-Dri] Allow NativeDisplayDelegateDri to handle multiple DRM devices
Add the ability to use multiple DRM devices. Also changes the way calls
are forwarded to ScreenManager since IDs (CRTC, Connector, ...) are not
unique across all DRM devices.
BUG=427959
Review URL: https://codereview.chromium.org/876313008
Cr-Commit-Position: refs/heads/master@{#315859}
Diffstat (limited to 'ui/ozone')
-rw-r--r-- | ui/ozone/platform/dri/dri_gpu_platform_support.cc | 1 | ||||
-rw-r--r-- | ui/ozone/platform/dri/dri_util.cc | 5 | ||||
-rw-r--r-- | ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc | 4 | ||||
-rw-r--r-- | ui/ozone/platform/dri/dri_wrapper.h | 2 | ||||
-rw-r--r-- | ui/ozone/platform/dri/hardware_display_controller.cc | 9 | ||||
-rw-r--r-- | ui/ozone/platform/dri/hardware_display_controller.h | 5 | ||||
-rw-r--r-- | ui/ozone/platform/dri/hardware_display_controller_unittest.cc | 5 | ||||
-rw-r--r-- | ui/ozone/platform/dri/native_display_delegate_dri.cc | 113 | ||||
-rw-r--r-- | ui/ozone/platform/dri/native_display_delegate_dri.h | 8 | ||||
-rw-r--r-- | ui/ozone/platform/dri/ozone_platform_dri.cc | 2 | ||||
-rw-r--r-- | ui/ozone/platform/dri/ozone_platform_gbm.cc | 2 | ||||
-rw-r--r-- | ui/ozone/platform/dri/screen_manager.cc | 47 | ||||
-rw-r--r-- | ui/ozone/platform/dri/screen_manager.h | 14 | ||||
-rw-r--r-- | ui/ozone/platform/dri/screen_manager_unittest.cc | 203 |
14 files changed, 243 insertions, 177 deletions
diff --git a/ui/ozone/platform/dri/dri_gpu_platform_support.cc b/ui/ozone/platform/dri/dri_gpu_platform_support.cc index 92f7754..010ef8c 100644 --- a/ui/ozone/platform/dri/dri_gpu_platform_support.cc +++ b/ui/ozone/platform/dri/dri_gpu_platform_support.cc @@ -180,6 +180,7 @@ DriGpuPlatformSupport::DriGpuPlatformSupport( window_manager_(window_manager), screen_manager_(screen_manager), ndd_(ndd.Pass()) { + ndd_->AddGraphicsDevice(drm_); filter_ = new DriGpuPlatformSupportMessageFilter( window_manager, base::Bind(&DriGpuPlatformSupport::SetIOTaskRunner, base::Unretained(this)), diff --git a/ui/ozone/platform/dri/dri_util.cc b/ui/ozone/platform/dri/dri_util.cc index af64e74..39c1501 100644 --- a/ui/ozone/platform/dri/dri_util.cc +++ b/ui/ozone/platform/dri/dri_util.cc @@ -152,8 +152,9 @@ void ForceInitializationOfPrimaryDisplay(const scoped_refptr<DriWrapper>& drm, screen_manager->AddDisplayController(drm, displays[0]->crtc()->crtc_id, displays[0]->connector()->connector_id); if (screen_manager->ConfigureDisplayController( - displays[0]->crtc()->crtc_id, displays[0]->connector()->connector_id, - gfx::Point(), displays[0]->connector()->modes[0])) { + drm, displays[0]->crtc()->crtc_id, + displays[0]->connector()->connector_id, gfx::Point(), + displays[0]->connector()->modes[0])) { if (dpms) drm->SetProperty(displays[0]->connector()->connector_id, dpms->prop_id, DRM_MODE_DPMS_ON); diff --git a/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc b/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc index 1264aac..32d52af 100644 --- a/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc +++ b/ui/ozone/platform/dri/dri_window_delegate_impl_unittest.cc @@ -59,8 +59,8 @@ void DriWindowDelegateImplTest::SetUp() { buffer_generator_.reset(new ui::DriBufferGenerator()); screen_manager_.reset(new ui::ScreenManager(buffer_generator_.get())); screen_manager_->AddDisplayController(dri_, kDefaultCrtc, kDefaultConnector); - screen_manager_->ConfigureDisplayController(kDefaultCrtc, kDefaultConnector, - gfx::Point(), kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kDefaultCrtc, kDefaultConnector, gfx::Point(), kDefaultMode); drm_device_manager_.reset(new ui::DrmDeviceManager(dri_)); window_delegate_manager_.reset(new ui::DriWindowDelegateManager()); diff --git a/ui/ozone/platform/dri/dri_wrapper.h b/ui/ozone/platform/dri/dri_wrapper.h index ea82ca6b..b83b7a7 100644 --- a/ui/ozone/platform/dri/dri_wrapper.h +++ b/ui/ozone/platform/dri/dri_wrapper.h @@ -160,6 +160,8 @@ class OZONE_EXPORT DriWrapper : public base::RefCountedThreadSafe<DriWrapper> { int get_fd() const { return file_.GetPlatformFile(); } + base::FilePath device_path() const { return device_path_; } + HardwareDisplayPlaneManager* plane_manager() { return plane_manager_.get(); } protected: diff --git a/ui/ozone/platform/dri/hardware_display_controller.cc b/ui/ozone/platform/dri/hardware_display_controller.cc index 5e1cb62..0bd4947 100644 --- a/ui/ozone/platform/dri/hardware_display_controller.cc +++ b/ui/ozone/platform/dri/hardware_display_controller.cc @@ -155,10 +155,11 @@ void HardwareDisplayController::AddCrtc(scoped_ptr<CrtcController> controller) { } scoped_ptr<CrtcController> HardwareDisplayController::RemoveCrtc( + const scoped_refptr<DriWrapper>& drm, uint32_t crtc) { for (ScopedVector<CrtcController>::iterator it = crtc_controllers_.begin(); it != crtc_controllers_.end(); ++it) { - if ((*it)->crtc() == crtc) { + if ((*it)->drm() == drm && (*it)->crtc() == crtc) { scoped_ptr<CrtcController> controller(*it); crtc_controllers_.weak_erase(it); // Remove entry from |owned_hardware_planes_| iff no other crtcs share it. @@ -188,9 +189,11 @@ scoped_ptr<CrtcController> HardwareDisplayController::RemoveCrtc( return nullptr; } -bool HardwareDisplayController::HasCrtc(uint32_t crtc) const { +bool HardwareDisplayController::HasCrtc(const scoped_refptr<DriWrapper>& drm, + uint32_t crtc) const { for (size_t i = 0; i < crtc_controllers_.size(); ++i) - if (crtc_controllers_[i]->crtc() == crtc) + if (crtc_controllers_[i]->drm() == drm && + crtc_controllers_[i]->crtc() == crtc) return true; return false; diff --git a/ui/ozone/platform/dri/hardware_display_controller.h b/ui/ozone/platform/dri/hardware_display_controller.h index 272964d..e2db520 100644 --- a/ui/ozone/platform/dri/hardware_display_controller.h +++ b/ui/ozone/platform/dri/hardware_display_controller.h @@ -134,8 +134,9 @@ class OZONE_EXPORT HardwareDisplayController bool MoveCursor(const gfx::Point& location); void AddCrtc(scoped_ptr<CrtcController> controller); - scoped_ptr<CrtcController> RemoveCrtc(uint32_t crtc); - bool HasCrtc(uint32_t crtc) const; + scoped_ptr<CrtcController> RemoveCrtc(const scoped_refptr<DriWrapper>& drm, + uint32_t crtc); + bool HasCrtc(const scoped_refptr<DriWrapper>& drm, uint32_t crtc) const; bool IsMirrored() const; bool IsDisabled() const; gfx::Size GetModeSize() const; diff --git a/ui/ozone/platform/dri/hardware_display_controller_unittest.cc b/ui/ozone/platform/dri/hardware_display_controller_unittest.cc index 26a471d..2d1b467 100644 --- a/ui/ozone/platform/dri/hardware_display_controller_unittest.cc +++ b/ui/ozone/platform/dri/hardware_display_controller_unittest.cc @@ -226,7 +226,8 @@ TEST_F(HardwareDisplayControllerTest, PlaneStateAfterRemoveCrtc) { ASSERT_TRUE(owned_plane != nullptr); EXPECT_EQ(kPrimaryCrtc, owned_plane->owning_crtc()); // Removing the crtc should free the plane. - scoped_ptr<ui::CrtcController> crtc = controller_->RemoveCrtc(kPrimaryCrtc); + scoped_ptr<ui::CrtcController> crtc = + controller_->RemoveCrtc(drm_, kPrimaryCrtc); EXPECT_FALSE(owned_plane->in_use()); } @@ -269,7 +270,7 @@ TEST_F(HardwareDisplayControllerTest, RemoveCrtcMidPageFlip) { base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, base::Unretained(this)))); - controller_->RemoveCrtc(kPrimaryCrtc); + controller_->RemoveCrtc(drm_, kPrimaryCrtc); EXPECT_EQ(1, page_flips_); drm_->RunCallbacks(); diff --git a/ui/ozone/platform/dri/native_display_delegate_dri.cc b/ui/ozone/platform/dri/native_display_delegate_dri.cc index 6c50f88..45acb2e 100644 --- a/ui/ozone/platform/dri/native_display_delegate_dri.cc +++ b/ui/ozone/platform/dri/native_display_delegate_dri.cc @@ -50,16 +50,22 @@ uint32_t GetContentProtectionValue(drmModePropertyRes* property, class DisplaySnapshotComparator { public: explicit DisplaySnapshotComparator(const DisplaySnapshotDri* snapshot) - : crtc_(snapshot->crtc()), connector_(snapshot->connector()) {} + : drm_(snapshot->drm()), + crtc_(snapshot->crtc()), + connector_(snapshot->connector()) {} - DisplaySnapshotComparator(uint32_t crtc, uint32_t connector) - : crtc_(crtc), connector_(connector) {} + DisplaySnapshotComparator(const scoped_refptr<DriWrapper>& drm, + uint32_t crtc, + uint32_t connector) + : drm_(drm), crtc_(crtc), connector_(connector) {} bool operator()(const DisplaySnapshotDri* other) const { - return connector_ == other->connector() && crtc_ == other->crtc(); + return drm_ == other->drm() && connector_ == other->connector() && + crtc_ == other->crtc(); } private: + scoped_refptr<DriWrapper> drm_; uint32_t crtc_; uint32_t connector_; }; @@ -67,9 +73,8 @@ class DisplaySnapshotComparator { } // namespace NativeDisplayDelegateDri::NativeDisplayDelegateDri( - const scoped_refptr<DriWrapper>& dri, ScreenManager* screen_manager) - : dri_(dri), screen_manager_(screen_manager) { + : screen_manager_(screen_manager) { } NativeDisplayDelegateDri::~NativeDisplayDelegateDri() { @@ -106,17 +111,21 @@ void NativeDisplayDelegateDri::UngrabServer() { } bool NativeDisplayDelegateDri::TakeDisplayControl() { - if (!dri_->SetMaster()) { - LOG(ERROR) << "Failed to take control of the display"; - return false; + for (const auto& drm : devices_) { + if (!drm->SetMaster()) { + LOG(ERROR) << "Failed to take control of the display"; + return false; + } } return true; } bool NativeDisplayDelegateDri::RelinquishDisplayControl() { - if (!dri_->DropMaster()) { - LOG(ERROR) << "Failed to relinquish control of the display"; - return false; + for (const auto& drm : devices_) { + if (!drm->DropMaster()) { + LOG(ERROR) << "Failed to relinquish control of the display"; + return false; + } } return true; } @@ -141,26 +150,28 @@ std::vector<DisplaySnapshot*> NativeDisplayDelegateDri::GetDisplays() { ScopedVector<DisplaySnapshotDri> old_displays(cached_displays_.Pass()); ScopedVector<const DisplayMode> old_modes(cached_modes_.Pass()); - ScopedVector<HardwareDisplayControllerInfo> displays = - GetAvailableDisplayControllerInfos(dri_->get_fd()); - for (size_t i = 0; i < displays.size(); ++i) { - DisplaySnapshotDri* display = new DisplaySnapshotDri( - dri_.get(), displays[i]->connector(), displays[i]->crtc(), i); - - // If the display exists make sure to sync up the new snapshot with the old - // one to keep the user configured details. - auto it = std::find_if( - old_displays.begin(), old_displays.end(), - DisplaySnapshotComparator(displays[i]->crtc()->crtc_id, - displays[i]->connector()->connector_id)); - // Origin is only used within the platform code to keep track of the display - // location. - if (it != old_displays.end()) - display->set_origin((*it)->origin()); - - cached_displays_.push_back(display); - cached_modes_.insert(cached_modes_.end(), display->modes().begin(), - display->modes().end()); + for (const auto& drm : devices_) { + ScopedVector<HardwareDisplayControllerInfo> displays = + GetAvailableDisplayControllerInfos(drm->get_fd()); + for (size_t i = 0; i < displays.size(); ++i) { + DisplaySnapshotDri* display = new DisplaySnapshotDri( + drm, displays[i]->connector(), displays[i]->crtc(), i); + + // If the display exists make sure to sync up the new snapshot with the + // old one to keep the user configured details. + auto it = std::find_if( + old_displays.begin(), old_displays.end(), + DisplaySnapshotComparator(drm, displays[i]->crtc()->crtc_id, + displays[i]->connector()->connector_id)); + // Origin is only used within the platform code to keep track of the + // display location. + if (it != old_displays.end()) + display->set_origin((*it)->origin()); + + cached_displays_.push_back(display); + cached_modes_.insert(cached_modes_.end(), display->modes().begin(), + display->modes().end()); + } } NotifyScreenManager(cached_displays_.get(), old_displays.get()); @@ -185,16 +196,20 @@ bool NativeDisplayDelegateDri::Configure(const DisplaySnapshot& output, const DisplaySnapshotDri& dri_output = static_cast<const DisplaySnapshotDri&>(output); - VLOG(1) << "DRM configuring: crtc=" << dri_output.crtc() + VLOG(1) << "DRM configuring: device=" + << dri_output.drm()->device_path().value() + << " crtc=" << dri_output.crtc() << " connector=" << dri_output.connector() << " origin=" << origin.ToString() << " size=" << (mode ? mode->size().ToString() : "0x0"); if (mode) { if (!screen_manager_->ConfigureDisplayController( - dri_output.crtc(), dri_output.connector(), origin, + dri_output.drm(), dri_output.crtc(), dri_output.connector(), origin, static_cast<const DisplayModeDri*>(mode)->mode_info())) { - VLOG(1) << "Failed to configure: crtc=" << dri_output.crtc() + VLOG(1) << "Failed to configure: device=" + << dri_output.drm()->device_path().value() + << " crtc=" << dri_output.crtc() << " connector=" << dri_output.connector(); return false; } @@ -205,8 +220,11 @@ bool NativeDisplayDelegateDri::Configure(const DisplaySnapshot& output, DRM_MODE_DPMS_OFF); } - if (!screen_manager_->DisableDisplayController(dri_output.crtc())) { - VLOG(1) << "Failed to disable crtc=" << dri_output.crtc(); + if (!screen_manager_->DisableDisplayController(dri_output.drm(), + dri_output.crtc())) { + VLOG(1) << "Failed to disable device=" + << dri_output.drm()->device_path().value() + << " crtc=" << dri_output.crtc(); return false; } } @@ -314,8 +332,10 @@ void NativeDisplayDelegateDri::NotifyScreenManager( std::find_if(new_displays.begin(), new_displays.end(), DisplaySnapshotComparator(old_displays[i])); - if (it == new_displays.end()) - screen_manager_->RemoveDisplayController(old_displays[i]->crtc()); + if (it == new_displays.end()) { + screen_manager_->RemoveDisplayController(old_displays[i]->drm(), + old_displays[i]->crtc()); + } } for (size_t i = 0; i < new_displays.size(); ++i) { @@ -323,11 +343,24 @@ void NativeDisplayDelegateDri::NotifyScreenManager( std::find_if(old_displays.begin(), old_displays.end(), DisplaySnapshotComparator(new_displays[i])); - if (it == old_displays.end()) + if (it == old_displays.end()) { screen_manager_->AddDisplayController(new_displays[i]->drm(), new_displays[i]->crtc(), new_displays[i]->connector()); + } } } +void NativeDisplayDelegateDri::AddGraphicsDevice( + const scoped_refptr<DriWrapper>& drm) { + devices_.push_back(drm); +} + +void NativeDisplayDelegateDri::RemoveGraphicsDevice( + const scoped_refptr<DriWrapper>& drm) { + auto it = std::find(devices_.begin(), devices_.end(), drm); + if (it != devices_.end()) + devices_.erase(it); +} + } // namespace ui diff --git a/ui/ozone/platform/dri/native_display_delegate_dri.h b/ui/ozone/platform/dri/native_display_delegate_dri.h index b45ffe9..6bd3faf 100644 --- a/ui/ozone/platform/dri/native_display_delegate_dri.h +++ b/ui/ozone/platform/dri/native_display_delegate_dri.h @@ -19,8 +19,7 @@ class ScreenManager; class NativeDisplayDelegateDri : public NativeDisplayDelegate { public: - NativeDisplayDelegateDri(const scoped_refptr<DriWrapper>& dri, - ScreenManager* screen_manager); + NativeDisplayDelegateDri(ScreenManager* screen_manager); ~NativeDisplayDelegateDri() override; DisplaySnapshot* FindDisplaySnapshot(int64_t id); @@ -33,6 +32,9 @@ class NativeDisplayDelegateDri : public NativeDisplayDelegate { const DisplayMode* mode, const gfx::Point& origin); + void AddGraphicsDevice(const scoped_refptr<DriWrapper>& dri); + void RemoveGraphicsDevice(const scoped_refptr<DriWrapper>& dri); + // NativeDisplayDelegate overrides: void Initialize() override; void GrabServer() override; @@ -66,8 +68,8 @@ class NativeDisplayDelegateDri : public NativeDisplayDelegate { const std::vector<DisplaySnapshotDri*>& new_displays, const std::vector<DisplaySnapshotDri*>& old_displays) const; - scoped_refptr<DriWrapper> dri_; ScreenManager* screen_manager_; // Not owned. + std::vector<scoped_refptr<DriWrapper>> devices_; // Modes can be shared between different displays, so we need to keep track // of them independently for cleanup. ScopedVector<const DisplayMode> cached_modes_; diff --git a/ui/ozone/platform/dri/ozone_platform_dri.cc b/ui/ozone/platform/dri/ozone_platform_dri.cc index ee6f7b0..a78f498 100644 --- a/ui/ozone/platform/dri/ozone_platform_dri.cc +++ b/ui/ozone/platform/dri/ozone_platform_dri.cc @@ -100,7 +100,7 @@ class OzonePlatformDri : public OzonePlatform { surface_factory_ozone_.reset( new DriSurfaceFactory(&window_delegate_manager_)); scoped_ptr<NativeDisplayDelegateDri> ndd( - new NativeDisplayDelegateDri(dri_.get(), screen_manager_.get())); + new NativeDisplayDelegateDri(screen_manager_.get())); ndd->Initialize(); gpu_platform_support_.reset(new DriGpuPlatformSupport( dri_, drm_device_manager_.get(), &window_delegate_manager_, diff --git a/ui/ozone/platform/dri/ozone_platform_gbm.cc b/ui/ozone/platform/dri/ozone_platform_gbm.cc index 37d59a0..03c2b22 100644 --- a/ui/ozone/platform/dri/ozone_platform_gbm.cc +++ b/ui/ozone/platform/dri/ozone_platform_gbm.cc @@ -171,7 +171,7 @@ class OzonePlatformGbm : public OzonePlatform { surface_factory_ozone_->InitializeGpu(gbm_, drm_device_manager_.get(), window_delegate_manager_.get()); scoped_ptr<NativeDisplayDelegateDri> ndd( - new NativeDisplayDelegateDri(gbm_, screen_manager_.get())); + new NativeDisplayDelegateDri(screen_manager_.get())); ndd->Initialize(); gpu_platform_support_.reset(new DriGpuPlatformSupport( gbm_, drm_device_manager_.get(), window_delegate_manager_.get(), diff --git a/ui/ozone/platform/dri/screen_manager.cc b/ui/ozone/platform/dri/screen_manager.cc index 7add8d7..2a1eaec 100644 --- a/ui/ozone/platform/dri/screen_manager.cc +++ b/ui/ozone/platform/dri/screen_manager.cc @@ -69,7 +69,7 @@ ScreenManager::~ScreenManager() { void ScreenManager::AddDisplayController(const scoped_refptr<DriWrapper>& dri, uint32_t crtc, uint32_t connector) { - HardwareDisplayControllers::iterator it = FindDisplayController(crtc); + HardwareDisplayControllers::iterator it = FindDisplayController(dri, crtc); // TODO(dnicoara): Turn this into a DCHECK when async display configuration is // properly supported. (When there can't be a race between forcing initial // display configuration in ScreenManager and NativeDisplayDelegate creating @@ -83,11 +83,13 @@ void ScreenManager::AddDisplayController(const scoped_refptr<DriWrapper>& dri, scoped_ptr<CrtcController>(new CrtcController(dri, crtc, connector)))); } -void ScreenManager::RemoveDisplayController(uint32_t crtc) { - HardwareDisplayControllers::iterator it = FindDisplayController(crtc); +void ScreenManager::RemoveDisplayController( + const scoped_refptr<DriWrapper>& drm, + uint32_t crtc) { + HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); if (it != controllers_.end()) { bool is_mirrored = (*it)->IsMirrored(); - (*it)->RemoveCrtc(crtc); + (*it)->RemoveCrtc(drm, crtc); if (!is_mirrored) { FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, OnDisplayRemoved(*it)); @@ -96,13 +98,15 @@ void ScreenManager::RemoveDisplayController(uint32_t crtc) { } } -bool ScreenManager::ConfigureDisplayController(uint32_t crtc, - uint32_t connector, - const gfx::Point& origin, - const drmModeModeInfo& mode) { +bool ScreenManager::ConfigureDisplayController( + const scoped_refptr<DriWrapper>& drm, + uint32_t crtc, + uint32_t connector, + const gfx::Point& origin, + const drmModeModeInfo& mode) { gfx::Rect modeset_bounds(origin.x(), origin.y(), mode.hdisplay, mode.vdisplay); - HardwareDisplayControllers::iterator it = FindDisplayController(crtc); + HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc << ") doesn't exist."; @@ -117,7 +121,7 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc, // If there is an active controller at the same location then start mirror // mode. if (mirror != controllers_.end()) - return HandleMirrorMode(it, mirror, crtc, connector); + return HandleMirrorMode(it, mirror, drm, crtc, connector); } // Just re-enable the controller to re-use the current state. @@ -133,7 +137,8 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc, // mirror mode, subsequent calls configuring the other controllers will // restore mirror mode. if (controller->IsMirrored()) { - controller = new HardwareDisplayController(controller->RemoveCrtc(crtc)); + controller = + new HardwareDisplayController(controller->RemoveCrtc(drm, crtc)); controllers_.push_back(controller); it = controllers_.end() - 1; } @@ -142,17 +147,19 @@ bool ScreenManager::ConfigureDisplayController(uint32_t crtc, FindActiveDisplayControllerByLocation(modeset_bounds); // Handle mirror mode. if (mirror != controllers_.end() && it != mirror) - return HandleMirrorMode(it, mirror, crtc, connector); + return HandleMirrorMode(it, mirror, drm, crtc, connector); return ModesetDisplayController(controller, origin, mode); } -bool ScreenManager::DisableDisplayController(uint32_t crtc) { - HardwareDisplayControllers::iterator it = FindDisplayController(crtc); +bool ScreenManager::DisableDisplayController( + const scoped_refptr<DriWrapper>& drm, + uint32_t crtc) { + HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); if (it != controllers_.end()) { if ((*it)->IsMirrored()) { HardwareDisplayController* controller = - new HardwareDisplayController((*it)->RemoveCrtc(crtc)); + new HardwareDisplayController((*it)->RemoveCrtc(drm, crtc)); controllers_.push_back(controller); } @@ -183,11 +190,12 @@ void ScreenManager::RemoveObserver(DisplayChangeObserver* observer) { } ScreenManager::HardwareDisplayControllers::iterator -ScreenManager::FindDisplayController(uint32_t crtc) { +ScreenManager::FindDisplayController(const scoped_refptr<DriWrapper>& drm, + uint32_t crtc) { for (HardwareDisplayControllers::iterator it = controllers_.begin(); it != controllers_.end(); ++it) { - if ((*it)->HasCrtc(crtc)) + if ((*it)->HasCrtc(drm, crtc)) return it; } @@ -239,9 +247,10 @@ bool ScreenManager::ModesetDisplayController( bool ScreenManager::HandleMirrorMode( HardwareDisplayControllers::iterator original, HardwareDisplayControllers::iterator mirror, + const scoped_refptr<DriWrapper>& drm, uint32_t crtc, uint32_t connector) { - (*mirror)->AddCrtc((*original)->RemoveCrtc(crtc)); + (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc)); if ((*mirror)->Enable()) { FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, OnDisplayRemoved(*original)); @@ -256,7 +265,7 @@ bool ScreenManager::HandleMirrorMode( // When things go wrong revert back to the previous configuration since // it is expected that the configuration would not have changed if // things fail. - (*original)->AddCrtc((*mirror)->RemoveCrtc(crtc)); + (*original)->AddCrtc((*mirror)->RemoveCrtc(drm, crtc)); (*original)->Enable(); return false; } diff --git a/ui/ozone/platform/dri/screen_manager.h b/ui/ozone/platform/dri/screen_manager.h index 862a5d0..5eaaa46 100644 --- a/ui/ozone/platform/dri/screen_manager.h +++ b/ui/ozone/platform/dri/screen_manager.h @@ -39,18 +39,21 @@ class OZONE_EXPORT ScreenManager { // Remove a display controller from the list of active controllers. The // controller is removed since it was disconnected. - void RemoveDisplayController(uint32_t crtc); + void RemoveDisplayController(const scoped_refptr<DriWrapper>& dri, + uint32_t crtc); // Configure a display controller. The display controller is identified by // (|crtc|, |connector|) and the controller is modeset using |mode|. - bool ConfigureDisplayController(uint32_t crtc, + bool ConfigureDisplayController(const scoped_refptr<DriWrapper>& dri, + uint32_t crtc, uint32_t connector, const gfx::Point& origin, const drmModeModeInfo& mode); // Disable the display controller identified by |crtc|. Note, the controller // may still be connected, so this does not remove the controller. - bool DisableDisplayController(uint32_t crtc); + bool DisableDisplayController(const scoped_refptr<DriWrapper>& dri, + uint32_t crtc); // Returns a reference to the display controller configured to display within // |bounds|. If the caller caches the controller it must also register as an @@ -65,7 +68,9 @@ class OZONE_EXPORT ScreenManager { // Returns an iterator into |controllers_| for the controller identified by // (|crtc|, |connector|). - HardwareDisplayControllers::iterator FindDisplayController(uint32_t crtc); + HardwareDisplayControllers::iterator FindDisplayController( + const scoped_refptr<DriWrapper>& drm, + uint32_t crtc); // Returns an iterator into |controllers_| for the controller located at // |origin|. @@ -82,6 +87,7 @@ class OZONE_EXPORT ScreenManager { // controller is currently present. bool HandleMirrorMode(HardwareDisplayControllers::iterator original, HardwareDisplayControllers::iterator mirror, + const scoped_refptr<DriWrapper>& drm, uint32_t crtc, uint32_t connector); diff --git a/ui/ozone/platform/dri/screen_manager_unittest.cc b/ui/ozone/platform/dri/screen_manager_unittest.cc index 8e9fbd4..1501b71 100644 --- a/ui/ozone/platform/dri/screen_manager_unittest.cc +++ b/ui/ozone/platform/dri/screen_manager_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "testing/gtest/include/gtest/gtest.h" +#include "ui/ozone/platform/dri/crtc_controller.h" #include "ui/ozone/platform/dri/dri_buffer.h" #include "ui/ozone/platform/dri/hardware_display_controller.h" #include "ui/ozone/platform/dri/screen_manager.h" @@ -91,23 +92,21 @@ TEST_F(ScreenManagerTest, CheckWithNoControllers) { TEST_F(ScreenManagerTest, CheckWithValidController) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); ui::HardwareDisplayController* controller = screen_manager_->GetDisplayController(GetPrimaryBounds()); EXPECT_TRUE(controller); - EXPECT_TRUE(controller->HasCrtc(kPrimaryCrtc)); + EXPECT_TRUE(controller->HasCrtc(dri_, kPrimaryCrtc)); } TEST_F(ScreenManagerTest, CheckWithInvalidBounds) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); @@ -115,14 +114,13 @@ TEST_F(ScreenManagerTest, CheckWithInvalidBounds) { TEST_F(ScreenManagerTest, CheckForSecondValidController) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, kSecondaryConnector); screen_manager_->ConfigureDisplayController( - kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), + dri_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); @@ -131,15 +129,14 @@ TEST_F(ScreenManagerTest, CheckForSecondValidController) { TEST_F(ScreenManagerTest, CheckControllerAfterItIsRemoved) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); EXPECT_EQ(1, observer_.num_displays_changed()); EXPECT_EQ(0, observer_.num_displays_removed()); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); - screen_manager_->RemoveDisplayController(kPrimaryCrtc); + screen_manager_->RemoveDisplayController(dri_, kPrimaryCrtc); EXPECT_EQ(1, observer_.num_displays_changed()); EXPECT_EQ(1, observer_.num_displays_removed()); EXPECT_FALSE(screen_manager_->GetDisplayController(GetPrimaryBounds())); @@ -147,16 +144,14 @@ TEST_F(ScreenManagerTest, CheckControllerAfterItIsRemoved) { TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); uint32_t framebuffer = dri_->current_framebuffer(); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); // Should reuse existing framebuffer. EXPECT_EQ(framebuffer, dri_->current_framebuffer()); @@ -170,14 +165,14 @@ TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) { TEST_F(ScreenManagerTest, CheckChangingMode) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); drmModeModeInfo new_mode = kDefaultMode; new_mode.vdisplay = 10; screen_manager_->ConfigureDisplayController( - kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), new_mode); + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + new_mode); EXPECT_EQ(2, observer_.num_displays_changed()); EXPECT_EQ(0, observer_.num_displays_removed()); @@ -193,16 +188,14 @@ TEST_F(ScreenManagerTest, CheckChangingMode) { TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, kSecondaryConnector); - screen_manager_->ConfigureDisplayController(kSecondaryCrtc, - kSecondaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); EXPECT_EQ(2, observer_.num_displays_changed()); EXPECT_EQ(1, observer_.num_displays_removed()); @@ -212,65 +205,55 @@ TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) { TEST_F(ScreenManagerTest, CheckMirrorModeTransitions) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, kSecondaryConnector); - screen_manager_->ConfigureDisplayController(kSecondaryCrtc, - kSecondaryConnector, - GetSecondaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), + kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds())); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); - screen_manager_->ConfigureDisplayController(kSecondaryCrtc, - kSecondaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetSecondaryBounds().origin(), - kDefaultMode); - screen_manager_->ConfigureDisplayController(kSecondaryCrtc, - kSecondaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(), + kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_TRUE(screen_manager_->GetDisplayController(GetSecondaryBounds())); } TEST_F(ScreenManagerTest, MonitorGoneInMirrorMode) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, kSecondaryConnector); - screen_manager_->ConfigureDisplayController(kSecondaryCrtc, - kSecondaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); EXPECT_EQ(2, observer_.num_displays_changed()); EXPECT_EQ(1, observer_.num_displays_removed()); - screen_manager_->RemoveDisplayController(kSecondaryCrtc); - EXPECT_TRUE( - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, - kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode)); + screen_manager_->RemoveDisplayController(dri_, kSecondaryCrtc); + EXPECT_TRUE(screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode)); EXPECT_EQ(3, observer_.num_displays_changed()); EXPECT_EQ(1, observer_.num_displays_removed()); @@ -284,18 +267,18 @@ TEST_F(ScreenManagerTest, DoNotEnterMirrorModeUnlessSameBounds) { kSecondaryConnector); // Configure displays in extended mode. - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); screen_manager_->ConfigureDisplayController( - kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kSecondaryCrtc, kSecondaryConnector, GetSecondaryBounds().origin(), kDefaultMode); drmModeModeInfo new_mode = kDefaultMode; new_mode.vdisplay = 10; // Shouldn't enter mirror mode unless the display bounds are the same. screen_manager_->ConfigureDisplayController( - kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), new_mode); EXPECT_FALSE( @@ -304,17 +287,17 @@ TEST_F(ScreenManagerTest, DoNotEnterMirrorModeUnlessSameBounds) { TEST_F(ScreenManagerTest, ReuseFramebufferIfDisabledThenReEnabled) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); uint32_t framebuffer = dri_->current_framebuffer(); - screen_manager_->DisableDisplayController(kPrimaryCrtc); + screen_manager_->DisableDisplayController(dri_, kPrimaryCrtc); EXPECT_EQ(0u, dri_->current_framebuffer()); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); // Should reuse existing framebuffer. EXPECT_EQ(framebuffer, dri_->current_framebuffer()); @@ -322,15 +305,15 @@ TEST_F(ScreenManagerTest, ReuseFramebufferIfDisabledThenReEnabled) { TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) { screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); - screen_manager_->DisableDisplayController(kPrimaryCrtc); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->DisableDisplayController(dri_, kPrimaryCrtc); screen_manager_->AddDisplayController(dri_, kSecondaryCrtc, kSecondaryConnector); screen_manager_->ConfigureDisplayController( - kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), + dri_, kSecondaryCrtc, kSecondaryConnector, GetPrimaryBounds().origin(), kDefaultMode); ui::HardwareDisplayController* controller = @@ -338,9 +321,33 @@ TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) { EXPECT_TRUE(controller); EXPECT_FALSE(controller->IsMirrored()); - screen_manager_->ConfigureDisplayController(kPrimaryCrtc, kPrimaryConnector, - GetPrimaryBounds().origin(), - kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); EXPECT_TRUE(controller); EXPECT_TRUE(controller->IsMirrored()); } + +TEST_F(ScreenManagerTest, + CheckProperConfigurationWithDifferentDeviceAndSameCrtc) { + scoped_refptr<ui::MockDriWrapper> dri2 = new ui::MockDriWrapper(); + + screen_manager_->AddDisplayController(dri_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->AddDisplayController(dri2, kPrimaryCrtc, kPrimaryConnector); + + screen_manager_->ConfigureDisplayController( + dri_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); + screen_manager_->ConfigureDisplayController( + dri2, kPrimaryCrtc, kPrimaryConnector, GetSecondaryBounds().origin(), + kDefaultMode); + + ui::HardwareDisplayController* controller1 = + screen_manager_->GetDisplayController(GetPrimaryBounds()); + ui::HardwareDisplayController* controller2 = + screen_manager_->GetDisplayController(GetSecondaryBounds()); + + EXPECT_NE(controller1, controller2); + EXPECT_EQ(dri_, controller1->crtc_controllers()[0]->drm()); + EXPECT_EQ(dri2, controller2->crtc_controllers()[0]->drm()); +} |