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)
// Trigger a display reconfiguration. OzoneHostMsg_UpdateNativeDisplays will be
// sent as a response.
// The |displays| parameter will hold a list of last known displays.
IPC_MESSAGE_CONTROL1(OzoneGpuMsg_RefreshNativeDisplays,
std::vector<ui::DisplaySnapshot_Params> /* displays */)
IPC_MESSAGE_CONTROL0(OzoneGpuMsg_RefreshNativeDisplays)
// Configure a display with the specified mode at the specified location.
IPC_MESSAGE_CONTROL3(OzoneGpuMsg_ConfigureNativeDisplay,
......@@ -112,3 +110,7 @@ IPC_MESSAGE_CONTROL0(OzoneGpuMsg_RelinquishDisplayControl)
// Updates the list of active displays.
IPC_MESSAGE_CONTROL1(OzoneHostMsg_UpdateNativeDisplays,
std::vector<ui::DisplaySnapshot_Params>)
IPC_MESSAGE_CONTROL2(OzoneHostMsg_DisplayConfigured,
int64_t /* display_id */,
bool /* status */)
......@@ -119,27 +119,10 @@ void DriGpuPlatformSupport::OnForceDPMSOn() {
ndd_->ForceDPMSOn();
}
void DriGpuPlatformSupport::OnRefreshNativeDisplays(
const std::vector<DisplaySnapshot_Params>& cached_displays) {
void DriGpuPlatformSupport::OnRefreshNativeDisplays() {
std::vector<DisplaySnapshot_Params> displays;
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)
displays.push_back(GetDisplaySnapshotParams(*native_displays[i]));
......@@ -181,7 +164,8 @@ void DriGpuPlatformSupport::OnConfigureNativeDisplay(
return;
}
ndd_->Configure(*display, mode, origin);
sender_->Send(new OzoneHostMsg_DisplayConfigured(
id, ndd_->Configure(*display, mode, origin)));
}
void DriGpuPlatformSupport::OnDisableNativeDisplay(int64_t id) {
......
......@@ -64,8 +64,7 @@ class DriGpuPlatformSupport : public GpuPlatformSupport {
// Display related IPC handlers.
void OnForceDPMSOn();
void OnRefreshNativeDisplays(
const std::vector<DisplaySnapshot_Params>& cached_displays);
void OnRefreshNativeDisplays();
void OnConfigureNativeDisplay(int64_t id,
const DisplayMode_Params& mode,
const gfx::Point& origin);
......
......@@ -87,7 +87,7 @@ bool DriGpuPlatformSupportHost::Send(IPC::Message* message) {
if (sender_)
return sender_->Send(message);
return true;
return false;
}
void DriGpuPlatformSupportHost::SetHardwareCursor(
......
......@@ -47,7 +47,8 @@ NativeDisplayDelegateProxy::NativeDisplayDelegateProxy(
DisplayManager* display_manager)
: proxy_(proxy),
device_manager_(device_manager),
display_manager_(display_manager) {
display_manager_(display_manager),
has_dummy_display_(false) {
proxy_->RegisterHandler(this);
}
......@@ -64,8 +65,10 @@ void NativeDisplayDelegateProxy::Initialize() {
return;
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_));
has_dummy_display_ = true;
}
}
void NativeDisplayDelegateProxy::GrabServer() {
......@@ -98,9 +101,10 @@ void NativeDisplayDelegateProxy::ForceDPMSOn() {
void NativeDisplayDelegateProxy::GetDisplays(
const GetDisplaysCallback& callback) {
// GetDisplays() is supposed to force a refresh of the display list.
proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays(
std::vector<DisplaySnapshot_Params>()));
callback.Run(displays_.get());
if (proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays()))
get_displays_callback_ = callback;
else
callback.Run(displays_.get());
}
void NativeDisplayDelegateProxy::AddMode(const DisplaySnapshot& output,
......@@ -111,14 +115,24 @@ void NativeDisplayDelegateProxy::Configure(const DisplaySnapshot& output,
const DisplayMode* mode,
const gfx::Point& origin,
const ConfigureCallback& callback) {
// TODO(dnicoara) Should handle an asynchronous response.
if (mode)
proxy_->Send(new OzoneGpuMsg_ConfigureNativeDisplay(
if (has_dummy_display_) {
callback.Run(true);
return;
}
bool status = false;
if (mode) {
status = proxy_->Send(new OzoneGpuMsg_ConfigureNativeDisplay(
output.display_id(), GetDisplayModeParams(*mode), origin));
else
proxy_->Send(new OzoneGpuMsg_DisableNativeDisplay(output.display_id()));
} else {
status =
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) {
......@@ -170,29 +184,36 @@ void NativeDisplayDelegateProxy::OnDeviceEvent(const DeviceEvent& event) {
break;
case DeviceEvent::CHANGE:
VLOG(1) << "Got display changed event for " << event.path().value();
proxy_->Send(new OzoneGpuMsg_RefreshNativeDisplays(
std::vector<DisplaySnapshot_Params>()));
break;
case DeviceEvent::REMOVE:
VLOG(1) << "Got display removed event for " << event.path().value();
proxy_->Send(new OzoneGpuMsg_RemoveGraphicsDevice(event.path()));
break;
}
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
OnConfigurationChanged());
}
void NativeDisplayDelegateProxy::OnChannelEstablished(int host_id,
IPC::Sender* sender) {
std::vector<DisplaySnapshot_Params> display_params;
for (size_t i = 0; i < displays_.size(); ++i)
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));
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
OnConfigurationChanged());
}
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(
......@@ -201,6 +222,7 @@ bool NativeDisplayDelegateProxy::OnMessageReceived(
IPC_BEGIN_MESSAGE_MAP(NativeDisplayDelegateProxy, message)
IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays, OnUpdateNativeDisplays)
IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured, OnDisplayConfigured)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
......@@ -209,29 +231,23 @@ bool NativeDisplayDelegateProxy::OnMessageReceived(
void NativeDisplayDelegateProxy::OnUpdateNativeDisplays(
const std::vector<DisplaySnapshot_Params>& displays) {
bool has_new_displays = displays.size() != displays_.size();
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;
has_dummy_display_ = false;
displays_.clear();
for (size_t i = 0; i < displays.size(); ++i)
displays_.push_back(
new DriDisplaySnapshotProxy(displays[i], display_manager_));
FOR_EACH_OBSERVER(NativeDisplayObserver, observers_,
OnConfigurationChanged());
if (!get_displays_callback_.is_null())
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
......@@ -5,6 +5,8 @@
#ifndef 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/memory/scoped_vector.h"
#include "base/observer_list.h"
......@@ -67,14 +69,24 @@ class NativeDisplayDelegateProxy : public NativeDisplayDelegate,
private:
void OnUpdateNativeDisplays(
const std::vector<DisplaySnapshot_Params>& displays);
void OnDisplayConfigured(int64_t display_id, bool status);
DriGpuPlatformSupportHost* proxy_; // Not owned.
DeviceManager* device_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_;
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);
};
......
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