Commit e26c6dee authored by dnicoara's avatar dnicoara Committed by Commit bot

[Ozone-DRI] Add support for asynchronous display configuration

Keep track of the display configuration callbacks and trigger them when the
GPU process responds.

BUG=429746
NOTRY=true
TBR=kenrb@chromium.org

Review URL: https://codereview.chromium.org/800743002

Cr-Commit-Position: refs/heads/master@{#308255}
parent 6fd2ad99
...@@ -80,9 +80,7 @@ IPC_MESSAGE_CONTROL0(OzoneGpuMsg_ForceDPMSOn) ...@@ -80,9 +80,7 @@ IPC_MESSAGE_CONTROL0(OzoneGpuMsg_ForceDPMSOn)
// Trigger a display reconfiguration. OzoneHostMsg_UpdateNativeDisplays will be // Trigger a display reconfiguration. OzoneHostMsg_UpdateNativeDisplays will be
// sent as a response. // sent as a response.
// The |displays| parameter will hold a list of last known displays. IPC_MESSAGE_CONTROL0(OzoneGpuMsg_RefreshNativeDisplays)
IPC_MESSAGE_CONTROL1(OzoneGpuMsg_RefreshNativeDisplays,
std::vector<ui::DisplaySnapshot_Params> /* displays */)
// Configure a display with the specified mode at the specified location. // Configure a display with the specified mode at the specified location.
IPC_MESSAGE_CONTROL3(OzoneGpuMsg_ConfigureNativeDisplay, IPC_MESSAGE_CONTROL3(OzoneGpuMsg_ConfigureNativeDisplay,
...@@ -112,3 +110,7 @@ IPC_MESSAGE_CONTROL0(OzoneGpuMsg_RelinquishDisplayControl) ...@@ -112,3 +110,7 @@ IPC_MESSAGE_CONTROL0(OzoneGpuMsg_RelinquishDisplayControl)
// Updates the list of active displays. // Updates the list of active displays.
IPC_MESSAGE_CONTROL1(OzoneHostMsg_UpdateNativeDisplays, IPC_MESSAGE_CONTROL1(OzoneHostMsg_UpdateNativeDisplays,
std::vector<ui::DisplaySnapshot_Params>) std::vector<ui::DisplaySnapshot_Params>)
IPC_MESSAGE_CONTROL2(OzoneHostMsg_DisplayConfigured,
int64_t /* display_id */,
bool /* status */)
...@@ -119,27 +119,10 @@ void DriGpuPlatformSupport::OnForceDPMSOn() { ...@@ -119,27 +119,10 @@ void DriGpuPlatformSupport::OnForceDPMSOn() {
ndd_->ForceDPMSOn(); ndd_->ForceDPMSOn();
} }
void DriGpuPlatformSupport::OnRefreshNativeDisplays( void DriGpuPlatformSupport::OnRefreshNativeDisplays() {
const std::vector<DisplaySnapshot_Params>& cached_displays) {
std::vector<DisplaySnapshot_Params> displays; std::vector<DisplaySnapshot_Params> displays;
std::vector<DisplaySnapshot*> native_displays = ndd_->GetDisplays(); std::vector<DisplaySnapshot*> native_displays = ndd_->GetDisplays();
// If any of the cached displays are in the list of new displays then apply
// their configuration immediately.
for (size_t i = 0; i < native_displays.size(); ++i) {
std::vector<DisplaySnapshot_Params>::const_iterator it =
std::find_if(cached_displays.begin(), cached_displays.end(),
FindDisplayById(native_displays[i]->display_id()));
if (it == cached_displays.end())
continue;
if (it->has_current_mode)
OnConfigureNativeDisplay(it->display_id, it->current_mode, it->origin);
else
OnDisableNativeDisplay(it->display_id);
}
for (size_t i = 0; i < native_displays.size(); ++i) for (size_t i = 0; i < native_displays.size(); ++i)
displays.push_back(GetDisplaySnapshotParams(*native_displays[i])); displays.push_back(GetDisplaySnapshotParams(*native_displays[i]));
...@@ -181,7 +164,8 @@ void DriGpuPlatformSupport::OnConfigureNativeDisplay( ...@@ -181,7 +164,8 @@ void DriGpuPlatformSupport::OnConfigureNativeDisplay(
return; return;
} }
ndd_->Configure(*display, mode, origin); sender_->Send(new OzoneHostMsg_DisplayConfigured(
id, ndd_->Configure(*display, mode, origin)));
} }
void DriGpuPlatformSupport::OnDisableNativeDisplay(int64_t id) { void DriGpuPlatformSupport::OnDisableNativeDisplay(int64_t id) {
......
...@@ -64,8 +64,7 @@ class DriGpuPlatformSupport : public GpuPlatformSupport { ...@@ -64,8 +64,7 @@ class DriGpuPlatformSupport : public GpuPlatformSupport {
// Display related IPC handlers. // Display related IPC handlers.
void OnForceDPMSOn(); void OnForceDPMSOn();
void OnRefreshNativeDisplays( void OnRefreshNativeDisplays();
const std::vector<DisplaySnapshot_Params>& cached_displays);
void OnConfigureNativeDisplay(int64_t id, void OnConfigureNativeDisplay(int64_t id,
const DisplayMode_Params& mode, const DisplayMode_Params& mode,
const gfx::Point& origin); const gfx::Point& origin);
......
...@@ -87,7 +87,7 @@ bool DriGpuPlatformSupportHost::Send(IPC::Message* message) { ...@@ -87,7 +87,7 @@ bool DriGpuPlatformSupportHost::Send(IPC::Message* message) {
if (sender_) if (sender_)
return sender_->Send(message); return sender_->Send(message);
return true; return false;
} }
void DriGpuPlatformSupportHost::SetHardwareCursor( void DriGpuPlatformSupportHost::SetHardwareCursor(
......
...@@ -47,7 +47,8 @@ NativeDisplayDelegateProxy::NativeDisplayDelegateProxy( ...@@ -47,7 +47,8 @@ NativeDisplayDelegateProxy::NativeDisplayDelegateProxy(
DisplayManager* display_manager) DisplayManager* display_manager)
: proxy_(proxy), : proxy_(proxy),
device_manager_(device_manager), device_manager_(device_manager),
display_manager_(display_manager) { display_manager_(display_manager),
has_dummy_display_(false) {
proxy_->RegisterHandler(this); proxy_->RegisterHandler(this);
} }
...@@ -64,8 +65,10 @@ void NativeDisplayDelegateProxy::Initialize() { ...@@ -64,8 +65,10 @@ void NativeDisplayDelegateProxy::Initialize() {
return; return;
DisplaySnapshot_Params params = CreateSnapshotFromCommandLine(); DisplaySnapshot_Params params = CreateSnapshotFromCommandLine();
if (params.type != DISPLAY_CONNECTION_TYPE_NONE) if (params.type != DISPLAY_CONNECTION_TYPE_NONE) {
displays_.push_back(new DriDisplaySnapshotProxy(params, display_manager_)); displays_.push_back(new DriDisplaySnapshotProxy(params, display_manager_));
has_dummy_display_ = true;
}
} }
void NativeDisplayDelegateProxy::GrabServer() { void NativeDisplayDelegateProxy::GrabServer() {
...@@ -98,8 +101,9 @@ void NativeDisplayDelegateProxy::ForceDPMSOn() { ...@@ -98,8 +101,9 @@ void NativeDisplayDelegateProxy::ForceDPMSOn() {
void NativeDisplayDelegateProxy::GetDisplays( void NativeDisplayDelegateProxy::GetDisplays(
const GetDisplaysCallback& callback) { const GetDisplaysCallback& callback) {
// GetDisplays() is supposed to force a refresh of the display list. // GetDisplays() is supposed to force a refresh of the display list.
proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays( if (proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays()))
std::vector<DisplaySnapshot_Params>())); get_displays_callback_ = callback;
else
callback.Run(displays_.get()); callback.Run(displays_.get());
} }
...@@ -111,14 +115,24 @@ void NativeDisplayDelegateProxy::Configure(const DisplaySnapshot& output, ...@@ -111,14 +115,24 @@ void NativeDisplayDelegateProxy::Configure(const DisplaySnapshot& output,
const DisplayMode* mode, const DisplayMode* mode,
const gfx::Point& origin, const gfx::Point& origin,
const ConfigureCallback& callback) { const ConfigureCallback& callback) {
// TODO(dnicoara) Should handle an asynchronous response. if (has_dummy_display_) {
if (mode) callback.Run(true);
proxy_->Send(new OzoneGpuMsg_ConfigureNativeDisplay( return;
}
bool status = false;
if (mode) {
status = proxy_->Send(new OzoneGpuMsg_ConfigureNativeDisplay(
output.display_id(), GetDisplayModeParams(*mode), origin)); output.display_id(), GetDisplayModeParams(*mode), origin));
else } else {
status =
proxy_->Send(new OzoneGpuMsg_DisableNativeDisplay(output.display_id())); proxy_->Send(new OzoneGpuMsg_DisableNativeDisplay(output.display_id()));
}
callback.Run(true); if (status)
configure_callback_map_[output.display_id()] = callback;
else
callback.Run(false);
} }
void NativeDisplayDelegateProxy::CreateFrameBuffer(const gfx::Size& size) { void NativeDisplayDelegateProxy::CreateFrameBuffer(const gfx::Size& size) {
...@@ -170,29 +184,36 @@ void NativeDisplayDelegateProxy::OnDeviceEvent(const DeviceEvent& event) { ...@@ -170,29 +184,36 @@ void NativeDisplayDelegateProxy::OnDeviceEvent(const DeviceEvent& event) {
break; break;
case DeviceEvent::CHANGE: case DeviceEvent::CHANGE:
VLOG(1) << "Got display changed event for " << event.path().value(); VLOG(1) << "Got display changed event for " << event.path().value();
proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays(
std::vector<DisplaySnapshot_Params>()));
break; break;
case DeviceEvent::REMOVE: case DeviceEvent::REMOVE:
VLOG(1) << "Got display removed event for " << event.path().value(); VLOG(1) << "Got display removed event for " << event.path().value();
proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(event.path())); proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(event.path()));
break; break;
} }
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
OnConfigurationChanged());
} }
void NativeDisplayDelegateProxy::OnChannelEstablished(int host_id, void NativeDisplayDelegateProxy::OnChannelEstablished(int host_id,
IPC::Sender* sender) { IPC::Sender* sender) {
std::vector<DisplaySnapshot_Params> display_params; FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
for (size_t i = 0; i < displays_.size(); ++i) OnConfigurationChanged());
display_params.push_back(GetDisplaySnapshotParams(*displays_[i]));
// Force an initial configure such that the browser process can get the actual
// state. Pass in the current display state since the GPU process may have
// crashed and we want to re-synchronize the state between processes.
proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays(display_params));
} }
void NativeDisplayDelegateProxy::OnChannelDestroyed(int host_id) { void NativeDisplayDelegateProxy::OnChannelDestroyed(int host_id) {
// If the channel got destroyed in the middle of a configuration then just
// respond with failure.
if (!get_displays_callback_.is_null()) {
get_displays_callback_.Run(std::vector<DisplaySnapshot*>());
get_displays_callback_.Reset();
}
for (const auto& pair : configure_callback_map_) {
pair.second.Run(false);
}
configure_callback_map_.clear();
} }
bool NativeDisplayDelegateProxy::OnMessageReceived( bool NativeDisplayDelegateProxy::OnMessageReceived(
...@@ -201,6 +222,7 @@ bool NativeDisplayDelegateProxy::OnMessageReceived( ...@@ -201,6 +222,7 @@ bool NativeDisplayDelegateProxy::OnMessageReceived(
IPC_BEGIN_MESSAGE_MAP(NativeDisplayDelegateProxy, message) IPC_BEGIN_MESSAGE_MAP(NativeDisplayDelegateProxy, message)
IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays, OnUpdateNativeDisplays) IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays, OnUpdateNativeDisplays)
IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured, OnDisplayConfigured)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
...@@ -209,29 +231,23 @@ bool NativeDisplayDelegateProxy::OnMessageReceived( ...@@ -209,29 +231,23 @@ bool NativeDisplayDelegateProxy::OnMessageReceived(
void NativeDisplayDelegateProxy::OnUpdateNativeDisplays( void NativeDisplayDelegateProxy::OnUpdateNativeDisplays(
const std::vector<DisplaySnapshot_Params>& displays) { const std::vector<DisplaySnapshot_Params>& displays) {
bool has_new_displays = displays.size() != displays_.size(); has_dummy_display_ = false;
if (!has_new_displays) {
for (DisplaySnapshot* display : displays_) {
auto it = std::find_if(displays.begin(), displays.end(),
FindDisplayById(display->display_id()));
if (it == displays.end()) {
has_new_displays = true;
break;
}
}
}
// If the configuration hasn't changed do not update.
if (!has_new_displays)
return;
displays_.clear(); displays_.clear();
for (size_t i = 0; i < displays.size(); ++i) for (size_t i = 0; i < displays.size(); ++i)
displays_.push_back( displays_.push_back(
new DriDisplaySnapshotProxy(displays[i], display_manager_)); new DriDisplaySnapshotProxy(displays[i], display_manager_));
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_, if (!get_displays_callback_.is_null())
OnConfigurationChanged()); get_displays_callback_.Run(displays_.get());
}
void NativeDisplayDelegateProxy::OnDisplayConfigured(int64_t display_id,
bool status) {
auto it = configure_callback_map_.find(display_id);
if (it != configure_callback_map_.end()) {
it->second.Run(status);
configure_callback_map_.erase(it);
}
} }
} // namespace ui } // namespace ui
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_PROXY_H_ #ifndef UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_PROXY_H_
#define UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_PROXY_H_ #define UI_OZONE_PLATFORM_DRI_NATIVE_DISPLAY_DELEGATE_PROXY_H_
#include <map>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "base/observer_list.h" #include "base/observer_list.h"
...@@ -67,14 +69,24 @@ class NativeDisplayDelegateProxy : public NativeDisplayDelegate, ...@@ -67,14 +69,24 @@ class NativeDisplayDelegateProxy : public NativeDisplayDelegate,
private: private:
void OnUpdateNativeDisplays( void OnUpdateNativeDisplays(
const std::vector<DisplaySnapshot_Params>& displays); const std::vector<DisplaySnapshot_Params>& displays);
void OnDisplayConfigured(int64_t display_id, bool status);
DriGpuPlatformSupportHost* proxy_; // Not owned. DriGpuPlatformSupportHost* proxy_; // Not owned.
DeviceManager* device_manager_; // Not owned. DeviceManager* device_manager_; // Not owned.
DisplayManager* display_manager_; // Not owned. DisplayManager* display_manager_; // Not owned.
// Keeps track if there is a dummy display. This happens on initialization
// when there is no connection to the GPU to update the displays.
bool has_dummy_display_;
ScopedVector<DisplaySnapshot> displays_; ScopedVector<DisplaySnapshot> displays_;
ObserverList<NativeDisplayObserver> observers_; ObserverList<NativeDisplayObserver> observers_;
GetDisplaysCallback get_displays_callback_;
// Map between display_id and the configuration callback.
std::map<int64_t, ConfigureCallback> configure_callback_map_;
DISALLOW_COPY_AND_ASSIGN(NativeDisplayDelegateProxy); DISALLOW_COPY_AND_ASSIGN(NativeDisplayDelegateProxy);
}; };
......
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