| Index: ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
|
| diff --git a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
|
| index 6f6a88490892a051164b11d71f38a62e548fe7f8..bb29a42dfb292d4acf1240e7c79610cc54213e74 100644
|
| --- a/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
|
| +++ b/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
|
| @@ -4,70 +4,31 @@
|
|
|
| #include "ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h"
|
|
|
| -#include "base/bind.h"
|
| -#include "base/command_line.h"
|
| -#include "base/file_descriptor_posix.h"
|
| -#include "base/files/file.h"
|
| -#include "base/single_thread_task_runner.h"
|
| #include "ui/display/types/gamma_ramp_rgb_entry.h"
|
| -#include "ui/display/types/native_display_observer.h"
|
| -#include "ui/events/ozone/device/device_event.h"
|
| #include "ui/ozone/common/display_util.h"
|
| #include "ui/ozone/platform/drm/common/drm_util.h"
|
| #include "ui/ozone/platform/drm/gpu/drm_device.h"
|
| #include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
|
| -#include "ui/ozone/platform/drm/gpu/drm_display_mode.h"
|
| -#include "ui/ozone/platform/drm/gpu/drm_display_snapshot.h"
|
| +#include "ui/ozone/platform/drm/gpu/drm_display.h"
|
| #include "ui/ozone/platform/drm/gpu/screen_manager.h"
|
| -#include "ui/ozone/public/ozone_switches.h"
|
|
|
| namespace ui {
|
|
|
| namespace {
|
|
|
| -const char kContentProtection[] = "Content Protection";
|
| -
|
| -struct ContentProtectionMapping {
|
| - const char* name;
|
| - HDCPState state;
|
| -};
|
| -
|
| -const ContentProtectionMapping kContentProtectionStates[] = {
|
| - {"Undesired", HDCP_STATE_UNDESIRED},
|
| - {"Desired", HDCP_STATE_DESIRED},
|
| - {"Enabled", HDCP_STATE_ENABLED}};
|
| -
|
| -uint32_t GetContentProtectionValue(drmModePropertyRes* property,
|
| - HDCPState state) {
|
| - std::string name;
|
| - for (size_t i = 0; i < arraysize(kContentProtectionStates); ++i) {
|
| - if (kContentProtectionStates[i].state == state) {
|
| - name = kContentProtectionStates[i].name;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - for (int i = 0; i < property->count_enums; ++i)
|
| - if (name == property->enums[i].name)
|
| - return i;
|
| -
|
| - NOTREACHED();
|
| - return 0;
|
| -}
|
| -
|
| -class DisplaySnapshotComparator {
|
| +class DisplayComparator {
|
| public:
|
| - explicit DisplaySnapshotComparator(const DrmDisplaySnapshot* snapshot)
|
| - : drm_(snapshot->drm()),
|
| - crtc_(snapshot->crtc()),
|
| - connector_(snapshot->connector()) {}
|
| -
|
| - DisplaySnapshotComparator(const scoped_refptr<DrmDevice>& drm,
|
| - uint32_t crtc,
|
| - uint32_t connector)
|
| + explicit DisplayComparator(const DrmDisplay* display)
|
| + : drm_(display->drm()),
|
| + crtc_(display->crtc()),
|
| + connector_(display->connector()) {}
|
| +
|
| + DisplayComparator(const scoped_refptr<DrmDevice>& drm,
|
| + uint32_t crtc,
|
| + uint32_t connector)
|
| : drm_(drm), crtc_(crtc), connector_(connector) {}
|
|
|
| - bool operator()(const DrmDisplaySnapshot* other) const {
|
| + bool operator()(const DrmDisplay* other) const {
|
| return drm_ == other->drm() && connector_ == other->connector() &&
|
| crtc_ == other->crtc();
|
| }
|
| @@ -78,21 +39,28 @@ class DisplaySnapshotComparator {
|
| uint32_t connector_;
|
| };
|
|
|
| -std::string GetEnumNameForProperty(drmModeConnector* connector,
|
| - drmModePropertyRes* property) {
|
| - for (int prop_idx = 0; prop_idx < connector->count_props; ++prop_idx) {
|
| - if (connector->props[prop_idx] != property->prop_id)
|
| - continue;
|
| -
|
| - for (int enum_idx = 0; enum_idx < property->count_enums; ++enum_idx) {
|
| - const drm_mode_property_enum& property_enum = property->enums[enum_idx];
|
| - if (property_enum.value == connector->prop_values[prop_idx])
|
| - return property_enum.name;
|
| +bool FindMatchingMode(const std::vector<drmModeModeInfo> modes,
|
| + const DisplayMode_Params& mode_params,
|
| + drmModeModeInfo* mode) {
|
| + for (const drmModeModeInfo& m : modes) {
|
| + DisplayMode_Params params = CreateDisplayModeParams(m);
|
| + if (mode_params.size == params.size &&
|
| + mode_params.refresh_rate == params.refresh_rate &&
|
| + mode_params.is_interlaced == params.is_interlaced) {
|
| + *mode = m;
|
| + return true;
|
| }
|
| }
|
|
|
| - NOTREACHED();
|
| - return std::string();
|
| + return false;
|
| +}
|
| +
|
| +std::vector<drmModeModeInfo> GetDrmModeVector(drmModeConnector* connector) {
|
| + std::vector<drmModeModeInfo> modes;
|
| + for (int i = 0; i < connector->count_modes; ++i)
|
| + modes.push_back(connector->modes[i]);
|
| +
|
| + return modes;
|
| }
|
|
|
| } // namespace
|
| @@ -106,69 +74,30 @@ DrmGpuDisplayManager::~DrmGpuDisplayManager() {
|
| }
|
|
|
| std::vector<DisplaySnapshot_Params> DrmGpuDisplayManager::GetDisplays() {
|
| - RefreshDisplayList();
|
| -
|
| - std::vector<DisplaySnapshot_Params> displays;
|
| - for (size_t i = 0; i < cached_displays_.size(); ++i)
|
| - displays.push_back(GetDisplaySnapshotParams(*cached_displays_[i]));
|
| -
|
| - return displays;
|
| -}
|
| -
|
| -bool DrmGpuDisplayManager::ConfigureDisplay(
|
| - int64_t id,
|
| - const DisplayMode_Params& mode_param,
|
| - const gfx::Point& origin) {
|
| - DrmDisplaySnapshot* display = FindDisplaySnapshot(id);
|
| - if (!display) {
|
| - LOG(ERROR) << "There is no display with ID " << id;
|
| - return false;
|
| - }
|
| + ScopedVector<DrmDisplay> old_displays(displays_.Pass());
|
| + std::vector<DisplaySnapshot_Params> params_list;
|
|
|
| - const DisplayMode* mode = NULL;
|
| - for (size_t i = 0; i < display->modes().size(); ++i) {
|
| - if (mode_param.size == display->modes()[i]->size() &&
|
| - mode_param.is_interlaced == display->modes()[i]->is_interlaced() &&
|
| - mode_param.refresh_rate == display->modes()[i]->refresh_rate()) {
|
| - mode = display->modes()[i];
|
| - break;
|
| + const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices();
|
| + // Unique identifier used to create the display id.
|
| + size_t index = 0;
|
| + for (const auto& drm : devices) {
|
| + ScopedVector<HardwareDisplayControllerInfo> display_infos =
|
| + GetAvailableDisplayControllerInfos(drm->get_fd());
|
| + for (auto* display_info : display_infos) {
|
| + DisplaySnapshot_Params params =
|
| + CreateDisplaySnapshotParams(display_info, drm->get_fd(), index++);
|
| + params_list.push_back(params);
|
| +
|
| + displays_.push_back(
|
| + new DrmDisplay(screen_manager_, params.display_id, drm,
|
| + display_info->crtc()->crtc_id,
|
| + display_info->connector()->connector_id,
|
| + GetDrmModeVector(display_info->connector())));
|
| }
|
| }
|
|
|
| - // 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).
|
| - if (!mode)
|
| - mode = FindDisplayMode(mode_param.size, mode_param.is_interlaced,
|
| - mode_param.refresh_rate);
|
| -
|
| - if (!mode) {
|
| - LOG(ERROR) << "Failed to find mode: size=" << mode_param.size.ToString()
|
| - << " is_interlaced=" << mode_param.is_interlaced
|
| - << " refresh_rate=" << mode_param.refresh_rate;
|
| - return false;
|
| - }
|
| -
|
| - bool success =
|
| - Configure(*display, static_cast<const DrmDisplayMode*>(mode), origin);
|
| - if (success) {
|
| - display->set_origin(origin);
|
| - display->set_current_mode(mode);
|
| - }
|
| -
|
| - return success;
|
| -}
|
| -
|
| -bool DrmGpuDisplayManager::DisableDisplay(int64_t id) {
|
| - DrmDisplaySnapshot* display = FindDisplaySnapshot(id);
|
| - bool success = false;
|
| - if (display)
|
| - success = Configure(*display, NULL, gfx::Point());
|
| - else
|
| - LOG(ERROR) << "There is no display with ID " << id;
|
| -
|
| - return success;
|
| + NotifyScreenManager(displays_.get(), old_displays.get());
|
| + return params_list;
|
| }
|
|
|
| bool DrmGpuDisplayManager::TakeDisplayControl() {
|
| @@ -179,6 +108,7 @@ bool DrmGpuDisplayManager::TakeDisplayControl() {
|
| return false;
|
| }
|
| }
|
| +
|
| return true;
|
| }
|
|
|
| @@ -190,176 +120,101 @@ bool DrmGpuDisplayManager::RelinquishDisplayControl() {
|
| return false;
|
| }
|
| }
|
| +
|
| return true;
|
| }
|
|
|
| -void DrmGpuDisplayManager::SetGammaRamp(
|
| - int64_t id,
|
| - const std::vector<GammaRampRGBEntry>& lut) {
|
| - DrmDisplaySnapshot* display = FindDisplaySnapshot(id);
|
| +bool DrmGpuDisplayManager::ConfigureDisplay(
|
| + int64_t display_id,
|
| + const DisplayMode_Params& mode_param,
|
| + const gfx::Point& origin) {
|
| + DrmDisplay* display = FindDisplay(display_id);
|
| if (!display) {
|
| - LOG(ERROR) << "There is no display with ID " << id;
|
| - return;
|
| + LOG(ERROR) << "There is no display with ID " << display_id;
|
| + return false;
|
| }
|
|
|
| - if (!display->drm()->SetGammaRamp(display->crtc(), lut)) {
|
| - LOG(ERROR) << "Failed to set gamma ramp for display: crtc_id = "
|
| - << display->crtc() << " size = " << lut.size();
|
| + drmModeModeInfo mode;
|
| + bool mode_found = FindMatchingMode(display->modes(), mode_param, &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 (DrmDisplay* other : displays_) {
|
| + mode_found = FindMatchingMode(other->modes(), mode_param, &mode);
|
| + if (mode_found)
|
| + break;
|
| + }
|
| }
|
| -}
|
| -
|
| -DrmDisplaySnapshot* DrmGpuDisplayManager::FindDisplaySnapshot(int64_t id) {
|
| - for (size_t i = 0; i < cached_displays_.size(); ++i)
|
| - if (cached_displays_[i]->display_id() == id)
|
| - return cached_displays_[i];
|
| -
|
| - return NULL;
|
| -}
|
|
|
| -const DrmDisplayMode* DrmGpuDisplayManager::FindDisplayMode(
|
| - const gfx::Size& size,
|
| - bool is_interlaced,
|
| - float refresh_rate) {
|
| - for (size_t i = 0; i < cached_modes_.size(); ++i)
|
| - if (cached_modes_[i]->size() == size &&
|
| - cached_modes_[i]->is_interlaced() == is_interlaced &&
|
| - cached_modes_[i]->refresh_rate() == refresh_rate)
|
| - return static_cast<const DrmDisplayMode*>(cached_modes_[i]);
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -void DrmGpuDisplayManager::RefreshDisplayList() {
|
| - ScopedVector<DrmDisplaySnapshot> old_displays(cached_displays_.Pass());
|
| - ScopedVector<const DisplayMode> old_modes(cached_modes_.Pass());
|
| -
|
| - const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices();
|
| - for (const auto& drm : devices) {
|
| - ScopedVector<HardwareDisplayControllerInfo> displays =
|
| - GetAvailableDisplayControllerInfos(drm->get_fd());
|
| - for (size_t i = 0; i < displays.size(); ++i) {
|
| - DrmDisplaySnapshot* display = new DrmDisplaySnapshot(
|
| - 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());
|
| - }
|
| + if (!mode_found) {
|
| + LOG(ERROR) << "Failed to find mode: size=" << mode_param.size.ToString()
|
| + << " is_interlaced=" << mode_param.is_interlaced
|
| + << " refresh_rate=" << mode_param.refresh_rate;
|
| + return false;
|
| }
|
|
|
| - NotifyScreenManager(cached_displays_.get(), old_displays.get());
|
| + return display->Configure(&mode, origin);
|
| }
|
|
|
| -bool DrmGpuDisplayManager::Configure(const DrmDisplaySnapshot& output,
|
| - const DrmDisplayMode* mode,
|
| - const gfx::Point& origin) {
|
| - VLOG(1) << "DRM configuring: device=" << output.drm()->device_path().value()
|
| - << " crtc=" << output.crtc() << " connector=" << output.connector()
|
| - << " origin=" << origin.ToString()
|
| - << " size=" << (mode ? mode->size().ToString() : "0x0");
|
| -
|
| - if (mode) {
|
| - if (!screen_manager_->ConfigureDisplayController(
|
| - output.drm(), output.crtc(), output.connector(), origin,
|
| - mode->mode_info())) {
|
| - VLOG(1) << "Failed to configure: device="
|
| - << output.drm()->device_path().value()
|
| - << " crtc=" << output.crtc()
|
| - << " connector=" << output.connector();
|
| - return false;
|
| - }
|
| - } else {
|
| - if (!screen_manager_->DisableDisplayController(output.drm(),
|
| - output.crtc())) {
|
| - VLOG(1) << "Failed to disable device="
|
| - << output.drm()->device_path().value()
|
| - << " crtc=" << output.crtc();
|
| - return false;
|
| - }
|
| +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;
|
| }
|
|
|
| - return true;
|
| + return display->Configure(nullptr, gfx::Point());
|
| }
|
|
|
| bool DrmGpuDisplayManager::GetHDCPState(int64_t display_id, HDCPState* state) {
|
| - DrmDisplaySnapshot* output = FindDisplaySnapshot(display_id);
|
| - if (!output) {
|
| + DrmDisplay* display = FindDisplay(display_id);
|
| + if (!display) {
|
| LOG(ERROR) << "There is no display with ID " << display_id;
|
| return false;
|
| }
|
|
|
| - ScopedDrmConnectorPtr connector(
|
| - output->drm()->GetConnector(output->connector()));
|
| - if (!connector) {
|
| - PLOG(ERROR) << "Failed to get connector " << output->connector();
|
| - return false;
|
| - }
|
| + return display->GetHDCPState(state);
|
| +}
|
|
|
| - ScopedDrmPropertyPtr hdcp_property(
|
| - output->drm()->GetProperty(connector.get(), kContentProtection));
|
| - if (!hdcp_property) {
|
| - PLOG(ERROR) << "'" << kContentProtection << "' property doesn't exist.";
|
| +bool DrmGpuDisplayManager::SetHDCPState(int64_t display_id, HDCPState state) {
|
| + DrmDisplay* display = FindDisplay(display_id);
|
| + if (!display) {
|
| + LOG(ERROR) << "There is no display with ID " << display_id;
|
| return false;
|
| }
|
|
|
| - std::string name =
|
| - GetEnumNameForProperty(connector.get(), hdcp_property.get());
|
| - for (size_t i = 0; i < arraysize(kContentProtectionStates); ++i) {
|
| - if (name == kContentProtectionStates[i].name) {
|
| - *state = kContentProtectionStates[i].state;
|
| - VLOG(3) << "HDCP state: " << *state << " (" << name << ")";
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - LOG(ERROR) << "Unknown content protection value '" << name << "'";
|
| - return false;
|
| + return display->SetHDCPState(state);
|
| }
|
|
|
| -bool DrmGpuDisplayManager::SetHDCPState(int64_t display_id, HDCPState state) {
|
| - DrmDisplaySnapshot* output = FindDisplaySnapshot(display_id);
|
| - if (!output) {
|
| +void DrmGpuDisplayManager::SetGammaRamp(
|
| + int64_t display_id,
|
| + const std::vector<GammaRampRGBEntry>& lut) {
|
| + DrmDisplay* display = FindDisplay(display_id);
|
| + if (!display) {
|
| LOG(ERROR) << "There is no display with ID " << display_id;
|
| - return false;
|
| + return;
|
| }
|
|
|
| - ScopedDrmConnectorPtr connector(
|
| - output->drm()->GetConnector(output->connector()));
|
| - if (!connector) {
|
| - PLOG(ERROR) << "Failed to get connector " << output->connector();
|
| - return false;
|
| - }
|
| + display->SetGammaRamp(lut);
|
| +}
|
|
|
| - ScopedDrmPropertyPtr hdcp_property(
|
| - output->drm()->GetProperty(connector.get(), kContentProtection));
|
| - if (!hdcp_property) {
|
| - PLOG(ERROR) << "'" << kContentProtection << "' property doesn't exist.";
|
| - return false;
|
| - }
|
| +DrmDisplay* DrmGpuDisplayManager::FindDisplay(int64_t display_id) {
|
| + for (DrmDisplay* display : displays_)
|
| + if (display->display_id() == display_id)
|
| + return display;
|
|
|
| - return output->drm()->SetProperty(
|
| - output->connector(), hdcp_property->prop_id,
|
| - GetContentProtectionValue(hdcp_property.get(), state));
|
| + return nullptr;
|
| }
|
|
|
| void DrmGpuDisplayManager::NotifyScreenManager(
|
| - const std::vector<DrmDisplaySnapshot*>& new_displays,
|
| - const std::vector<DrmDisplaySnapshot*>& old_displays) const {
|
| + const std::vector<DrmDisplay*>& new_displays,
|
| + const std::vector<DrmDisplay*>& old_displays) const {
|
| for (size_t i = 0; i < old_displays.size(); ++i) {
|
| - const std::vector<DrmDisplaySnapshot*>::const_iterator it =
|
| + const std::vector<DrmDisplay*>::const_iterator it =
|
| std::find_if(new_displays.begin(), new_displays.end(),
|
| - DisplaySnapshotComparator(old_displays[i]));
|
| + DisplayComparator(old_displays[i]));
|
|
|
| if (it == new_displays.end()) {
|
| screen_manager_->RemoveDisplayController(old_displays[i]->drm(),
|
| @@ -368,9 +223,9 @@ void DrmGpuDisplayManager::NotifyScreenManager(
|
| }
|
|
|
| for (size_t i = 0; i < new_displays.size(); ++i) {
|
| - const std::vector<DrmDisplaySnapshot*>::const_iterator it =
|
| + const std::vector<DrmDisplay*>::const_iterator it =
|
| std::find_if(old_displays.begin(), old_displays.end(),
|
| - DisplaySnapshotComparator(new_displays[i]));
|
| + DisplayComparator(new_displays[i]));
|
|
|
| if (it == old_displays.end()) {
|
| screen_manager_->AddDisplayController(new_displays[i]->drm(),
|
|
|