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

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

Issue 2887453002: SurfaceDependencyTracker: Only observe BeginFrames if a deadline is needed (Closed)
Patch Set: Fixed an incorrect DCHECK Created 3 years, 6 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), deadline_(this, begin_frame_source) {}
21 begin_frame_source_(begin_frame_source) {
22 begin_frame_source_->AddObserver(this);
23 }
24 21
25 SurfaceDependencyTracker::~SurfaceDependencyTracker() { 22 SurfaceDependencyTracker::~SurfaceDependencyTracker() {
26 begin_frame_source_->RemoveObserver(this); 23 deadline_.Cancel();
27 } 24 }
28 25
29 void SurfaceDependencyTracker::RequestSurfaceResolution(Surface* surface) { 26 void SurfaceDependencyTracker::RequestSurfaceResolution(Surface* surface) {
30 DCHECK(surface->HasPendingFrame()); 27 DCHECK(surface->HasPendingFrame());
31 28
32 const CompositorFrame& pending_frame = surface->GetPendingFrame(); 29 const CompositorFrame& pending_frame = surface->GetPendingFrame();
33 bool needs_deadline = pending_frame.metadata.can_activate_before_dependencies; 30 bool needs_deadline = pending_frame.metadata.can_activate_before_dependencies;
34 31
35 auto late_it = late_surfaces_by_id_.find(surface->surface_id()); 32 auto late_it = late_surfaces_by_id_.find(surface->surface_id());
36 if (needs_deadline && late_it != late_surfaces_by_id_.end()) { 33 if (needs_deadline && late_it != late_surfaces_by_id_.end()) {
37 late_surfaces_by_id_.erase(late_it); 34 late_surfaces_by_id_.erase(late_it);
38 surface->ActivatePendingFrameForDeadline(); 35 surface->ActivatePendingFrameForDeadline();
39 return; 36 return;
40 } 37 }
41 38
42 // 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
43 // or do not have an active CompsotiorFrame block this frame. 40 // or do not have an active CompsotiorFrame block this frame.
44 for (const SurfaceId& surface_id : 41 for (const SurfaceId& surface_id :
45 pending_frame.metadata.activation_dependencies) { 42 pending_frame.metadata.activation_dependencies) {
46 Surface* surface_dependency = surface_manager_->GetSurfaceForId(surface_id); 43 Surface* surface_dependency = surface_manager_->GetSurfaceForId(surface_id);
47 if (!surface_dependency || !surface_dependency->HasActiveFrame()) 44 if (!surface_dependency || !surface_dependency->HasActiveFrame())
48 blocked_surfaces_from_dependency_[surface_id].insert( 45 blocked_surfaces_from_dependency_[surface_id].insert(
49 surface->surface_id()); 46 surface->surface_id());
50 } 47 }
51 48
52 blocked_surfaces_by_id_.insert(surface->surface_id()); 49 blocked_surfaces_by_id_.insert(surface->surface_id());
53 50
54 if (needs_deadline && !frames_since_deadline_set_) 51 if (needs_deadline && !deadline_.has_deadline())
55 frames_since_deadline_set_ = 0; 52 deadline_.Set(kMaxBeginFrameCount);
56 } 53 }
57 54
58 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) { 55 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) {
59 blocked_surfaces_by_id_.erase(surface->surface_id()); 56 blocked_surfaces_by_id_.erase(surface->surface_id());
60 NotifySurfaceIdAvailable(surface->surface_id()); 57 NotifySurfaceIdAvailable(surface->surface_id());
61 } 58 }
62 59
63 void SurfaceDependencyTracker::OnSurfaceDependenciesChanged( 60 void SurfaceDependencyTracker::OnSurfaceDependenciesChanged(
64 Surface* surface, 61 Surface* surface,
65 const base::flat_set<SurfaceId>& added_dependencies, 62 const base::flat_set<SurfaceId>& added_dependencies,
66 const base::flat_set<SurfaceId>& removed_dependencies) { 63 const base::flat_set<SurfaceId>& removed_dependencies) {
67 // Update the |blocked_surfaces_from_dependency_| map with the changes in 64 // Update the |blocked_surfaces_from_dependency_| map with the changes in
68 // dependencies. 65 // dependencies.
69 for (const SurfaceId& surface_id : added_dependencies) 66 for (const SurfaceId& surface_id : added_dependencies)
70 blocked_surfaces_from_dependency_[surface_id].insert(surface->surface_id()); 67 blocked_surfaces_from_dependency_[surface_id].insert(surface->surface_id());
71 68
72 for (const SurfaceId& surface_id : removed_dependencies) { 69 for (const SurfaceId& surface_id : removed_dependencies) {
73 auto it = blocked_surfaces_from_dependency_.find(surface_id); 70 auto it = blocked_surfaces_from_dependency_.find(surface_id);
74 it->second.erase(surface->surface_id()); 71 it->second.erase(surface->surface_id());
75 if (it->second.empty()) 72 if (it->second.empty())
76 blocked_surfaces_from_dependency_.erase(it); 73 blocked_surfaces_from_dependency_.erase(it);
77 } 74 }
78 75
79 // If there are no more dependencies to resolve then we don't need to have a 76 // If there are no more dependencies to resolve then we don't need to have a
80 // deadline. 77 // deadline.
81 if (blocked_surfaces_from_dependency_.empty()) 78 if (blocked_surfaces_from_dependency_.empty())
82 frames_since_deadline_set_.reset(); 79 deadline_.Cancel();
83 } 80 }
84 81
85 void SurfaceDependencyTracker::OnSurfaceDiscarded(Surface* surface) { 82 void SurfaceDependencyTracker::OnSurfaceDiscarded(Surface* surface) {
86 // If the surface being destroyed doesn't have a pending frame then we have 83 // If the surface being destroyed doesn't have a pending frame then we have
87 // nothing to do here. 84 // nothing to do here.
88 if (!surface->HasPendingFrame()) 85 if (!surface->HasPendingFrame())
89 return; 86 return;
90 87
91 const CompositorFrame& pending_frame = surface->GetPendingFrame(); 88 const CompositorFrame& pending_frame = surface->GetPendingFrame();
92 89
93 DCHECK(!pending_frame.metadata.activation_dependencies.empty()); 90 DCHECK(!pending_frame.metadata.activation_dependencies.empty());
94 91
95 for (const SurfaceId& surface_id : 92 for (const SurfaceId& surface_id :
96 pending_frame.metadata.activation_dependencies) { 93 pending_frame.metadata.activation_dependencies) {
97 auto it = blocked_surfaces_from_dependency_.find(surface_id); 94 auto it = blocked_surfaces_from_dependency_.find(surface_id);
98 if (it == blocked_surfaces_from_dependency_.end()) 95 if (it == blocked_surfaces_from_dependency_.end())
99 continue; 96 continue;
100 97
101 auto& blocked_surface_ids = it->second; 98 auto& blocked_surface_ids = it->second;
102 auto blocked_surface_ids_it = 99 auto blocked_surface_ids_it =
103 blocked_surface_ids.find(surface->surface_id()); 100 blocked_surface_ids.find(surface->surface_id());
104 if (blocked_surface_ids_it != blocked_surface_ids.end()) { 101 if (blocked_surface_ids_it != blocked_surface_ids.end()) {
105 blocked_surface_ids.erase(surface->surface_id()); 102 blocked_surface_ids.erase(surface->surface_id());
106 if (blocked_surface_ids.empty()) 103 if (blocked_surface_ids.empty())
107 blocked_surfaces_from_dependency_.erase(surface_id); 104 blocked_surfaces_from_dependency_.erase(surface_id);
108 } 105 }
109 } 106 }
110 107
111 if (blocked_surfaces_from_dependency_.empty()) 108 if (blocked_surfaces_from_dependency_.empty())
112 frames_since_deadline_set_.reset(); 109 deadline_.Cancel();
113 110
114 blocked_surfaces_by_id_.erase(surface->surface_id()); 111 blocked_surfaces_by_id_.erase(surface->surface_id());
115 112
116 // Pretend that the discarded surface's SurfaceId is now available to unblock 113 // Pretend that the discarded surface's SurfaceId is now available to unblock
117 // dependencies because we now know the surface will never activate. 114 // dependencies because we now know the surface will never activate.
118 NotifySurfaceIdAvailable(surface->surface_id()); 115 NotifySurfaceIdAvailable(surface->surface_id());
119 } 116 }
120 117
121 void SurfaceDependencyTracker::OnBeginFrame(const BeginFrameArgs& args) { 118 void SurfaceDependencyTracker::OnDeadline() {
122 // If no deadline is set then we have nothing to do.
123 if (!frames_since_deadline_set_)
124 return;
125
126 // TODO(fsamuel, kylechar): We have a single global deadline here. We should
127 // scope deadlines to surface subtrees. We cannot do that until
128 // SurfaceReferences have been fully implemented
129 // (see https://crbug.com/689719).
130 last_begin_frame_args_ = args;
131 // Nothing to do if we haven't hit a deadline yet.
132 if (++(*frames_since_deadline_set_) != kMaxBeginFrameCount)
133 return;
134
135 late_surfaces_by_id_.clear(); 119 late_surfaces_by_id_.clear();
136 120
137 // Activate all surfaces that respect the deadline. 121 // Activate all surfaces that respect the deadline.
138 // Copy the set of blocked surfaces here because that set can mutate as we 122 // Copy the set of blocked surfaces here because that set can mutate as we
139 // activate CompositorFrames: an activation can trigger further activations 123 // activate CompositorFrames: an activation can trigger further activations
140 // which will remove elements from |blocked_surfaces_by_id_|. This 124 // which will remove elements from |blocked_surfaces_by_id_|. This
141 // invalidates the iterator. 125 // invalidates the iterator.
142 base::flat_set<SurfaceId> blocked_surfaces_by_id(blocked_surfaces_by_id_); 126 base::flat_set<SurfaceId> blocked_surfaces_by_id(blocked_surfaces_by_id_);
143 for (const SurfaceId& surface_id : blocked_surfaces_by_id) { 127 for (const SurfaceId& surface_id : blocked_surfaces_by_id) {
144 Surface* blocked_surface = surface_manager_->GetSurfaceForId(surface_id); 128 Surface* blocked_surface = surface_manager_->GetSurfaceForId(surface_id);
145 if (!blocked_surface) { 129 if (!blocked_surface) {
146 // A blocked surface may have been garbage collected during dependency 130 // A blocked surface may have been garbage collected during dependency
147 // resolution. 131 // resolution.
148 DCHECK(!blocked_surfaces_by_id_.count(surface_id)); 132 DCHECK(!blocked_surfaces_by_id_.count(surface_id));
149 continue; 133 continue;
150 } 134 }
151 // Clear all tracked blockers for |blocked_surface|. 135 // Clear all tracked blockers for |blocked_surface|.
152 for (const SurfaceId& blocking_surface_id : 136 for (const SurfaceId& blocking_surface_id :
153 blocked_surface->blocking_surfaces()) { 137 blocked_surface->blocking_surfaces()) {
154 // If we are not activating this blocker now, then it's late. 138 // If we are not activating this blocker now, then it's late.
155 if (!blocked_surfaces_by_id.count(blocking_surface_id)) 139 if (!blocked_surfaces_by_id.count(blocking_surface_id))
156 late_surfaces_by_id_.insert(blocking_surface_id); 140 late_surfaces_by_id_.insert(blocking_surface_id);
157 blocked_surfaces_from_dependency_[blocking_surface_id].erase(surface_id); 141 blocked_surfaces_from_dependency_[blocking_surface_id].erase(surface_id);
158 } 142 }
159 blocked_surface->ActivatePendingFrameForDeadline(); 143 blocked_surface->ActivatePendingFrameForDeadline();
160 } 144 }
161
162 frames_since_deadline_set_.reset();
163 } 145 }
164 146
165 const BeginFrameArgs& SurfaceDependencyTracker::LastUsedBeginFrameArgs() const {
166 return last_begin_frame_args_;
167 }
168
169 void SurfaceDependencyTracker::OnBeginFrameSourcePausedChanged(bool paused) {}
170
171 void SurfaceDependencyTracker::NotifySurfaceIdAvailable( 147 void SurfaceDependencyTracker::NotifySurfaceIdAvailable(
172 const SurfaceId& surface_id) { 148 const SurfaceId& surface_id) {
173 auto it = blocked_surfaces_from_dependency_.find(surface_id); 149 auto it = blocked_surfaces_from_dependency_.find(surface_id);
174 if (it == blocked_surfaces_from_dependency_.end()) 150 if (it == blocked_surfaces_from_dependency_.end())
175 return; 151 return;
176 152
177 // Unblock surfaces that depend on this |surface_id|. 153 // Unblock surfaces that depend on this |surface_id|.
178 base::flat_set<SurfaceId> blocked_surfaces_by_id(it->second); 154 base::flat_set<SurfaceId> blocked_surfaces_by_id(it->second);
179 blocked_surfaces_from_dependency_.erase(it); 155 blocked_surfaces_from_dependency_.erase(it);
180 // If there are no more blockers in the system, then we no longer need to 156 // If there are no more blockers in the system, then we no longer need to
181 // have a deadline. 157 // have a deadline.
182 if (blocked_surfaces_from_dependency_.empty()) 158 if (blocked_surfaces_from_dependency_.empty())
183 frames_since_deadline_set_.reset(); 159 deadline_.Cancel();
184 160
185 // Tell each surface about the availability of its blocker. 161 // Tell each surface about the availability of its blocker.
186 for (const SurfaceId& blocked_surface_by_id : blocked_surfaces_by_id) { 162 for (const SurfaceId& blocked_surface_by_id : blocked_surfaces_by_id) {
187 Surface* blocked_surface = 163 Surface* blocked_surface =
188 surface_manager_->GetSurfaceForId(blocked_surface_by_id); 164 surface_manager_->GetSurfaceForId(blocked_surface_by_id);
189 if (!blocked_surface) { 165 if (!blocked_surface) {
190 // A blocked surface may have been garbage collected during dependency 166 // A blocked surface may have been garbage collected during dependency
191 // resolution. 167 // resolution.
192 DCHECK(!blocked_surfaces_by_id_.count(blocked_surface_by_id)); 168 DCHECK(!blocked_surfaces_by_id_.count(blocked_surface_by_id));
193 continue; 169 continue;
194 } 170 }
195 blocked_surface->NotifySurfaceIdAvailable(surface_id); 171 blocked_surface->NotifySurfaceIdAvailable(surface_id);
196 } 172 }
197 } 173 }
198 174
199 } // namespace cc 175 } // 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