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

Unified Diff: cc/surfaces/display_scheduler.cc

Issue 2183333003: cc: Post the missed BeginFrame to a new stack (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: post-swapcomplete: ignoreresult Created 4 years, 5 months 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
Index: cc/surfaces/display_scheduler.cc
diff --git a/cc/surfaces/display_scheduler.cc b/cc/surfaces/display_scheduler.cc
index d26d1b6306973debcf5abde447dfa0c928b981f7..7c662340948954c78eb9cb9696df358819b6cd28 100644
--- a/cc/surfaces/display_scheduler.cc
+++ b/cc/surfaces/display_scheduler.cc
@@ -97,7 +97,12 @@ void DisplayScheduler::SurfaceDamaged(const SurfaceId& surface_id) {
if (!output_surface_lost_ && !observing_begin_frame_source_) {
observing_begin_frame_source_ = true;
+ // When we call AddObserver() this will cause a missed BeginFrame to
+ // occur. We need to detect this and not process it immediately in the
+ // same call stack.
+ inside_add_observer_ = true;
sunnyps 2016/07/27 02:00:14 nit: base::AutoReset<bool> mark_inside(&inside_add
danakj 2016/07/27 02:19:04 Done.
begin_frame_source_->AddObserver(this);
+ inside_add_observer_ = false;
}
ScheduleBeginFrameDeadline();
@@ -138,6 +143,24 @@ bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(),
"now", now);
+ if (inside_add_observer_) {
+ // Repost this so that we don't run a missed BeginFrame on the same
+ // callstack. Otherwise we end up running unexpected scheduler actions
+ // immediately while inside some other action (such as submitting a frame
+ // for a SurfaceFactory).
+ DCHECK_EQ(args.type, BeginFrameArgs::MISSED);
+ DCHECK(missed_begin_frame_task_.IsCancelled());
+ missed_begin_frame_task_.Reset(base::Bind(
+ base::IgnoreResult(&DisplayScheduler::OnBeginFrameDerivedImpl),
+ weak_ptr_factory_.GetWeakPtr(), args));
+ task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
+ return true;
+ } else {
+ // If we get another BeginFrame before a posted missed frame, just drop the
+ // missed frame.
+ missed_begin_frame_task_.Cancel();
+ }
+
// If we get another BeginFrame before the previous deadline,
// synchronously trigger the previous deadline before progressing.
if (inside_begin_frame_deadline_interval_) {

Powered by Google App Engine
This is Rietveld 408576698