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

Side by Side Diff: cc/surfaces/surface_dependency_tracker.cc

Issue 2789163002: [cc] Acknowledge BeginFrames in SurfaceDependencyTracker. (Closed)
Patch Set: . Created 3 years, 8 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 unified diff | Download patch
« no previous file with comments | « cc/surfaces/surface_dependency_tracker.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/surfaces/surface_dependency_tracker.h" 5 #include "cc/surfaces/surface_dependency_tracker.h"
6 6
7 #include "cc/surfaces/surface.h" 7 #include "cc/surfaces/surface.h"
8 #include "cc/surfaces/surface_info.h" 8 #include "cc/surfaces/surface_info.h"
9 #include "cc/surfaces/surface_manager.h" 9 #include "cc/surfaces/surface_manager.h"
10 10
11 namespace cc { 11 namespace cc {
12 12
13 namespace { 13 namespace {
14 constexpr uint32_t kMaxBeginFrameCount = 4; 14 constexpr uint32_t kMaxBeginFrameCount = 4;
15 } 15 }
16 16
17 SurfaceDependencyTracker::SurfaceDependencyTracker( 17 SurfaceDependencyTracker::SurfaceDependencyTracker(
18 SurfaceManager* surface_manager, 18 SurfaceManager* surface_manager,
19 BeginFrameSource* begin_frame_source) 19 BeginFrameSource* begin_frame_source)
20 : surface_manager_(surface_manager), 20 : surface_manager_(surface_manager),
21 begin_frame_source_(begin_frame_source) { 21 begin_frame_source_(begin_frame_source) {
22 surface_manager_->AddObserver(this); 22 surface_manager_->AddObserver(this);
23 begin_frame_source_->AddObserver(this);
24 } 23 }
25 24
26 SurfaceDependencyTracker::~SurfaceDependencyTracker() { 25 SurfaceDependencyTracker::~SurfaceDependencyTracker() {
27 surface_manager_->RemoveObserver(this); 26 surface_manager_->RemoveObserver(this);
28 begin_frame_source_->RemoveObserver(this);
29 for (Surface* pending_surface : pending_surfaces_) 27 for (Surface* pending_surface : pending_surfaces_)
30 pending_surface->RemoveObserver(this); 28 pending_surface->RemoveObserver(this);
31 pending_surfaces_.clear(); 29 pending_surfaces_.clear();
30 UpdateNeedsBeginFrames(); // Stop observing the BeginFrameSource.
32 } 31 }
33 32
34 void SurfaceDependencyTracker::RequestSurfaceResolution(Surface* surface) { 33 void SurfaceDependencyTracker::RequestSurfaceResolution(Surface* surface) {
35 DCHECK(surface->HasPendingFrame()); 34 DCHECK(surface->HasPendingFrame());
36 35
37 const CompositorFrame& pending_frame = surface->GetPendingFrame(); 36 const CompositorFrame& pending_frame = surface->GetPendingFrame();
38 bool needs_begin_frame = 37 bool needs_deadline = pending_frame.metadata.can_activate_before_dependencies;
39 pending_frame.metadata.can_activate_before_dependencies;
40 38
41 // Referenced surface IDs that aren't currently known to the surface manager 39 // Referenced surface IDs that aren't currently known to the surface manager
42 // or do not have an active CompsotiorFrame block this frame. 40 // or do not have an active CompsotiorFrame block this frame.
43 for (const SurfaceId& surface_id : 41 for (const SurfaceId& surface_id :
44 pending_frame.metadata.referenced_surfaces) { 42 pending_frame.metadata.referenced_surfaces) {
45 Surface* surface_dependency = surface_manager_->GetSurfaceForId(surface_id); 43 Surface* surface_dependency = surface_manager_->GetSurfaceForId(surface_id);
46 if (!surface_dependency || !surface_dependency->HasActiveFrame()) 44 if (!surface_dependency || !surface_dependency->HasActiveFrame())
47 blocked_surfaces_[surface_id].insert(surface); 45 blocked_surfaces_[surface_id].insert(surface);
48 } 46 }
49 47
50 if (!pending_surfaces_.count(surface)) { 48 if (!pending_surfaces_.count(surface)) {
51 surface->AddObserver(this); 49 surface->AddObserver(this);
52 pending_surfaces_.insert(surface); 50 pending_surfaces_.insert(surface);
53 } 51 }
54 52
55 if (needs_begin_frame && !frames_since_deadline_set_) 53 if (needs_deadline && !frames_since_deadline_set_)
56 frames_since_deadline_set_ = 0; 54 frames_since_deadline_set_ = 0;
55
56 UpdateNeedsBeginFrames(); // |pending_surfaces_| changed.
57 }
58
59 void SurfaceDependencyTracker::UpdateNeedsBeginFrames() {
60 // We observe while there are pending surfaces, even if we don't have a
61 // deadline set. This way, we can send BeginFrameAcks on behalf of the
62 // pending CompositorFrames.
63 bool needs_begin_frames = !pending_surfaces_.empty();
64
65 if (needs_begin_frames_ == needs_begin_frames)
66 return;
67 needs_begin_frames_ = needs_begin_frames;
68
69 if (needs_begin_frames_)
70 begin_frame_source_->AddObserver(this);
71 else
72 begin_frame_source_->RemoveObserver(this);
57 } 73 }
58 74
59 void SurfaceDependencyTracker::OnBeginFrame(const BeginFrameArgs& args) { 75 void SurfaceDependencyTracker::OnBeginFrame(const BeginFrameArgs& args) {
76 // We only acknowledge the BeginFrame if and when all pending frames have
77 // been activated. While there are pending frames, we will not acknowledge the
78 // BeginFrame. This way, we indicate to the BeginFrameSource that we are still
79 // waiting on blockers to resolve and that the
80 // |latest_confirmed_sequence_number| of each pending frame is not integrated
81 // into any display frame produced before their activation.
82 //
83 // While we are not acknowledging, the BeginFrameSource will use the sequence
84 // number of the last BeginFrame that we did not receive as our
85 // latest_confirmed_sequence_number. This may not be completely accurate (a
86 // pending frame may include older updates), but it is as good as we can get,
87 // since we cannot retroactively unconfirm BeginFrames that we didn't receive.
88
60 // If no deadline is set then we have nothing to do. 89 // If no deadline is set then we have nothing to do.
61 if (!frames_since_deadline_set_) 90 if (!frames_since_deadline_set_)
62 return; 91 return;
63 92
93 if (args.source_id == last_begin_frame_args_.source_id &&
94 args.sequence_number == last_begin_frame_args_.sequence_number) {
95 // We've seen this BeginFrame already.
96 return;
97 }
98
64 // TODO(fsamuel, kylechar): We have a single global deadline here. We should 99 // TODO(fsamuel, kylechar): We have a single global deadline here. We should
65 // scope deadlines to surface subtrees. We cannot do that until 100 // scope deadlines to surface subtrees. We cannot do that until
66 // SurfaceReferences have been fully implemented 101 // SurfaceReferences have been fully implemented
67 // (see https://crbug.com/689719). 102 // (see https://crbug.com/689719).
68 last_begin_frame_args_ = args; 103 last_begin_frame_args_ = args;
69 // Nothing to do if we haven't hit a deadline yet. 104 // Nothing to do if we haven't hit a deadline yet.
70 if (++(*frames_since_deadline_set_) != kMaxBeginFrameCount) 105 if (++(*frames_since_deadline_set_) != kMaxBeginFrameCount)
71 return; 106 return;
72 107
73 // Activate all surfaces that respect the deadline. 108 // Activate all surfaces that respect the deadline.
74 PendingSurfaceSet pending_surfaces(pending_surfaces_); 109 PendingSurfaceSet pending_surfaces(pending_surfaces_);
75 for (Surface* pending_surface : pending_surfaces) 110 for (Surface* pending_surface : pending_surfaces)
76 pending_surface->ActivatePendingFrameForDeadline(); 111 pending_surface->ActivatePendingFrameForDeadline();
77 112
78 frames_since_deadline_set_.reset(); 113 frames_since_deadline_set_.reset();
79 } 114 }
80 115
81 const BeginFrameArgs& SurfaceDependencyTracker::LastUsedBeginFrameArgs() const { 116 const BeginFrameArgs& SurfaceDependencyTracker::LastUsedBeginFrameArgs() const {
82 return last_begin_frame_args_; 117 // Return invalid args, so that we receive the same BeginFrame multiple times
118 // if we start observing BeginFrames again during the same BeginFrame: Even if
119 // we already received and acknowledged a BeginFrame before, we want to
120 // acknowledge it again on behalf of any newly added pending surfaces.
brianderson 2017/04/04 00:29:19 I'm not familiar with SurfaceDependencyTracker. Wh
Eric Seckler 2017/04/04 08:36:45 I was erring on the side of caution, i.e. not assu
121 static BeginFrameArgs args;
Fady Samuel 2017/04/03 19:03:02 This seems kinda icky... What's wrong with always
Eric Seckler 2017/04/04 08:36:45 If we always observe, we have the problem that we
122 return args;
83 } 123 }
84 124
85 void SurfaceDependencyTracker::OnBeginFrameSourcePausedChanged(bool paused) {} 125 void SurfaceDependencyTracker::OnBeginFrameSourcePausedChanged(bool paused) {}
86 126
127 void SurfaceDependencyTracker::AcknowledgeLastBeginFrame() {
128 DCHECK(needs_begin_frames_);
129 DCHECK(pending_surfaces_.empty());
Fady Samuel 2017/04/03 19:03:02 This makes me kind of sad...but maybe it's OK for
Eric Seckler 2017/04/04 08:36:45 Yeah. Added one. FWIW, I'm going to try out tracki
130
131 // Some clients submit CompositorFrames without prior BeginFrames.
132 if (!last_begin_frame_args_.IsValid())
133 return;
134
135 begin_frame_source_->DidFinishFrame(
136 this, BeginFrameAck(last_begin_frame_args_.source_id,
137 last_begin_frame_args_.sequence_number,
138 last_begin_frame_args_.sequence_number, true));
139 }
140
87 void SurfaceDependencyTracker::OnReferencedSurfacesChanged( 141 void SurfaceDependencyTracker::OnReferencedSurfacesChanged(
88 Surface* surface, 142 Surface* surface,
89 const std::vector<SurfaceId>* active_referenced_surfaces, 143 const std::vector<SurfaceId>* active_referenced_surfaces,
90 const std::vector<SurfaceId>* pending_referenced_surfaces) {} 144 const std::vector<SurfaceId>* pending_referenced_surfaces) {}
91 145
92 void SurfaceDependencyTracker::OnSurfaceDiscarded(Surface* surface) { 146 void SurfaceDependencyTracker::OnSurfaceDiscarded(Surface* surface) {
93 // If the surface being destroyed doesn't have a pending frame then we have 147 // If the surface being destroyed doesn't have a pending frame then we have
94 // nothing to do here. 148 // nothing to do here.
95 if (!surface->HasPendingFrame()) 149 if (!surface->HasPendingFrame())
96 return; 150 return;
(...skipping 13 matching lines...) Expand all
110 if (pending_surface_it != pending_surface_set.end()) { 164 if (pending_surface_it != pending_surface_set.end()) {
111 pending_surface_set.erase(surface); 165 pending_surface_set.erase(surface);
112 if (pending_surface_set.empty()) 166 if (pending_surface_set.empty())
113 blocked_surfaces_.erase(surface_id); 167 blocked_surfaces_.erase(surface_id);
114 } 168 }
115 } 169 }
116 170
117 if (blocked_surfaces_.empty()) 171 if (blocked_surfaces_.empty())
118 frames_since_deadline_set_.reset(); 172 frames_since_deadline_set_.reset();
119 173
120 pending_surfaces_.erase(surface); 174 DCHECK(!pending_surfaces_.empty());
175 DCHECK(pending_surfaces_.erase(surface));
121 surface->RemoveObserver(this); 176 surface->RemoveObserver(this);
122 177
178 if (pending_surfaces_.empty())
179 AcknowledgeLastBeginFrame();
180 UpdateNeedsBeginFrames(); // |pending_surfaces_| changed.
Fady Samuel 2017/04/03 19:03:02 nit: put this comment above.
181
123 // Pretend that the discarded surface's SurfaceId is now available to unblock 182 // Pretend that the discarded surface's SurfaceId is now available to unblock
124 // dependencies because we now know the surface will never activate. 183 // dependencies because we now know the surface will never activate.
125 NotifySurfaceIdAvailable(surface->surface_id()); 184 NotifySurfaceIdAvailable(surface->surface_id());
126 } 185 }
127 186
128 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) { 187 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) {
129 surface->RemoveObserver(this); 188 surface->RemoveObserver(this);
130 pending_surfaces_.erase(surface); 189 DCHECK(!pending_surfaces_.empty());
190 DCHECK(pending_surfaces_.erase(surface));
191
192 if (pending_surfaces_.empty())
193 AcknowledgeLastBeginFrame();
194 UpdateNeedsBeginFrames(); // |pending_surfaces_| changed.
Fady Samuel 2017/04/03 19:03:02 nit: put this comment above.
195
Fady Samuel 2017/04/03 19:03:02 nit: remove.
131 NotifySurfaceIdAvailable(surface->surface_id()); 196 NotifySurfaceIdAvailable(surface->surface_id());
132 } 197 }
133 198
134 void SurfaceDependencyTracker::OnSurfaceDependenciesChanged( 199 void SurfaceDependencyTracker::OnSurfaceDependenciesChanged(
135 Surface* surface, 200 Surface* surface,
136 const SurfaceDependencies& added_dependencies, 201 const SurfaceDependencies& added_dependencies,
137 const SurfaceDependencies& removed_dependencies) { 202 const SurfaceDependencies& removed_dependencies) {
138 // Update the |blocked_surfaces_| map with the changes in dependencies. 203 // Update the |blocked_surfaces_| map with the changes in dependencies.
139 for (const SurfaceId& surface_id : added_dependencies) 204 for (const SurfaceId& surface_id : added_dependencies)
140 blocked_surfaces_[surface_id].insert(surface); 205 blocked_surfaces_[surface_id].insert(surface);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // have a deadline. 243 // have a deadline.
179 if (blocked_surfaces_.empty()) 244 if (blocked_surfaces_.empty())
180 frames_since_deadline_set_.reset(); 245 frames_since_deadline_set_.reset();
181 246
182 // Tell each surface about the availability of its blocker. 247 // Tell each surface about the availability of its blocker.
183 for (Surface* blocked_pending_surface : blocked_pending_surface_set) 248 for (Surface* blocked_pending_surface : blocked_pending_surface_set)
184 blocked_pending_surface->NotifySurfaceIdAvailable(surface_id); 249 blocked_pending_surface->NotifySurfaceIdAvailable(surface_id);
185 } 250 }
186 251
187 } // namespace cc 252 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/surface_dependency_tracker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698