// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/ozone/platform/drm/gpu/drm_display.h" #include #include "ui/display/types/gamma_ramp_rgb_entry.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/screen_manager.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}}; // Converts |state| to the DRM value associated with the it. 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; } 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; } } NOTREACHED(); return std::string(); } gfx::Size GetDrmModeSize(const drmModeModeInfo& mode) { return gfx::Size(mode.hdisplay, mode.vdisplay); } std::vector GetDrmModeVector(drmModeConnector* connector) { std::vector modes; for (int i = 0; i < connector->count_modes; ++i) modes.push_back(connector->modes[i]); return modes; } } // namespace DrmDisplay::DrmDisplay(ScreenManager* screen_manager, const scoped_refptr& drm) : screen_manager_(screen_manager), display_id_(-1), drm_(drm) { } DrmDisplay::~DrmDisplay() { } DisplaySnapshot_Params DrmDisplay::Update(HardwareDisplayControllerInfo* info, size_t display_index) { DisplaySnapshot_Params params = CreateDisplaySnapshotParams(info, drm_->get_fd(), display_index, origin_); crtc_ = info->crtc()->crtc_id; connector_ = info->connector()->connector_id; display_id_ = params.display_id; modes_ = GetDrmModeVector(info->connector()); 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_ << " origin=" << origin.ToString() << " size=" << (mode ? GetDrmModeSize(*mode).ToString() : "0x0"); if (mode) { if (!screen_manager_->ConfigureDisplayController(drm_, crtc_, connector_, origin, *mode)) { VLOG(1) << "Failed to configure: device=" << drm_->device_path().value() << " crtc=" << crtc_ << " connector=" << connector_; 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(HDCPState* state) { ScopedDrmConnectorPtr connector(drm_->GetConnector(connector_)); if (!connector) { PLOG(ERROR) << "Failed to get connector " << connector_; return false; } ScopedDrmPropertyPtr hdcp_property( drm_->GetProperty(connector.get(), kContentProtection)); if (!hdcp_property) { PLOG(ERROR) << "'" << kContentProtection << "' property doesn't exist."; 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; } bool DrmDisplay::SetHDCPState(HDCPState state) { ScopedDrmConnectorPtr connector(drm_->GetConnector(connector_)); if (!connector) { PLOG(ERROR) << "Failed to get connector " << connector_; return false; } ScopedDrmPropertyPtr hdcp_property( drm_->GetProperty(connector.get(), kContentProtection)); if (!hdcp_property) { LOG(ERROR) << "'" << kContentProtection << "' property doesn't exist."; return false; } return drm_->SetProperty( connector_, hdcp_property->prop_id, GetContentProtectionValue(hdcp_property.get(), state)); } void DrmDisplay::SetGammaRamp(const std::vector& lut) { if (!drm_->SetGammaRamp(crtc_, lut)) { LOG(ERROR) << "Failed to set gamma ramp for display: crtc_id = " << crtc_ << " size = " << lut.size(); } } } // namespace ui