Commit 7bb351e8 authored by Fady Samuel's avatar Fady Samuel Committed by Commit Bot

Surface Synchronization: Simplify Deadlines

This CL simplifies deadline setup in viz::Surface a bit in anticipation
for throttling of child-initiated synchronization.

Prior to this CL, a Surface did not always have a SurfaceDependencyDeadline
object. One was only available if unlimited deadlines were not specified
by command line. This made deadline logic a bit more difficult to read
in Surface.

Furthermore, UpdateActivationDependencies didn't just update dependencies,
it also resolved the FrameDeadline into a wall time deadline. This CL
splits up that responsibility into a separate object in anticipation of
adding additional functionality in UpdateActivationDependencies in another
CL.

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel
Change-Id: Ib280a25922600a36265b705bac25a820043756bf
Bug: 672962
Reviewed-on: https://chromium-review.googlesource.com/1240506
Commit-Queue: Fady Samuel <fsamuel@chromium.org>
Reviewed-by: default avatarSaman Sami <samans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594319}
parent d6605101
...@@ -50,8 +50,8 @@ Surface::~Surface() { ...@@ -50,8 +50,8 @@ Surface::~Surface() {
for (const FrameSinkId& sink_id : observed_sinks_) for (const FrameSinkId& sink_id : observed_sinks_)
surface_manager_->RemoveActivationObserver(sink_id, surface_info_.id()); surface_manager_->RemoveActivationObserver(sink_id, surface_info_.id());
if (deadline_) DCHECK(deadline_);
deadline_->Cancel(); deadline_->Cancel();
TRACE_EVENT_ASYNC_END1(TRACE_DISABLED_BY_DEFAULT("viz.surface_lifetime"), TRACE_EVENT_ASYNC_END1(TRACE_DISABLED_BY_DEFAULT("viz.surface_lifetime"),
"Surface", this, "surface_info", "Surface", this, "surface_info",
...@@ -77,8 +77,8 @@ void Surface::Reset(base::WeakPtr<SurfaceClient> client) { ...@@ -77,8 +77,8 @@ void Surface::Reset(base::WeakPtr<SurfaceClient> client) {
void Surface::InheritActivationDeadlineFrom(Surface* surface) { void Surface::InheritActivationDeadlineFrom(Surface* surface) {
TRACE_EVENT1("viz", "Surface::InheritActivationDeadlineFrom", "FrameSinkId", TRACE_EVENT1("viz", "Surface::InheritActivationDeadlineFrom", "FrameSinkId",
surface_id().frame_sink_id().ToString()); surface_id().frame_sink_id().ToString());
if (!deadline_ || !surface->deadline_) DCHECK(deadline_);
return; DCHECK(surface->deadline_);
deadline_->InheritFrom(*surface->deadline_); deadline_->InheritFrom(*surface->deadline_);
} }
...@@ -216,14 +216,13 @@ bool Surface::QueueFrame( ...@@ -216,14 +216,13 @@ bool Surface::QueueFrame(
std::move(pending_frame_data_); std::move(pending_frame_data_);
pending_frame_data_.reset(); pending_frame_data_.reset();
FrameDeadline deadline = UpdateActivationDependencies(frame); UpdateActivationDependencies(frame);
// Receive and track the resources referenced from the CompositorFrame // Receive and track the resources referenced from the CompositorFrame
// regardless of whether it's pending or active. // regardless of whether it's pending or active.
surface_client_->ReceiveFromChild(frame.resource_list); surface_client_->ReceiveFromChild(frame.resource_list);
if (activation_dependencies_.empty() || if (activation_dependencies_.empty()) {
(deadline_ && !deadline.deadline_in_frames())) {
// If there are no blockers, then immediately activate the frame. // If there are no blockers, then immediately activate the frame.
ActivateFrame( ActivateFrame(
FrameData(std::move(frame), frame_index, std::move(presented_callback)), FrameData(std::move(frame), frame_index, std::move(presented_callback)),
...@@ -233,8 +232,9 @@ bool Surface::QueueFrame( ...@@ -233,8 +232,9 @@ bool Surface::QueueFrame(
FrameData(std::move(frame), frame_index, std::move(presented_callback)); FrameData(std::move(frame), frame_index, std::move(presented_callback));
RejectCompositorFramesToFallbackSurfaces(); RejectCompositorFramesToFallbackSurfaces();
// If the deadline is in the past, then we will activate immediately. // If the deadline is in the past, then the CompositorFrame will activate
if (!deadline_ || deadline_->Set(deadline)) { // immediately.
if (deadline_->Set(ResolveFrameDeadline(frame))) {
// Ask the SurfaceDependencyTracker to inform |this| when its dependencies // Ask the SurfaceDependencyTracker to inform |this| when its dependencies
// are resolved. // are resolved.
surface_manager_->dependency_tracker()->RequestSurfaceResolution(this); surface_manager_->dependency_tracker()->RequestSurfaceResolution(this);
...@@ -339,8 +339,8 @@ void Surface::ActivatePendingFrame(base::Optional<base::TimeDelta> duration) { ...@@ -339,8 +339,8 @@ void Surface::ActivatePendingFrame(base::Optional<base::TimeDelta> duration) {
FrameData frame_data = std::move(*pending_frame_data_); FrameData frame_data = std::move(*pending_frame_data_);
pending_frame_data_.reset(); pending_frame_data_.reset();
DCHECK(!duration || !deadline_ || !deadline_->has_deadline()); DCHECK(!duration || !deadline_->has_deadline());
if (!duration && deadline_) if (!duration)
duration = deadline_->Cancel(); duration = deadline_->Cancel();
ActivateFrame(std::move(frame_data), duration); ActivateFrame(std::move(frame_data), duration);
...@@ -456,22 +456,28 @@ void Surface::ActivateFrame(FrameData frame_data, ...@@ -456,22 +456,28 @@ void Surface::ActivateFrame(FrameData frame_data,
surface_client_->OnFrameTokenChanged(metadata.frame_token); surface_client_->OnFrameTokenChanged(metadata.frame_token);
} }
FrameDeadline Surface::UpdateActivationDependencies( FrameDeadline Surface::ResolveFrameDeadline(
const CompositorFrame& current_frame) { const CompositorFrame& current_frame) {
const base::Optional<uint32_t>& default_deadline = const base::Optional<uint32_t>& default_deadline =
surface_manager_->activation_deadline_in_frames(); surface_manager_->activation_deadline_in_frames();
FrameDeadline deadline = current_frame.metadata.deadline; const FrameDeadline& deadline = current_frame.metadata.deadline;
uint32_t deadline_in_frames = deadline.deadline_in_frames(); uint32_t deadline_in_frames = deadline.deadline_in_frames();
if (default_deadline && deadline.use_default_lower_bound_deadline())
deadline_in_frames = std::max(deadline_in_frames, *default_deadline);
deadline = FrameDeadline(deadline.frame_start_time(), deadline_in_frames, // If no default deadline is available then all deadlines are treated as
deadline.frame_interval(), // effectively infinite deadlines.
false /* use_default_lower_bound_deadline */); if (!default_deadline || deadline.use_default_lower_bound_deadline()) {
deadline_in_frames = std::max(
deadline_in_frames,
default_deadline.value_or(std::numeric_limits<uint32_t>::max()));
}
bool track_dependencies = !default_deadline || deadline_in_frames > 0; return FrameDeadline(deadline.frame_start_time(), deadline_in_frames,
deadline.frame_interval(),
false /* use_default_lower_bound_deadline */);
}
void Surface::UpdateActivationDependencies(
const CompositorFrame& current_frame) {
base::flat_map<FrameSinkId, SequenceNumbers> new_frame_sink_id_dependencies; base::flat_map<FrameSinkId, SequenceNumbers> new_frame_sink_id_dependencies;
base::flat_set<SurfaceId> new_activation_dependencies; base::flat_set<SurfaceId> new_activation_dependencies;
...@@ -482,9 +488,6 @@ FrameDeadline Surface::UpdateActivationDependencies( ...@@ -482,9 +488,6 @@ FrameDeadline Surface::UpdateActivationDependencies(
// the display compositor, then it blocks this frame. // the display compositor, then it blocks this frame.
if (!dependency || !dependency->HasActiveFrame()) { if (!dependency || !dependency->HasActiveFrame()) {
new_activation_dependencies.insert(surface_id); new_activation_dependencies.insert(surface_id);
if (!track_dependencies)
continue;
TRACE_EVENT_WITH_FLOW2( TRACE_EVENT_WITH_FLOW2(
TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"), TRACE_DISABLED_BY_DEFAULT("viz.surface_id_flow"),
"LocalSurfaceId.Embed.Flow", "LocalSurfaceId.Embed.Flow",
...@@ -516,16 +519,8 @@ FrameDeadline Surface::UpdateActivationDependencies( ...@@ -516,16 +519,8 @@ FrameDeadline Surface::UpdateActivationDependencies(
// map. // map.
ComputeChangeInDependencies(new_frame_sink_id_dependencies); ComputeChangeInDependencies(new_frame_sink_id_dependencies);
if (track_dependencies) { activation_dependencies_ = std::move(new_activation_dependencies);
activation_dependencies_ = std::move(new_activation_dependencies);
} else {
// If the deadline is zero, then all dependencies are late.
activation_dependencies_.clear();
late_activation_dependencies_ = std::move(new_activation_dependencies);
}
frame_sink_id_dependencies_ = std::move(new_frame_sink_id_dependencies); frame_sink_id_dependencies_ = std::move(new_frame_sink_id_dependencies);
return deadline;
} }
void Surface::ComputeChangeInDependencies( void Surface::ComputeChangeInDependencies(
......
...@@ -262,11 +262,15 @@ class VIZ_SERVICE_EXPORT Surface final : public SurfaceDeadlineClient { ...@@ -262,11 +262,15 @@ class VIZ_SERVICE_EXPORT Surface final : public SurfaceDeadlineClient {
void ActivateFrame(FrameData frame_data, void ActivateFrame(FrameData frame_data,
base::Optional<base::TimeDelta> duration); base::Optional<base::TimeDelta> duration);
// Resolve the activation deadline specified by |current_frame| into a wall
// time to be used by SurfaceDependencyDeadline.
FrameDeadline ResolveFrameDeadline(const CompositorFrame& current_frame);
// Updates the set of unresolved activation dependenices of the // Updates the set of unresolved activation dependenices of the
// |current_frame|. If the deadline requested by the frame is 0 then no // |current_frame|. If the deadline requested by the frame is 0 then no
// dependencies will be added even if they're not yet available. // dependencies will be added even if they're not yet available.
FrameDeadline UpdateActivationDependencies( void UpdateActivationDependencies(const CompositorFrame& current_frame);
const CompositorFrame& current_frame);
void ComputeChangeInDependencies( void ComputeChangeInDependencies(
const base::flat_map<FrameSinkId, SequenceNumbers>& new_dependencies); const base::flat_map<FrameSinkId, SequenceNumbers>& new_dependencies);
......
...@@ -29,7 +29,6 @@ SurfaceDependencyDeadline::~SurfaceDependencyDeadline() { ...@@ -29,7 +29,6 @@ SurfaceDependencyDeadline::~SurfaceDependencyDeadline() {
} }
bool SurfaceDependencyDeadline::Set(const FrameDeadline& frame_deadline) { bool SurfaceDependencyDeadline::Set(const FrameDeadline& frame_deadline) {
DCHECK_GT(frame_deadline.deadline_in_frames(), 0u);
CancelInternal(false); CancelInternal(false);
start_time_ = frame_deadline.frame_start_time(); start_time_ = frame_deadline.frame_start_time();
deadline_ = start_time_ + frame_deadline.deadline_in_frames() * deadline_ = start_time_ + frame_deadline.deadline_in_frames() *
......
...@@ -117,12 +117,8 @@ Surface* SurfaceManager::CreateSurface( ...@@ -117,12 +117,8 @@ Surface* SurfaceManager::CreateSurface(
if (it == surface_map_.end()) { if (it == surface_map_.end()) {
std::unique_ptr<Surface> surface = std::make_unique<Surface>( std::unique_ptr<Surface> surface = std::make_unique<Surface>(
surface_info, this, surface_client, needs_sync_tokens); surface_info, this, surface_client, needs_sync_tokens);
// If no default deadline is specified then don't track deadlines. surface->SetDependencyDeadline(std::make_unique<SurfaceDependencyDeadline>(
if (activation_deadline_in_frames_) { surface.get(), begin_frame_source, tick_clock_));
surface->SetDependencyDeadline(
std::make_unique<SurfaceDependencyDeadline>(
surface.get(), begin_frame_source, tick_clock_));
}
surface_map_[surface_info.id()] = std::move(surface); surface_map_[surface_info.id()] = std::move(surface);
// We can get into a situation where multiple CompositorFrames arrive for a // We can get into a situation where multiple CompositorFrames arrive for a
// FrameSink before the client can add any references for the frame. When // FrameSink before the client can add any references for the frame. When
......
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