Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2672)

Unified Diff: cc/surfaces/display_scheduler.cc

Issue 2411793008: Adds BeginFrameControl via DevTools.
Patch Set: BFC prototype v2 with allow_latency_opts and waiting for BFOs. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/surfaces/display_scheduler.h ('k') | cc/surfaces/display_scheduler_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/surfaces/display_scheduler.cc
diff --git a/cc/surfaces/display_scheduler.cc b/cc/surfaces/display_scheduler.cc
index 229bc6306ccb1ecf4af4056e074b35a56ac9f429..3728f043984473a5831743acb5937345861e5691 100644
--- a/cc/surfaces/display_scheduler.cc
+++ b/cc/surfaces/display_scheduler.cc
@@ -9,14 +9,15 @@
#include "base/auto_reset.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
+#include "cc/output/begin_frame_args.h"
#include "cc/output/output_surface.h"
namespace cc {
-DisplayScheduler::DisplayScheduler(BeginFrameSource* begin_frame_source,
- base::SingleThreadTaskRunner* task_runner,
+DisplayScheduler::DisplayScheduler(base::SingleThreadTaskRunner* task_runner,
int max_pending_swaps)
- : begin_frame_source_(begin_frame_source),
+ : client_(nullptr),
+ begin_frame_source_(nullptr),
task_runner_(task_runner),
inside_surface_damaged_(false),
visible_(false),
@@ -44,6 +45,13 @@ void DisplayScheduler::SetClient(DisplaySchedulerClient* client) {
client_ = client;
}
+void DisplayScheduler::SetBeginFrameSource(
+ DisplayBeginFrameSource* begin_frame_source) {
+ begin_frame_source_ = begin_frame_source;
+ begin_frame_source_->SetClient(this);
+ DCHECK(begin_frame_source_->GetTargetSource());
+}
+
void DisplayScheduler::SetVisible(bool visible) {
if (visible_ == visible)
return;
@@ -70,7 +78,7 @@ void DisplayScheduler::ForceImmediateSwapIfPossible() {
bool in_begin = inside_begin_frame_deadline_interval_;
AttemptDrawAndSwap();
if (in_begin)
- begin_frame_source_->DidFinishFrame(this, 0);
+ begin_frame_source_->GetTargetSource()->DidFinishFrame(this, 0);
}
void DisplayScheduler::DisplayResized() {
@@ -108,9 +116,21 @@ void DisplayScheduler::SurfaceDamaged(const SurfaceId& surface_id) {
} else {
child_surface_ids_damaged_.insert(surface_id);
- // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts.
- all_active_child_surfaces_ready_to_draw_ = base::STLIncludes(
- child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_);
+ if (BeginFrameForcesDamage()) {
+ // Wait for all BeginFrameObservers to call DidFinishFrame() before
+ // triggering an early deadline. We do this only if we know that the
+ // BeginFrame should cause damage on all active surfaces, because BFOs
+ // currently may not call DidFinishFrame() when the BeginFrame does not
+ // cause any damage to their surface.
+ // TODO(eseckler): Make this the default heuristic once we can guarantee
+ // observers to call DidFinishFrame() for every frame.
+ all_active_child_surfaces_ready_to_draw_ =
+ begin_frame_source_->AllObserversFinishedFrame();
+ } else {
+ // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts.
+ all_active_child_surfaces_ready_to_draw_ = base::STLIncludes(
+ child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_);
+ }
}
StartObservingBeginFrames();
@@ -188,21 +208,33 @@ bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
current_begin_frame_args_.deadline -=
BeginFrameArgs::DefaultEstimatedParentDrawTime();
inside_begin_frame_deadline_interval_ = true;
- ScheduleBeginFrameDeadline();
+ if (BeginFrameForcesDamage()) {
+ // We know every surface that receives the BeginFrame will be damaged, so we
+ // wait until all BeginFrameObservers have responded instead of waiting for
+ // child_surface_ids_to_expect_damage_from_.
+ expect_damage_from_root_surface_ = false;
+ all_active_child_surfaces_ready_to_draw_ =
+ begin_frame_source_->AllObserversFinishedFrame();
+ }
+
+ ScheduleBeginFrameDeadline();
return true;
}
void DisplayScheduler::StartObservingBeginFrames() {
if (!observing_begin_frame_source_ && ShouldDraw()) {
- begin_frame_source_->AddObserver(this);
+ // We don't want to wait for our own DidFinishFrame() when using
+ // begin_frame_source_->AllObserversFinishedFrame(), so we add ourselves to
+ // the target source directly.
+ begin_frame_source_->GetTargetSource()->AddObserver(this);
observing_begin_frame_source_ = true;
}
}
void DisplayScheduler::StopObservingBeginFrames() {
if (observing_begin_frame_source_) {
- begin_frame_source_->RemoveObserver(this);
+ begin_frame_source_->GetTargetSource()->RemoveObserver(this);
observing_begin_frame_source_ = false;
// A missed BeginFrame may be queued, so drop that too if we're going to
@@ -217,6 +249,10 @@ bool DisplayScheduler::ShouldDraw() {
return needs_draw_ && !output_surface_lost_ && visible_;
}
+bool DisplayScheduler::BeginFrameForcesDamage() const {
+ return !current_begin_frame_args_.allow_latency_optimizations;
+}
+
void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) {
// BeginFrameSources used with DisplayScheduler do not make use of this
// feature.
@@ -224,6 +260,24 @@ void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) {
NOTIMPLEMENTED();
}
+void DisplayScheduler::ObserverStatusChanged() {
+ // If we're using the BeginFrameObservers to determine when all active
+ // surfaces have been damaged, we may need to update the deadline.
+ if (BeginFrameForcesDamage()) {
+ all_active_child_surfaces_ready_to_draw_ =
+ begin_frame_source_->AllObserversFinishedFrame();
+ ScheduleBeginFrameDeadline();
+ }
+}
+
+void DisplayScheduler::BeginFrameSourceSwapping(BeginFrameSource* new_source) {
+ DCHECK(new_source);
+ if (observing_begin_frame_source_) {
+ begin_frame_source_->GetTargetSource()->RemoveObserver(this);
+ new_source->AddObserver(this);
+ }
+}
+
base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() {
if (output_surface_lost_) {
TRACE_EVENT_INSTANT0("cc", "Lost output surface", TRACE_EVENT_SCOPE_THREAD);
@@ -236,7 +290,10 @@ base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() {
current_begin_frame_args_.interval;
}
- if (!needs_draw_) {
+ // Allow an immediate deadline even if there's no damage and we know that
+ // no BeginFrameObservers are active.
+ if (!needs_draw_ &&
+ !(BeginFrameForcesDamage() && all_active_child_surfaces_ready_to_draw_)) {
TRACE_EVENT_INSTANT0("cc", "No damage yet", TRACE_EVENT_SCOPE_THREAD);
return current_begin_frame_args_.frame_time +
current_begin_frame_args_.interval;
@@ -351,7 +408,7 @@ void DisplayScheduler::OnBeginFrameDeadline() {
TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline");
AttemptDrawAndSwap();
- begin_frame_source_->DidFinishFrame(this, 0);
+ begin_frame_source_->GetTargetSource()->DidFinishFrame(this, 0);
}
void DisplayScheduler::DidSwapBuffers() {
« no previous file with comments | « cc/surfaces/display_scheduler.h ('k') | cc/surfaces/display_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698