Commit ad53a6ac authored by Mark Yacoub's avatar Mark Yacoub Committed by Commit Bot

Ozone: Configure Display Controllers of the same DRM only

Split the displays passed to the ScreenManager so that the list of
configs all share the same DRM.
This ensures that all parallel operations are done on the same DRM (i.e.
Atomically committing all display props on the same commit, which
requires the same fd).

BUG=1082882
TEST=no changes in enabling or disabling displays.

Change-Id: I2f38449c2114f71672f409b50808a92d72f758db
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2405414Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Commit-Queue: Mark Yacoub <markyacoub@google.com>
Cr-Commit-Position: refs/heads/master@{#808901}
parent 998b3b74
......@@ -115,6 +115,19 @@ ScreenManager::ControllerConfigParams::ControllerConfigParams(
origin(origin),
mode(std::move(pmode)) {}
ScreenManager::ControllerConfigParams::ControllerConfigParams(
const ControllerConfigParams& other)
: display_id(other.display_id),
drm(other.drm),
crtc(other.crtc),
connector(other.connector),
origin(other.origin) {
if (other.mode) {
drmModeModeInfo mode_obj = *other.mode.get();
mode = std::make_unique<drmModeModeInfo>(mode_obj);
}
}
ScreenManager::ControllerConfigParams::ControllerConfigParams(
ControllerConfigParams&& other)
: display_id(other.display_id),
......@@ -163,19 +176,38 @@ void ScreenManager::RemoveDisplayController(const scoped_refptr<DrmDevice>& drm,
base::flat_map<int64_t, bool> ScreenManager::ConfigureDisplayControllers(
const std::vector<ScreenManager::ControllerConfigParams>&
controllers_params) {
// Split them to different lists unique to each DRM Device.
base::flat_map<scoped_refptr<DrmDevice>,
std::vector<ScreenManager::ControllerConfigParams>>
displays_for_drms;
for (auto& params : controllers_params) {
auto it = displays_for_drms.find(params.drm);
if (it == displays_for_drms.end()) {
displays_for_drms.insert(std::make_pair(
params.drm, std::vector<ScreenManager::ControllerConfigParams>()));
}
displays_for_drms[params.drm].emplace_back(params);
}
base::flat_map<int64_t, bool> statuses;
bool has_everything_succeeded = true;
for (auto& params : controllers_params) {
bool status =
params.mode
? EnableDisplayController(params.drm, params.crtc, params.connector,
params.origin, *params.mode)
: DisableDisplayController(params.drm, params.crtc);
statuses.insert(std::make_pair(params.display_id, status));
has_everything_succeeded &= status;
// Perform display configurations together for the same DRM only.
for (const auto& configs_on_drm : displays_for_drms) {
for (auto& params : configs_on_drm.second) {
DCHECK_EQ(configs_on_drm.first, params.drm);
bool status = params.mode
? EnableDisplayController(params.drm, params.crtc,
params.connector,
params.origin, *params.mode)
: DisableDisplayController(params.drm, params.crtc);
statuses.insert(std::make_pair(params.display_id, status));
has_everything_succeeded &= status;
}
}
if (has_everything_succeeded)
UpdateControllerToWindowMapping();
......
......@@ -38,6 +38,7 @@ class ScreenManager {
uint32_t connector,
gfx::Point origin,
std::unique_ptr<drmModeModeInfo> pmode);
ControllerConfigParams(const ControllerConfigParams& other);
ControllerConfigParams(ControllerConfigParams&& other);
~ControllerConfigParams();
......@@ -66,7 +67,7 @@ class ScreenManager {
// Enables/Disables the display controller based on if a mode exists.
base::flat_map<int64_t, bool> ConfigureDisplayControllers(
const std::vector<ScreenManager::ControllerConfigParams>&
controllersParams);
controllers_params);
// Returns a reference to the display controller configured to display within
// |bounds|. If the caller caches the controller it must also register as an
......
......@@ -627,6 +627,38 @@ TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) {
EXPECT_TRUE(controller->IsMirrored());
}
TEST_F(ScreenManagerTest, ConfigureOnDifferentDrmDevices) {
auto gbm_device = std::make_unique<ui::MockGbmDevice>();
scoped_refptr<ui::MockDrmDevice> drm2 =
new ui::MockDrmDevice(std::move(gbm_device));
screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
screen_manager_->AddDisplayController(drm2, kSecondaryCrtc,
kSecondaryConnector);
screen_manager_->AddDisplayController(drm2, kSecondaryCrtc + 1,
kSecondaryConnector + 1);
std::vector<ScreenManager::ControllerConfigParams> controllers_to_enable;
controllers_to_enable.emplace_back(
kPrimaryDisplayId, drm_, kPrimaryCrtc, kPrimaryConnector,
GetPrimaryBounds().origin(),
std::make_unique<drmModeModeInfo>(kDefaultMode));
drmModeModeInfo secondary_mode = kDefaultMode;
controllers_to_enable.emplace_back(
kSecondaryDisplayId, drm2, kSecondaryCrtc, kSecondaryConnector,
GetSecondaryBounds().origin(),
std::make_unique<drmModeModeInfo>(secondary_mode));
drmModeModeInfo secondary_mode2 = kDefaultMode;
controllers_to_enable.emplace_back(
kSecondaryDisplayId + 1, drm2, kSecondaryCrtc + 1,
kSecondaryConnector + 1, GetSecondaryBounds().origin(),
std::make_unique<drmModeModeInfo>(secondary_mode2));
screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
EXPECT_EQ(drm_->get_set_crtc_call_count(), 1);
EXPECT_EQ(drm2->get_set_crtc_call_count(), 2);
}
TEST_F(ScreenManagerTest,
CheckProperConfigurationWithDifferentDeviceAndSameCrtc) {
auto gbm_device = std::make_unique<ui::MockGbmDevice>();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment