ozone: fix HDPMLegacy - do the PF after overlays, also clear old overlays
[chromium-blink-merge.git] / ui / ozone / platform / dri / native_display_delegate_dri.cc
blobd1b853b4d5d944929ceb47d134720466980ad48c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/ozone/platform/dri/native_display_delegate_dri.h"
7 #include "base/bind.h"
8 #include "ui/display/types/native_display_observer.h"
9 #include "ui/events/ozone/device/device_event.h"
10 #include "ui/ozone/platform/dri/display_mode_dri.h"
11 #include "ui/ozone/platform/dri/display_snapshot_dri.h"
12 #include "ui/ozone/platform/dri/dri_util.h"
13 #include "ui/ozone/platform/dri/dri_wrapper.h"
14 #include "ui/ozone/platform/dri/screen_manager.h"
16 namespace ui {
18 namespace {
20 const char kContentProtection[] = "Content Protection";
22 struct ContentProtectionMapping {
23 const char* name;
24 HDCPState state;
27 const ContentProtectionMapping kContentProtectionStates[] = {
28 {"Undesired", HDCP_STATE_UNDESIRED},
29 {"Desired", HDCP_STATE_DESIRED},
30 {"Enabled", HDCP_STATE_ENABLED}};
32 uint32_t GetContentProtectionValue(drmModePropertyRes* property,
33 HDCPState state) {
34 std::string name;
35 for (size_t i = 0; i < arraysize(kContentProtectionStates); ++i) {
36 if (kContentProtectionStates[i].state == state) {
37 name = kContentProtectionStates[i].name;
38 break;
42 for (int i = 0; i < property->count_enums; ++i)
43 if (name == property->enums[i].name)
44 return i;
46 NOTREACHED();
47 return 0;
50 class DisplaySnapshotComparator {
51 public:
52 explicit DisplaySnapshotComparator(const DisplaySnapshotDri* snapshot)
53 : crtc_(snapshot->crtc()), connector_(snapshot->connector()) {}
55 DisplaySnapshotComparator(uint32_t crtc, uint32_t connector)
56 : crtc_(crtc), connector_(connector) {}
58 bool operator()(const DisplaySnapshotDri* other) const {
59 return connector_ == other->connector() && crtc_ == other->crtc();
62 private:
63 uint32_t crtc_;
64 uint32_t connector_;
67 } // namespace
69 NativeDisplayDelegateDri::NativeDisplayDelegateDri(
70 DriWrapper* dri,
71 ScreenManager* screen_manager)
72 : dri_(dri), screen_manager_(screen_manager) {
73 // TODO(dnicoara): Remove when async display configuration is supported.
74 screen_manager_->ForceInitializationOfPrimaryDisplay();
77 NativeDisplayDelegateDri::~NativeDisplayDelegateDri() {
80 DisplaySnapshot* NativeDisplayDelegateDri::FindDisplaySnapshot(int64_t id) {
81 for (size_t i = 0; i < cached_displays_.size(); ++i)
82 if (cached_displays_[i]->display_id() == id)
83 return cached_displays_[i];
85 return NULL;
88 const DisplayMode* NativeDisplayDelegateDri::FindDisplayMode(
89 const gfx::Size& size,
90 bool is_interlaced,
91 float refresh_rate) {
92 for (size_t i = 0; i < cached_modes_.size(); ++i)
93 if (cached_modes_[i]->size() == size &&
94 cached_modes_[i]->is_interlaced() == is_interlaced &&
95 cached_modes_[i]->refresh_rate() == refresh_rate)
96 return cached_modes_[i];
98 return NULL;
101 void NativeDisplayDelegateDri::Initialize() {
104 void NativeDisplayDelegateDri::GrabServer() {
107 void NativeDisplayDelegateDri::UngrabServer() {
110 bool NativeDisplayDelegateDri::TakeDisplayControl() {
111 if (!dri_->SetMaster()) {
112 LOG(ERROR) << "Failed to take control of the display";
113 return false;
115 return true;
118 bool NativeDisplayDelegateDri::RelinquishDisplayControl() {
119 if (!dri_->DropMaster()) {
120 LOG(ERROR) << "Failed to relinquish control of the display";
121 return false;
123 return true;
126 void NativeDisplayDelegateDri::SyncWithServer() {
129 void NativeDisplayDelegateDri::SetBackgroundColor(uint32_t color_argb) {
132 void NativeDisplayDelegateDri::ForceDPMSOn() {
133 for (size_t i = 0; i < cached_displays_.size(); ++i) {
134 DisplaySnapshotDri* dri_output = cached_displays_[i];
135 if (dri_output->dpms_property())
136 dri_->SetProperty(dri_output->connector(),
137 dri_output->dpms_property()->prop_id, DRM_MODE_DPMS_ON);
141 std::vector<DisplaySnapshot*> NativeDisplayDelegateDri::GetDisplays() {
142 ScopedVector<DisplaySnapshotDri> old_displays(cached_displays_.Pass());
143 ScopedVector<const DisplayMode> old_modes(cached_modes_.Pass());
145 ScopedVector<HardwareDisplayControllerInfo> displays =
146 GetAvailableDisplayControllerInfos(dri_->get_fd());
147 for (size_t i = 0; i < displays.size(); ++i) {
148 DisplaySnapshotDri* display = new DisplaySnapshotDri(
149 dri_, displays[i]->connector(), displays[i]->crtc(), i);
151 // If the display exists make sure to sync up the new snapshot with the old
152 // one to keep the user configured details.
153 auto it = std::find_if(
154 old_displays.begin(), old_displays.end(),
155 DisplaySnapshotComparator(displays[i]->crtc()->crtc_id,
156 displays[i]->connector()->connector_id));
157 // Origin is only used within the platform code to keep track of the display
158 // location.
159 if (it != old_displays.end())
160 display->set_origin((*it)->origin());
162 cached_displays_.push_back(display);
163 cached_modes_.insert(cached_modes_.end(), display->modes().begin(),
164 display->modes().end());
167 NotifyScreenManager(cached_displays_.get(), old_displays.get());
169 std::vector<DisplaySnapshot*> generic_displays(cached_displays_.begin(),
170 cached_displays_.end());
171 return generic_displays;
174 void NativeDisplayDelegateDri::GetDisplays(
175 const GetDisplaysCallback& callback) {
176 NOTREACHED();
179 void NativeDisplayDelegateDri::AddMode(const DisplaySnapshot& output,
180 const DisplayMode* mode) {
183 bool NativeDisplayDelegateDri::Configure(const DisplaySnapshot& output,
184 const DisplayMode* mode,
185 const gfx::Point& origin) {
186 const DisplaySnapshotDri& dri_output =
187 static_cast<const DisplaySnapshotDri&>(output);
189 VLOG(1) << "DRM configuring: crtc=" << dri_output.crtc()
190 << " connector=" << dri_output.connector()
191 << " origin=" << origin.ToString()
192 << " size=" << (mode ? mode->size().ToString() : "0x0");
194 if (mode) {
195 if (!screen_manager_->ConfigureDisplayController(
196 dri_output.crtc(), dri_output.connector(), origin,
197 static_cast<const DisplayModeDri*>(mode)->mode_info())) {
198 VLOG(1) << "Failed to configure: crtc=" << dri_output.crtc()
199 << " connector=" << dri_output.connector();
200 return false;
202 } else {
203 if (!screen_manager_->DisableDisplayController(dri_output.crtc())) {
204 VLOG(1) << "Failed to disable crtc=" << dri_output.crtc();
205 return false;
209 return true;
212 void NativeDisplayDelegateDri::Configure(const DisplaySnapshot& output,
213 const DisplayMode* mode,
214 const gfx::Point& origin,
215 const ConfigureCallback& callback) {
216 NOTREACHED();
219 void NativeDisplayDelegateDri::CreateFrameBuffer(const gfx::Size& size) {
222 bool NativeDisplayDelegateDri::GetHDCPState(const DisplaySnapshot& output,
223 HDCPState* state) {
224 const DisplaySnapshotDri& dri_output =
225 static_cast<const DisplaySnapshotDri&>(output);
227 ScopedDrmConnectorPtr connector(dri_->GetConnector(dri_output.connector()));
228 if (!connector) {
229 LOG(ERROR) << "Failed to get connector " << dri_output.connector();
230 return false;
233 ScopedDrmPropertyPtr hdcp_property(
234 dri_->GetProperty(connector.get(), kContentProtection));
235 if (!hdcp_property) {
236 LOG(ERROR) << "'" << kContentProtection << "' property doesn't exist.";
237 return false;
240 DCHECK_LT(static_cast<int>(hdcp_property->prop_id), connector->count_props);
241 int hdcp_state_idx = connector->prop_values[hdcp_property->prop_id];
242 DCHECK_LT(hdcp_state_idx, hdcp_property->count_enums);
244 std::string name(hdcp_property->enums[hdcp_state_idx].name);
245 for (size_t i = 0; i < arraysize(kContentProtectionStates); ++i) {
246 if (name == kContentProtectionStates[i].name) {
247 *state = kContentProtectionStates[i].state;
248 VLOG(3) << "HDCP state: " << *state << " (" << name << ")";
249 return true;
253 LOG(ERROR) << "Unknown content protection value '" << name << "'";
254 return false;
257 bool NativeDisplayDelegateDri::SetHDCPState(const DisplaySnapshot& output,
258 HDCPState state) {
259 const DisplaySnapshotDri& dri_output =
260 static_cast<const DisplaySnapshotDri&>(output);
262 ScopedDrmConnectorPtr connector(dri_->GetConnector(dri_output.connector()));
263 if (!connector) {
264 LOG(ERROR) << "Failed to get connector " << dri_output.connector();
265 return false;
268 ScopedDrmPropertyPtr hdcp_property(
269 dri_->GetProperty(connector.get(), kContentProtection));
270 if (!hdcp_property) {
271 LOG(ERROR) << "'" << kContentProtection << "' property doesn't exist.";
272 return false;
275 return dri_->SetProperty(
276 dri_output.connector(), hdcp_property->prop_id,
277 GetContentProtectionValue(hdcp_property.get(), state));
280 std::vector<ui::ColorCalibrationProfile>
281 NativeDisplayDelegateDri::GetAvailableColorCalibrationProfiles(
282 const ui::DisplaySnapshot& output) {
283 NOTIMPLEMENTED();
284 return std::vector<ui::ColorCalibrationProfile>();
287 bool NativeDisplayDelegateDri::SetColorCalibrationProfile(
288 const ui::DisplaySnapshot& output,
289 ui::ColorCalibrationProfile new_profile) {
290 NOTIMPLEMENTED();
291 return false;
294 void NativeDisplayDelegateDri::AddObserver(NativeDisplayObserver* observer) {
295 observers_.AddObserver(observer);
298 void NativeDisplayDelegateDri::RemoveObserver(NativeDisplayObserver* observer) {
299 observers_.RemoveObserver(observer);
302 void NativeDisplayDelegateDri::NotifyScreenManager(
303 const std::vector<DisplaySnapshotDri*>& new_displays,
304 const std::vector<DisplaySnapshotDri*>& old_displays) const {
305 for (size_t i = 0; i < old_displays.size(); ++i) {
306 const std::vector<DisplaySnapshotDri*>::const_iterator it =
307 std::find_if(new_displays.begin(), new_displays.end(),
308 DisplaySnapshotComparator(old_displays[i]));
310 if (it == new_displays.end())
311 screen_manager_->RemoveDisplayController(old_displays[i]->crtc());
314 for (size_t i = 0; i < new_displays.size(); ++i) {
315 const std::vector<DisplaySnapshotDri*>::const_iterator it =
316 std::find_if(old_displays.begin(), old_displays.end(),
317 DisplaySnapshotComparator(new_displays[i]));
319 if (it == old_displays.end())
320 screen_manager_->AddDisplayController(dri_, new_displays[i]->crtc(),
321 new_displays[i]->connector());
325 } // namespace ui