forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
delayed_scheduler.cc
107 lines (93 loc) · 3.32 KB
/
delayed_scheduler.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/slim/delayed_scheduler.h"
namespace cc::slim {
DelayedScheduler::DelayedScheduler() = default;
DelayedScheduler::~DelayedScheduler() = default;
void DelayedScheduler::Initialize(SchedulerClient* client) {
DCHECK(!client_);
DCHECK(client);
client_ = client;
}
void DelayedScheduler::OnBeginFrameFromViz(
const viz::BeginFrameArgs& begin_frame_args) {
if (!needs_begin_frame_) {
// If begin frames are not needed anymore, then just rely immediately with
// DidNotProduceFrame for all args.
if (unused_args_.IsValid()) {
SendDidNotProduceFrameAndResetArgs(unused_args_);
}
client_->SendDidNotProduceFrame(begin_frame_args);
return;
}
viz::BeginFrameArgs args;
if (unused_args_.IsValid()) {
// If there is cached args, use it and cache new args.
args = unused_args_;
unused_args_ = begin_frame_args;
} else {
// There is no existing cached args. Decide whether to begin frame with
// new args or skip and cache new args.
if (missed_composite_now_ && !is_swap_throttled_) {
// If already missed a `MaybeCompositeNow` and can produce frame now, try
// to catch up and begin frame immediately.
args = begin_frame_args;
} else {
// Cache args and skip begin frame.
unused_args_ = begin_frame_args;
}
}
if (!args.IsValid()) {
return;
}
missed_composite_now_ = false;
BeginFrameAndResetArgs(args);
}
void DelayedScheduler::OnBeginFramePausedChanged(bool paused) {
// If there are no more begin frames even when requested, then try to produce
// frame with any cached args since client probably still wants begin frames.
if (paused && unused_args_.IsValid()) {
BeginFrameAndResetArgs(unused_args_);
}
}
void DelayedScheduler::SetNeedsBeginFrame(bool needs_begin_frame) {
needs_begin_frame_ = needs_begin_frame;
if (!needs_begin_frame && unused_args_.IsValid()) {
// Make sure there are no un-acked frame when idle.
SendDidNotProduceFrameAndResetArgs(unused_args_);
}
}
void DelayedScheduler::SetIsSwapThrottled(bool is_swap_throttled) {
is_swap_throttled_ = is_swap_throttled;
// A begin frame was missed due to being throttled, begin frame immediately
// when no longer throttled.
if (!is_swap_throttled && missed_composite_now_ && unused_args_.IsValid()) {
BeginFrameAndResetArgs(unused_args_);
}
}
void DelayedScheduler::MaybeCompositeNow() {
// Begin frame immediately if possible, or mark a MaybeCompositeNow was
// missed.
if (!unused_args_.IsValid() || is_swap_throttled_) {
missed_composite_now_ = true;
return;
}
BeginFrameAndResetArgs(unused_args_);
}
void DelayedScheduler::BeginFrameAndResetArgs(viz::BeginFrameArgs& args) {
// Make a copy and clear immediately to avoid re-entrancy issues.
viz::BeginFrameArgs copy = args;
args = viz::BeginFrameArgs();
if (!client_->DoBeginFrame(copy)) {
SendDidNotProduceFrameAndResetArgs(copy);
}
}
void DelayedScheduler::SendDidNotProduceFrameAndResetArgs(
viz::BeginFrameArgs& args) {
// Make a copy and clear immediately to avoid re-entrancy issues.
viz::BeginFrameArgs copy = args;
args = viz::BeginFrameArgs();
client_->SendDidNotProduceFrame(copy);
}
} // namespace cc::slim