Commit 6e498cf4 authored by Mark Yacoub's avatar Mark Yacoub Committed by Commit Bot

Ozone: Pass all displays to be enabled in a vector to Screen Manager

Combine all displays requested to be enabled into 1 vector to the Screen Manager.
When atomic modeset is enabled, this will allow the screen manager to maintain their combined state and modeset them together.

BUG=1082882
TEST=no changes enabling, ozone_unittests.

Change-Id: Ib8bf31b13f6877c6523aada5c56e5a37f2b64fe7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2316155
Commit-Queue: Mark Yacoub <markyacoub@google.com>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800893}
parent 4eedfb7f
......@@ -73,10 +73,6 @@ std::string GetEnumNameForProperty(drmModeObjectProperties* property_values,
return std::string();
}
gfx::Size GetDrmModeSize(const drmModeModeInfo& mode) {
return gfx::Size(mode.hdisplay, mode.vdisplay);
}
std::vector<drmModeModeInfo> GetDrmModeVector(drmModeConnector* connector) {
std::vector<drmModeModeInfo> modes;
for (int i = 0; i < connector->count_modes; ++i)
......@@ -99,11 +95,8 @@ void FillPowerFunctionValues(std::vector<display::GammaRampRGBEntry>* table,
} // namespace
DrmDisplay::DrmDisplay(ScreenManager* screen_manager,
const scoped_refptr<DrmDevice>& drm)
: screen_manager_(screen_manager),
drm_(drm),
current_color_space_(gfx::ColorSpace::CreateSRGB()) {}
DrmDisplay::DrmDisplay(const scoped_refptr<DrmDevice>& drm)
: drm_(drm), current_color_space_(gfx::ColorSpace::CreateSRGB()) {}
DrmDisplay::~DrmDisplay() = default;
......@@ -140,33 +133,6 @@ std::unique_ptr<display::DisplaySnapshot> DrmDisplay::Update(
return params;
}
bool DrmDisplay::Configure(const drmModeModeInfo* mode,
const gfx::Point& origin) {
VLOG(1) << "DRM configuring: device=" << drm_->device_path().value()
<< " crtc=" << crtc_ << " connector=" << connector_->connector_id
<< " origin=" << origin.ToString()
<< " size=" << (mode ? GetDrmModeSize(*mode).ToString() : "0x0")
<< " refresh_rate=" << (mode ? mode->vrefresh : 0) << "Hz";
if (mode) {
if (!screen_manager_->ConfigureDisplayController(
drm_, crtc_, connector_->connector_id, origin, *mode)) {
VLOG(1) << "Failed to configure: device=" << drm_->device_path().value()
<< " crtc=" << crtc_ << " connector=" << connector_->connector_id;
return false;
}
} else {
if (!screen_manager_->DisableDisplayController(drm_, crtc_)) {
VLOG(1) << "Failed to disable device=" << drm_->device_path().value()
<< " crtc=" << crtc_;
return false;
}
}
origin_ = origin;
return true;
}
bool DrmDisplay::GetHDCPState(display::HDCPState* state) {
if (!connector_)
return false;
......
......@@ -22,17 +22,15 @@ typedef struct _drmModeModeInfo drmModeModeInfo;
namespace display {
class DisplaySnapshot;
struct GammaRampRGBEntry;
}
} // namespace display
namespace ui {
class DrmDevice;
class HardwareDisplayControllerInfo;
class ScreenManager;
class DrmDisplay {
public:
DrmDisplay(ScreenManager* screen_manager,
const scoped_refptr<DrmDevice>& drm);
explicit DrmDisplay(const scoped_refptr<DrmDevice>& drm);
~DrmDisplay();
int64_t display_id() const { return display_id_; }
......@@ -45,7 +43,7 @@ class DrmDisplay {
HardwareDisplayControllerInfo* info,
size_t device_index);
bool Configure(const drmModeModeInfo* mode, const gfx::Point& origin);
void SetOrigin(const gfx::Point origin) { origin_ = origin; }
bool GetHDCPState(display::HDCPState* state);
bool SetHDCPState(display::HDCPState state);
void SetColorMatrix(const std::vector<float>& color_matrix);
......@@ -63,8 +61,6 @@ class DrmDisplay {
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
ScreenManager* screen_manager_; // Not owned.
int64_t display_id_ = -1;
const scoped_refptr<DrmDevice> drm_;
uint32_t crtc_ = 0;
......
......@@ -14,7 +14,6 @@
#include "ui/ozone/platform/drm/gpu/hardware_display_plane.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h"
#include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
#include "ui/ozone/platform/drm/gpu/screen_manager.h"
using ::testing::_;
using ::testing::SizeIs;
......@@ -117,7 +116,7 @@ class DrmDisplayTest : public testing::Test {
DrmDisplayTest()
: mock_drm_device_(base::MakeRefCounted<MockDrmDevice>(
std::make_unique<MockGbmDevice>())),
drm_display_(&screen_manager_, mock_drm_device_) {}
drm_display_(mock_drm_device_) {}
MockHardwareDisplayPlaneManager* AddMockHardwareDisplayPlaneManager() {
auto mock_hardware_display_plane_manager =
......@@ -132,7 +131,6 @@ class DrmDisplayTest : public testing::Test {
base::test::TaskEnvironment env_;
scoped_refptr<DrmDevice> mock_drm_device_;
ScreenManager screen_manager_;
DrmDisplay drm_display_;
};
......
......@@ -65,6 +65,33 @@ bool FindMatchingMode(const std::vector<drmModeModeInfo> modes,
return false;
}
bool FindModeForDisplay(
drmModeModeInfo* mode_ptr,
const display::DisplayMode& display_mode,
const std::vector<drmModeModeInfo>& modes,
const std::vector<std::unique_ptr<DrmDisplay>>& all_displays) {
bool mode_found = FindMatchingMode(modes, display_mode, mode_ptr);
if (!mode_found) {
// If the display doesn't have the mode natively, then lookup the mode
// from other displays and try using it on the current display (some
// displays support panel fitting and they can use different modes even
// if the mode isn't explicitly declared).
for (const auto& other_display : all_displays) {
mode_found =
FindMatchingMode(other_display->modes(), display_mode, mode_ptr);
if (mode_found)
break;
}
if (!mode_found) {
LOG(ERROR) << "Failed to find mode: size="
<< display_mode.size().ToString()
<< " is_interlaced=" << display_mode.is_interlaced()
<< " refresh_rate=" << display_mode.refresh_rate();
}
}
return mode_found;
}
} // namespace
DrmGpuDisplayManager::DrmGpuDisplayManager(ScreenManager* screen_manager,
......@@ -100,7 +127,7 @@ MovableDisplaySnapshots DrmGpuDisplayManager::GetDisplays() {
displays_.push_back(std::move(*it));
old_displays.erase(it);
} else {
displays_.push_back(std::make_unique<DrmDisplay>(screen_manager_, drm));
displays_.push_back(std::make_unique<DrmDisplay>(drm));
}
auto display_snapshot =
......@@ -139,55 +166,80 @@ void DrmGpuDisplayManager::RelinquishDisplayControl() {
drm->DropMaster();
}
bool DrmGpuDisplayManager::ConfigureDisplay(
int64_t display_id,
const display::DisplayMode& display_mode,
const gfx::Point& origin) {
DrmDisplay* display = FindDisplay(display_id);
if (!display) {
LOG(ERROR) << "There is no display with ID " << display_id;
return false;
}
base::flat_map<int64_t, bool> DrmGpuDisplayManager::ConfigureDisplays(
const std::vector<display::DisplayConfigurationParams>& config_requests) {
base::flat_map<int64_t, bool> statuses;
std::vector<ScreenManager::ControllerConfigParams> controllers_to_configure;
for (const auto& config : config_requests) {
int64_t display_id = config.id;
DrmDisplay* display = FindDisplay(display_id);
if (!display) {
LOG(ERROR) << "There is no display with ID " << display_id;
statuses.insert(std::make_pair(display_id, false));
continue;
}
drmModeModeInfo mode;
bool mode_found = FindMatchingMode(display->modes(), display_mode, &mode);
if (!mode_found) {
// If the display doesn't have the mode natively, then lookup the mode from
// other displays and try using it on the current display (some displays
// support panel fitting and they can use different modes even if the mode
// isn't explicitly declared).
for (const auto& other_display : displays_) {
mode_found =
FindMatchingMode(other_display->modes(), display_mode, &mode);
if (mode_found)
break;
std::unique_ptr<drmModeModeInfo> mode_ptr =
config.mode ? std::make_unique<drmModeModeInfo>() : nullptr;
if (config.mode) {
if (!FindModeForDisplay(mode_ptr.get(), *config.mode.value(),
display->modes(), displays_)) {
statuses.insert(std::make_pair(display_id, false));
continue;
}
}
}
if (!mode_found) {
LOG(ERROR) << "Failed to find mode: size=" << display_mode.size().ToString()
<< " is_interlaced=" << display_mode.is_interlaced()
<< " refresh_rate=" << display_mode.refresh_rate();
return false;
scoped_refptr<DrmDevice> drm = display->drm();
VLOG(1) << "DRM configuring: device=" << drm->device_path().value()
<< " crtc=" << display->crtc()
<< " connector=" << display->connector()
<< " origin=" << config.origin.ToString() << " size="
<< (mode_ptr ? ModeSize(*(mode_ptr.get())).ToString() : "0x0")
<< " refresh_rate=" << (mode_ptr ? mode_ptr->vrefresh : 0) << "Hz";
ScreenManager::ControllerConfigParams params(
display->display_id(), drm, display->crtc(), display->connector(),
config.origin, std::move(mode_ptr));
controllers_to_configure.push_back(std::move(params));
}
if (controllers_to_configure.empty())
return statuses;
if (clear_overlay_cache_callback_)
clear_overlay_cache_callback_.Run();
return display->Configure(&mode, origin);
}
auto config_statuses =
screen_manager_->ConfigureDisplayControllers(controllers_to_configure);
for (const auto& status : config_statuses) {
int64_t display_id = status.first;
bool success = status.second;
DrmDisplay* display = FindDisplay(display_id);
auto config = std::find_if(
config_requests.begin(), config_requests.end(),
[display_id](const auto& request) { return request.id == display_id; });
if (success) {
display->SetOrigin(config->origin);
} else {
if (config->mode) {
VLOG(1) << "Failed to enable device="
<< display->drm()->device_path().value()
<< " crtc=" << display->crtc()
<< " connector=" << display->connector();
} else {
VLOG(1) << "Failed to disable device="
<< display->drm()->device_path().value()
<< " crtc=" << display->crtc();
}
}
bool DrmGpuDisplayManager::DisableDisplay(int64_t display_id) {
DrmDisplay* display = FindDisplay(display_id);
if (!display) {
LOG(ERROR) << "There is no display with ID " << display_id;
return false;
statuses.insert(std::make_pair(display_id, success));
}
if (clear_overlay_cache_callback_)
clear_overlay_cache_callback_.Run();
return display->Configure(nullptr, gfx::Point());
return statuses;
}
bool DrmGpuDisplayManager::GetHDCPState(int64_t display_id,
......
......@@ -10,16 +10,19 @@
#include <vector>
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "ui/display/types/display_configuration_params.h"
#include "ui/display/types/display_constants.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/drm/common/display_types.h"
using drmModeModeInfo = struct _drmModeModeInfo;
namespace display {
class DisplayMode;
struct GammaRampRGBEntry;
}
} // namespace display
namespace gfx {
class ColorSpace;
......@@ -49,16 +52,13 @@ class DrmGpuDisplayManager {
bool TakeDisplayControl();
void RelinquishDisplayControl();
bool ConfigureDisplay(int64_t id,
const display::DisplayMode& display_mode,
const gfx::Point& origin);
bool DisableDisplay(int64_t id);
base::flat_map<int64_t, bool> ConfigureDisplays(
const std::vector<display::DisplayConfigurationParams>& config_requests);
bool GetHDCPState(int64_t display_id, display::HDCPState* state);
bool SetHDCPState(int64_t display_id, display::HDCPState state);
void SetColorMatrix(int64_t display_id,
const std::vector<float>& color_matrix);
void SetBackgroundColor(int64_t display_id,
const uint64_t background_color);
void SetBackgroundColor(int64_t display_id, const uint64_t background_color);
void SetGammaCorrection(
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
......
......@@ -5,6 +5,7 @@
#include "ui/ozone/platform/drm/gpu/drm_overlay_validator.h"
#include <drm_fourcc.h>
#include <xf86drm.h>
#include <memory>
#include <utility>
......@@ -213,8 +214,11 @@ void DrmOverlayValidatorTest::InitDrmStatesAndControllers(
void DrmOverlayValidatorTest::SetupControllers() {
screen_manager_ = std::make_unique<ui::ScreenManager>();
screen_manager_->AddDisplayController(drm_, kCrtcIdBase, kConnectorIdBase);
screen_manager_->ConfigureDisplayController(
drm_, kCrtcIdBase, kConnectorIdBase, gfx::Point(), kDefaultMode);
std::vector<ui::ScreenManager::ControllerConfigParams> controllers_to_enable;
controllers_to_enable.push_back(
{1 /*display_id*/, drm_, kCrtcIdBase, kConnectorIdBase, gfx::Point(),
std::make_unique<drmModeModeInfo>(kDefaultMode)});
screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
drm_device_manager_ = std::make_unique<ui::DrmDeviceManager>(nullptr);
......
......@@ -330,17 +330,9 @@ void DrmThread::ConfigureNativeDisplays(
base::OnceCallback<void(const base::flat_map<int64_t, bool>&)> callback) {
TRACE_EVENT0("drm", "DrmThread::ConfigureNativeDisplays");
base::flat_map<int64_t, bool> statuses;
for (const auto& config : config_requests) {
bool status = false;
if (config.mode) {
status = display_manager_->ConfigureDisplay(
config.id, *config.mode.value(), config.origin);
} else {
status = display_manager_->DisableDisplay(config.id);
}
statuses.insert(std::make_pair(config.id, status));
}
base::flat_map<int64_t, bool> statuses =
display_manager_->ConfigureDisplays(config_requests);
std::move(callback).Run(statuses);
}
......
......@@ -6,6 +6,7 @@
#include <drm_fourcc.h>
#include <stdint.h>
#include <xf86drm.h>
#include <memory>
#include <utility>
#include <vector>
......@@ -105,9 +106,13 @@ void DrmWindowTest::SetUp() {
auto gbm_device = std::make_unique<ui::MockGbmDevice>();
drm_ = new ui::MockDrmDevice(std::move(gbm_device));
screen_manager_ = std::make_unique<ui::ScreenManager>();
screen_manager_->AddDisplayController(drm_, kDefaultCrtc, kDefaultConnector);
screen_manager_->ConfigureDisplayController(
drm_, kDefaultCrtc, kDefaultConnector, gfx::Point(), kDefaultMode);
std::vector<ui::ScreenManager::ControllerConfigParams> controllers_to_enable;
controllers_to_enable.push_back(
{1 /*display_id*/, drm_, kDefaultCrtc, kDefaultConnector, gfx::Point(),
std::make_unique<drmModeModeInfo>(kDefaultMode)});
screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
drm_device_manager_ = std::make_unique<ui::DrmDeviceManager>(nullptr);
......@@ -161,10 +166,15 @@ TEST_F(DrmWindowTest, CheckCursorSurfaceAfterChangingDevice) {
auto gbm_device = std::make_unique<ui::MockGbmDevice>();
scoped_refptr<ui::MockDrmDevice> drm =
new ui::MockDrmDevice(std::move(gbm_device));
screen_manager_->AddDisplayController(drm, kDefaultCrtc, kDefaultConnector);
screen_manager_->ConfigureDisplayController(
drm, kDefaultCrtc, kDefaultConnector,
gfx::Point(0, kDefaultMode.vdisplay), kDefaultMode);
std::vector<ui::ScreenManager::ControllerConfigParams> controllers_to_enable;
controllers_to_enable.push_back(
{2 /*display_id*/, drm, kDefaultCrtc, kDefaultConnector,
gfx::Point(0, kDefaultMode.vdisplay),
std::make_unique<drmModeModeInfo>(kDefaultMode)});
screen_manager_->ConfigureDisplayControllers(controllers_to_enable);
// Move window to the display on the new device.
screen_manager_->GetWindow(kDefaultWidgetHandle)
......
......@@ -95,12 +95,41 @@ CrtcController* GetCrtcController(HardwareDisplayController* controller,
} // namespace
ScreenManager::ScreenManager() {}
ScreenManager::ScreenManager() = default;
ScreenManager::~ScreenManager() {
DCHECK(window_map_.empty());
}
ScreenManager::ControllerConfigParams::ControllerConfigParams(
int64_t display_id,
scoped_refptr<DrmDevice> drm,
uint32_t crtc,
uint32_t connector,
gfx::Point origin,
std::unique_ptr<drmModeModeInfo> pmode)
: display_id(display_id),
drm(drm),
crtc(crtc),
connector(connector),
origin(origin),
mode(std::move(pmode)) {}
ScreenManager::ControllerConfigParams::ControllerConfigParams(
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() = default;
void ScreenManager::AddDisplayController(const scoped_refptr<DrmDevice>& drm,
uint32_t crtc,
uint32_t connector) {
......@@ -115,8 +144,7 @@ void ScreenManager::AddDisplayController(const scoped_refptr<DrmDevice>& drm,
}
controllers_.push_back(std::make_unique<HardwareDisplayController>(
std::unique_ptr<CrtcController>(new CrtcController(drm, crtc, connector)),
gfx::Point()));
std::make_unique<CrtcController>(drm, crtc, connector), gfx::Point()));
}
void ScreenManager::RemoveDisplayController(const scoped_refptr<DrmDevice>& drm,
......@@ -132,26 +160,33 @@ void ScreenManager::RemoveDisplayController(const scoped_refptr<DrmDevice>& drm,
}
}
bool ScreenManager::ConfigureDisplayController(
const scoped_refptr<DrmDevice>& drm,
uint32_t crtc,
uint32_t connector,
const gfx::Point& origin,
const drmModeModeInfo& mode) {
bool status =
ActualConfigureDisplayController(drm, crtc, connector, origin, mode);
if (status)
base::flat_map<int64_t, bool> ScreenManager::ConfigureDisplayControllers(
const std::vector<ScreenManager::ControllerConfigParams>&
controllers_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;
}
if (has_everything_succeeded)
UpdateControllerToWindowMapping();
return status;
return statuses;
}
bool ScreenManager::ActualConfigureDisplayController(
const scoped_refptr<DrmDevice>& drm,
uint32_t crtc,
uint32_t connector,
const gfx::Point& origin,
const drmModeModeInfo& mode) {
bool ScreenManager::EnableDisplayController(const scoped_refptr<DrmDevice>& 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(drm, crtc);
......@@ -210,7 +245,6 @@ bool ScreenManager::DisableDisplayController(
}
controller->Disable();
UpdateControllerToWindowMapping();
return true;
}
......
......@@ -9,9 +9,11 @@
#include <memory>
#include <unordered_map>
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/drm/gpu/drm_display.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
typedef struct _drmModeModeInfo drmModeModeInfo;
......@@ -29,6 +31,24 @@ class DrmWindow;
// Responsible for keeping track of active displays and configuring them.
class ScreenManager {
public:
struct ControllerConfigParams {
ControllerConfigParams(int64_t display_id,
scoped_refptr<DrmDevice> drm,
uint32_t crtc,
uint32_t connector,
gfx::Point origin,
std::unique_ptr<drmModeModeInfo> pmode);
ControllerConfigParams(ControllerConfigParams&& other);
~ControllerConfigParams();
const int64_t display_id;
const scoped_refptr<DrmDevice> drm;
const uint32_t crtc;
const uint32_t connector;
const gfx::Point origin;
std::unique_ptr<drmModeModeInfo> mode = nullptr;
};
ScreenManager();
virtual ~ScreenManager();
......@@ -43,18 +63,10 @@ class ScreenManager {
void RemoveDisplayController(const scoped_refptr<DrmDevice>& drm,
uint32_t crtc);
// Configure a display controller. The display controller is identified by
// (|crtc|, |connector|) and the controller is modeset using |mode|.
bool ConfigureDisplayController(const scoped_refptr<DrmDevice>& drm,
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(const scoped_refptr<DrmDevice>& drm,
uint32_t crtc);
// Enables/Disables the display controller based on if a mode exists.
base::flat_map<int64_t, bool> ConfigureDisplayControllers(
const std::vector<ScreenManager::ControllerConfigParams>&
controllersParams);
// Returns a reference to the display controller configured to display within
// |bounds|. If the caller caches the controller it must also register as an
......@@ -90,11 +102,18 @@ class ScreenManager {
const scoped_refptr<DrmDevice>& drm,
uint32_t crtc);
bool ActualConfigureDisplayController(const scoped_refptr<DrmDevice>& drm,
uint32_t crtc,
uint32_t connector,
const gfx::Point& origin,
const drmModeModeInfo& mode);
// Configure a display controller. The display controller is identified by
// (|crtc|, |connector|) and the controller is modeset using |mode|.
bool EnableDisplayController(const scoped_refptr<DrmDevice>& drm,
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(const scoped_refptr<DrmDevice>& drm,
uint32_t crtc);
// Returns an iterator into |controllers_| for the controller located at
// |origin|.
......
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