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_proxy.h"
9 #include "base/logging.h"
10 #include "base/threading/thread_restrictions.h"
11 #include "ui/display/types/display_snapshot.h"
12 #include "ui/display/types/native_display_observer.h"
13 #include "ui/events/ozone/device/device_event.h"
14 #include "ui/events/ozone/device/device_manager.h"
15 #include "ui/ozone/common/display_snapshot_proxy.h"
16 #include "ui/ozone/common/display_util.h"
17 #include "ui/ozone/common/gpu/ozone_gpu_messages.h"
18 #include "ui/ozone/platform/dri/display_manager.h"
19 #include "ui/ozone/platform/dri/dri_gpu_platform_support_host.h"
25 class DriDisplaySnapshotProxy
: public DisplaySnapshotProxy
{
27 DriDisplaySnapshotProxy(const DisplaySnapshot_Params
& params
,
28 DisplayManager
* display_manager
)
29 : DisplaySnapshotProxy(params
), display_manager_(display_manager
) {
30 display_manager_
->RegisterDisplay(this);
33 ~DriDisplaySnapshotProxy() override
{
34 display_manager_
->UnregisterDisplay(this);
38 DisplayManager
* display_manager_
; // Not owned.
40 DISALLOW_COPY_AND_ASSIGN(DriDisplaySnapshotProxy
);
45 NativeDisplayDelegateProxy::NativeDisplayDelegateProxy(
46 DriGpuPlatformSupportHost
* proxy
,
47 DeviceManager
* device_manager
,
48 DisplayManager
* display_manager
)
50 device_manager_(device_manager
),
51 display_manager_(display_manager
),
52 has_dummy_display_(false) {
53 proxy_
->RegisterHandler(this);
56 NativeDisplayDelegateProxy::~NativeDisplayDelegateProxy() {
57 device_manager_
->RemoveObserver(this);
58 proxy_
->UnregisterHandler(this);
61 void NativeDisplayDelegateProxy::Initialize() {
62 device_manager_
->AddObserver(this);
63 device_manager_
->ScanDevices(this);
65 if (!displays_
.empty())
67 DisplaySnapshot_Params params
;
70 // The file generated by frecon that contains EDID for the 1st display.
71 const base::FilePath
kEDIDFile("/tmp/display_info.bin");
73 // Just read it on current thread as this is necessary information
74 // to start. This access only tmpfs, which is fast.
75 // TODO(dnicoara|oshima): crbug.com/450886.
76 base::ThreadRestrictions::ScopedAllowIO allow_io
;
77 success
= CreateSnapshotFromEDIDFile(kEDIDFile
, ¶ms
);
80 // Fallback to command line if the file doesn't exit or failed to read.
81 if (success
|| CreateSnapshotFromCommandLine(¶ms
)) {
82 DCHECK_NE(DISPLAY_CONNECTION_TYPE_NONE
, params
.type
);
83 displays_
.push_back(new DriDisplaySnapshotProxy(params
, display_manager_
));
84 has_dummy_display_
= true;
88 void NativeDisplayDelegateProxy::GrabServer() {
91 void NativeDisplayDelegateProxy::UngrabServer() {
94 bool NativeDisplayDelegateProxy::TakeDisplayControl() {
95 proxy_
->Send(new OzoneGpuMsg_TakeDisplayControl());
99 bool NativeDisplayDelegateProxy::RelinquishDisplayControl() {
100 proxy_
->Send(new OzoneGpuMsg_RelinquishDisplayControl());
104 void NativeDisplayDelegateProxy::SyncWithServer() {
107 void NativeDisplayDelegateProxy::SetBackgroundColor(uint32_t color_argb
) {
111 void NativeDisplayDelegateProxy::ForceDPMSOn() {
112 proxy_
->Send(new OzoneGpuMsg_ForceDPMSOn());
115 void NativeDisplayDelegateProxy::GetDisplays(
116 const GetDisplaysCallback
& callback
) {
117 get_displays_callback_
= callback
;
118 // GetDisplays() is supposed to force a refresh of the display list.
119 if (!proxy_
->Send(new OzoneGpuMsg_RefreshNativeDisplays())) {
120 get_displays_callback_
.Run(displays_
.get());
121 get_displays_callback_
.Reset();
125 void NativeDisplayDelegateProxy::AddMode(const DisplaySnapshot
& output
,
126 const DisplayMode
* mode
) {
129 void NativeDisplayDelegateProxy::Configure(const DisplaySnapshot
& output
,
130 const DisplayMode
* mode
,
131 const gfx::Point
& origin
,
132 const ConfigureCallback
& callback
) {
133 if (has_dummy_display_
) {
138 configure_callback_map_
[output
.display_id()] = callback
;
142 status
= proxy_
->Send(new OzoneGpuMsg_ConfigureNativeDisplay(
143 output
.display_id(), GetDisplayModeParams(*mode
), origin
));
146 proxy_
->Send(new OzoneGpuMsg_DisableNativeDisplay(output
.display_id()));
150 OnDisplayConfigured(output
.display_id(), false);
153 void NativeDisplayDelegateProxy::CreateFrameBuffer(const gfx::Size
& size
) {
156 bool NativeDisplayDelegateProxy::GetHDCPState(const DisplaySnapshot
& output
,
162 bool NativeDisplayDelegateProxy::SetHDCPState(const DisplaySnapshot
& output
,
168 std::vector
<ColorCalibrationProfile
>
169 NativeDisplayDelegateProxy::GetAvailableColorCalibrationProfiles(
170 const DisplaySnapshot
& output
) {
172 return std::vector
<ColorCalibrationProfile
>();
175 bool NativeDisplayDelegateProxy::SetColorCalibrationProfile(
176 const DisplaySnapshot
& output
,
177 ColorCalibrationProfile new_profile
) {
182 void NativeDisplayDelegateProxy::AddObserver(NativeDisplayObserver
* observer
) {
183 observers_
.AddObserver(observer
);
186 void NativeDisplayDelegateProxy::RemoveObserver(
187 NativeDisplayObserver
* observer
) {
188 observers_
.RemoveObserver(observer
);
191 void NativeDisplayDelegateProxy::OnDeviceEvent(const DeviceEvent
& event
) {
192 if (event
.device_type() != DeviceEvent::DISPLAY
)
195 switch (event
.action_type()) {
196 case DeviceEvent::ADD
:
197 VLOG(1) << "Got display added event for " << event
.path().value();
198 proxy_
->Send(new OzoneGpuMsg_AddGraphicsDevice(event
.path()));
200 case DeviceEvent::CHANGE
:
201 VLOG(1) << "Got display changed event for " << event
.path().value();
203 case DeviceEvent::REMOVE
:
204 VLOG(1) << "Got display removed event for " << event
.path().value();
205 proxy_
->Send(new OzoneGpuMsg_RemoveGraphicsDevice(event
.path()));
209 FOR_EACH_OBSERVER(NativeDisplayObserver
, observers_
,
210 OnConfigurationChanged());
213 void NativeDisplayDelegateProxy::OnChannelEstablished(
215 scoped_refptr
<base::SingleThreadTaskRunner
> send_runner
,
216 const base::Callback
<void(IPC::Message
*)>& send_callback
) {
217 FOR_EACH_OBSERVER(NativeDisplayObserver
, observers_
,
218 OnConfigurationChanged());
221 void NativeDisplayDelegateProxy::OnChannelDestroyed(int host_id
) {
222 // If the channel got destroyed in the middle of a configuration then just
223 // respond with failure.
224 if (!get_displays_callback_
.is_null()) {
225 get_displays_callback_
.Run(std::vector
<DisplaySnapshot
*>());
226 get_displays_callback_
.Reset();
229 for (const auto& pair
: configure_callback_map_
) {
230 pair
.second
.Run(false);
233 configure_callback_map_
.clear();
236 bool NativeDisplayDelegateProxy::OnMessageReceived(
237 const IPC::Message
& message
) {
240 IPC_BEGIN_MESSAGE_MAP(NativeDisplayDelegateProxy
, message
)
241 IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays
, OnUpdateNativeDisplays
)
242 IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured
, OnDisplayConfigured
)
243 IPC_MESSAGE_UNHANDLED(handled
= false)
244 IPC_END_MESSAGE_MAP()
249 void NativeDisplayDelegateProxy::OnUpdateNativeDisplays(
250 const std::vector
<DisplaySnapshot_Params
>& displays
) {
251 has_dummy_display_
= false;
253 for (size_t i
= 0; i
< displays
.size(); ++i
)
255 new DriDisplaySnapshotProxy(displays
[i
], display_manager_
));
257 if (!get_displays_callback_
.is_null()) {
258 get_displays_callback_
.Run(displays_
.get());
259 get_displays_callback_
.Reset();
263 void NativeDisplayDelegateProxy::OnDisplayConfigured(int64_t display_id
,
265 auto it
= configure_callback_map_
.find(display_id
);
266 if (it
!= configure_callback_map_
.end()) {
267 it
->second
.Run(status
);
268 configure_callback_map_
.erase(it
);