Make DisplayConfigureRequest own DisplayMode clones.
Prior to this change, DisplayConfigureRequest would indicate a
requested mode via a pointer to a DisplayMode owned by the corresponding
DisplaySnapshot. In order to support the virtual modes feature, it is
no longer valid to assume that a requested mode already exists by the
snapshot. This change replaces DisplayMode pointers with unique_ptrs to
enforce that DisplayConfigureRequests will always own their requested
mode.
When creating a request, modes are cloned as needed (if they already
exist on the snapshot), or created anew in the virtual case. When a
request succeeds, the newly applied mode is matched against existing
modes on the snapshot, or cloned and added to the snapshot in the
virtual case.
Bug: b:321725211
Change-Id: I16ff0a25dc1caac09ae930ca5eb5f4e17c28d039
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5606024
Reviewed-by: Gil Dekel <[email protected]>
Reviewed-by: Xiyuan Xia <[email protected]>
Commit-Queue: Andrew Wolfers <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1329024}
diff --git a/ui/display/manager/configure_displays_task.cc b/ui/display/manager/configure_displays_task.cc
index 1f59923..749d64af 100644
--- a/ui/display/manager/configure_displays_task.cc
+++ b/ui/display/manager/configure_displays_task.cc
@@ -79,8 +79,10 @@
if (request.mode == nullptr)
return;
- if (request.mode == request.display->native_mode())
+ if (request.display->native_mode() &&
+ *request.mode == *request.display->native_mode()) {
return;
+ }
LOG(ERROR) << "A mode other than the preferred mode was requested for the "
"internal display: preferred="
@@ -228,7 +230,7 @@
// After a successful configuration, the DisplaySnapshot associated with a
// request needs to have its state updated to reflect the new configuration.
void UpdateSnapshotAfterConfiguration(const DisplayConfigureRequest& request) {
- request.display->set_current_mode(request.mode);
+ request.display->set_current_mode(request.mode.get());
request.display->set_origin(request.origin);
if (request.display->IsVrrCapable()) {
request.display->set_variable_refresh_rate_state(
@@ -242,7 +244,10 @@
const DisplayMode* mode,
const gfx::Point& origin,
bool enable_vrr)
- : display(display), mode(mode), origin(origin), enable_vrr(enable_vrr) {}
+ : display(display),
+ mode(mode ? mode->Clone() : nullptr),
+ origin(origin),
+ enable_vrr(enable_vrr) {}
DisplayConfigureRequest::DisplayConfigureRequest(DisplaySnapshot* display,
const DisplayMode* mode,
@@ -252,6 +257,15 @@
origin,
/*enable_vrr=*/false) {}
+DisplayConfigureRequest::DisplayConfigureRequest(
+ const DisplayConfigureRequest& other)
+ : DisplayConfigureRequest(other.display,
+ other.mode.get(),
+ other.origin,
+ other.enable_vrr) {}
+
+DisplayConfigureRequest::~DisplayConfigureRequest() = default;
+
ConfigureDisplaysTask::ConfigureDisplaysTask(
NativeDisplayDelegate* delegate,
const std::vector<DisplayConfigureRequest>& requests,
@@ -268,7 +282,15 @@
ConfigureDisplaysTask::RequestToOriginalMode::RequestToOriginalMode(
DisplayConfigureRequest* request,
const DisplayMode* original_mode)
- : request(request), original_mode(original_mode) {}
+ : request(request),
+ original_mode(original_mode ? original_mode->Clone() : nullptr) {}
+
+ConfigureDisplaysTask::RequestToOriginalMode::RequestToOriginalMode(
+ const RequestToOriginalMode& other)
+ : RequestToOriginalMode(other.request, other.original_mode.get()) {}
+
+ConfigureDisplaysTask::RequestToOriginalMode::~RequestToOriginalMode() =
+ default;
ConfigureDisplaysTask::~ConfigureDisplaysTask() {
delegate_->RemoveObserver(this);
@@ -283,7 +305,7 @@
LogIfInvalidRequestForInternalDisplay(request);
config_requests.emplace_back(request.display->display_id(), request.origin,
- request.mode, request.enable_vrr);
+ request.mode.get(), request.enable_vrr);
if (is_first_attempt) {
const std::string uma_name_prefix = GetUmaNamePrefixForRequest(request);
@@ -325,8 +347,10 @@
PartitionRequests();
DCHECK(!pending_display_group_requests_.empty());
// Prep the first group
- for (const auto& pair : pending_display_group_requests_.front())
- pair.request->mode = pair.original_mode;
+ for (const auto& pair : pending_display_group_requests_.front()) {
+ pair.request->mode =
+ pair.original_mode ? pair.original_mode->Clone() : nullptr;
+ }
task_status_ = PARTIAL_SUCCESS;
Run();
return;
@@ -339,7 +363,7 @@
final_requests_status_.emplace_back(&request, true);
config_requests.emplace_back(request.display->display_id(), request.origin,
- request.mode, request.enable_vrr);
+ request.mode.get(), request.enable_vrr);
}
display::ModesetFlags modeset_flags{display::ModesetFlag::kCommitModeset};
@@ -366,8 +390,9 @@
// single) pending group fails. There is no point in disabling displays
// that are already disabled from previous attempts and failed to change
// mode.
- for (const auto& pair : pending_display_group_requests_.front())
- pair.request->mode = nullptr;
+ for (const auto& pair : pending_display_group_requests_.front()) {
+ pair.request->mode.reset();
+ }
task_status_ = ERROR;
}
} else {
@@ -377,7 +402,7 @@
last_successful_config_parameters_.clear();
for (const auto& request : requests_) {
last_successful_config_parameters_.emplace_back(
- request.display->display_id(), request.origin, request.mode,
+ request.display->display_id(), request.origin, request.mode.get(),
request.enable_vrr);
}
}
@@ -392,8 +417,10 @@
pending_display_group_requests_.pop();
if (!pending_display_group_requests_.empty()) {
// Prep the next group
- for (const auto& pair : pending_display_group_requests_.front())
- pair.request->mode = pair.original_mode;
+ for (const auto& pair : pending_display_group_requests_.front()) {
+ pair.request->mode =
+ pair.original_mode ? pair.original_mode->Clone() : nullptr;
+ }
Run();
return;
}
@@ -447,8 +474,8 @@
if (connector_id == requests_[j].display->base_connector_id()) {
// Disable all requests in preparation increment connector retries after
// mapping them to their original request.
- request_group.emplace_back(&requests_[j], requests_[j].mode);
- requests_[j].mode = nullptr;
+ request_group.emplace_back(&requests_[j], requests_[j].mode.get());
+ requests_[j].mode.reset();
}
}
@@ -485,7 +512,7 @@
const DisplayMode* next_mode = FindNextMode(*next_request);
if (next_mode) {
- next_request->mode = next_mode;
+ next_request->mode = next_mode->Clone();
return true;
}
}