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

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

Issue 2887453002: SurfaceDependencyTracker: Only observe BeginFrames if a deadline is needed (Closed)
Patch Set: Created 3 years, 7 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 | « no previous file | 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 begin_frame_source_->AddObserver(this);
23 } 22 }
24 23
25 SurfaceDependencyTracker::~SurfaceDependencyTracker() { 24 SurfaceDependencyTracker::~SurfaceDependencyTracker() = default;
26 begin_frame_source_->RemoveObserver(this);
27 }
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 if (!blocked_surfaces_by_id_.count(surface->surface_id())) 49 if (!blocked_surfaces_by_id_.count(surface->surface_id()))
53 blocked_surfaces_by_id_.insert(surface->surface_id()); 50 blocked_surfaces_by_id_.insert(surface->surface_id());
54 51
55 if (needs_deadline && !frames_since_deadline_set_) 52 if (needs_deadline && !frames_since_deadline_set_) {
56 frames_since_deadline_set_ = 0; 53 frames_since_deadline_set_ = 0;
54 begin_frame_source_->AddObserver(this);
vmpstr 2017/05/15 15:49:39 I wonder if we should have some sort of a scoped o
Fady Samuel 2017/05/29 17:46:54 I've introduced a SurfaceDependencyDeadline to dea
55 }
57 } 56 }
58 57
59 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) { 58 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) {
60 blocked_surfaces_by_id_.erase(surface->surface_id()); 59 blocked_surfaces_by_id_.erase(surface->surface_id());
61 NotifySurfaceIdAvailable(surface->surface_id()); 60 NotifySurfaceIdAvailable(surface->surface_id());
62 } 61 }
63 62
64 void SurfaceDependencyTracker::OnSurfaceDependenciesChanged( 63 void SurfaceDependencyTracker::OnSurfaceDependenciesChanged(
65 Surface* surface, 64 Surface* surface,
66 const base::flat_set<SurfaceId>& added_dependencies, 65 const base::flat_set<SurfaceId>& added_dependencies,
67 const base::flat_set<SurfaceId>& removed_dependencies) { 66 const base::flat_set<SurfaceId>& removed_dependencies) {
68 // Update the |blocked_surfaces_from_dependency_| map with the changes in 67 // Update the |blocked_surfaces_from_dependency_| map with the changes in
69 // dependencies. 68 // dependencies.
70 for (const SurfaceId& surface_id : added_dependencies) 69 for (const SurfaceId& surface_id : added_dependencies)
71 blocked_surfaces_from_dependency_[surface_id].insert(surface->surface_id()); 70 blocked_surfaces_from_dependency_[surface_id].insert(surface->surface_id());
72 71
73 for (const SurfaceId& surface_id : removed_dependencies) { 72 for (const SurfaceId& surface_id : removed_dependencies) {
74 auto it = blocked_surfaces_from_dependency_.find(surface_id); 73 auto it = blocked_surfaces_from_dependency_.find(surface_id);
75 it->second.erase(surface->surface_id()); 74 it->second.erase(surface->surface_id());
76 if (it->second.empty()) 75 if (it->second.empty())
77 blocked_surfaces_from_dependency_.erase(it); 76 blocked_surfaces_from_dependency_.erase(it);
78 } 77 }
79 78
80 // If there are no more dependencies to resolve then we don't need to have a 79 // If there are no more dependencies to resolve then we don't need to have a
81 // deadline. 80 // deadline.
82 if (blocked_surfaces_from_dependency_.empty()) 81 if (blocked_surfaces_from_dependency_.empty() && frames_since_deadline_set_) {
83 frames_since_deadline_set_.reset(); 82 frames_since_deadline_set_.reset();
83 begin_frame_source_->RemoveObserver(this);
84 }
84 } 85 }
85 86
86 void SurfaceDependencyTracker::OnSurfaceDiscarded(Surface* surface) { 87 void SurfaceDependencyTracker::OnSurfaceDiscarded(Surface* surface) {
87 // If the surface being destroyed doesn't have a pending frame then we have 88 // If the surface being destroyed doesn't have a pending frame then we have
88 // nothing to do here. 89 // nothing to do here.
89 if (!surface->HasPendingFrame()) 90 if (!surface->HasPendingFrame())
90 return; 91 return;
91 92
92 const CompositorFrame& pending_frame = surface->GetPendingFrame(); 93 const CompositorFrame& pending_frame = surface->GetPendingFrame();
93 94
94 DCHECK(!pending_frame.metadata.activation_dependencies.empty()); 95 DCHECK(!pending_frame.metadata.activation_dependencies.empty());
95 96
96 for (const SurfaceId& surface_id : 97 for (const SurfaceId& surface_id :
97 pending_frame.metadata.activation_dependencies) { 98 pending_frame.metadata.activation_dependencies) {
98 auto it = blocked_surfaces_from_dependency_.find(surface_id); 99 auto it = blocked_surfaces_from_dependency_.find(surface_id);
99 if (it == blocked_surfaces_from_dependency_.end()) 100 if (it == blocked_surfaces_from_dependency_.end())
100 continue; 101 continue;
101 102
102 auto& blocked_surface_ids = it->second; 103 auto& blocked_surface_ids = it->second;
103 auto blocked_surface_ids_it = 104 auto blocked_surface_ids_it =
104 blocked_surface_ids.find(surface->surface_id()); 105 blocked_surface_ids.find(surface->surface_id());
105 if (blocked_surface_ids_it != blocked_surface_ids.end()) { 106 if (blocked_surface_ids_it != blocked_surface_ids.end()) {
106 blocked_surface_ids.erase(surface->surface_id()); 107 blocked_surface_ids.erase(surface->surface_id());
107 if (blocked_surface_ids.empty()) 108 if (blocked_surface_ids.empty())
108 blocked_surfaces_from_dependency_.erase(surface_id); 109 blocked_surfaces_from_dependency_.erase(surface_id);
109 } 110 }
110 } 111 }
111 112
112 if (blocked_surfaces_from_dependency_.empty()) 113 if (blocked_surfaces_from_dependency_.empty() && frames_since_deadline_set_) {
113 frames_since_deadline_set_.reset(); 114 frames_since_deadline_set_.reset();
115 begin_frame_source_->RemoveObserver(this);
116 }
114 117
115 blocked_surfaces_by_id_.erase(surface->surface_id()); 118 blocked_surfaces_by_id_.erase(surface->surface_id());
116 119
117 // Pretend that the discarded surface's SurfaceId is now available to unblock 120 // Pretend that the discarded surface's SurfaceId is now available to unblock
118 // dependencies because we now know the surface will never activate. 121 // dependencies because we now know the surface will never activate.
119 NotifySurfaceIdAvailable(surface->surface_id()); 122 NotifySurfaceIdAvailable(surface->surface_id());
120 } 123 }
121 124
122 void SurfaceDependencyTracker::OnBeginFrame(const BeginFrameArgs& args) { 125 void SurfaceDependencyTracker::OnBeginFrame(const BeginFrameArgs& args) {
123 // If no deadline is set then we have nothing to do. 126 // If no deadline is set then we have nothing to do.
(...skipping 30 matching lines...) Expand all
154 blocked_surface->blocking_surfaces()) { 157 blocked_surface->blocking_surfaces()) {
155 // If we are not activating this blocker now, then it's late. 158 // If we are not activating this blocker now, then it's late.
156 if (!blocked_surfaces_by_id.count(blocking_surface_id)) 159 if (!blocked_surfaces_by_id.count(blocking_surface_id))
157 late_surfaces_by_id_.insert(blocking_surface_id); 160 late_surfaces_by_id_.insert(blocking_surface_id);
158 blocked_surfaces_from_dependency_[blocking_surface_id].erase(surface_id); 161 blocked_surfaces_from_dependency_[blocking_surface_id].erase(surface_id);
159 } 162 }
160 blocked_surface->ActivatePendingFrameForDeadline(); 163 blocked_surface->ActivatePendingFrameForDeadline();
161 } 164 }
162 165
163 frames_since_deadline_set_.reset(); 166 frames_since_deadline_set_.reset();
167 begin_frame_source_->RemoveObserver(this);
164 } 168 }
165 169
166 const BeginFrameArgs& SurfaceDependencyTracker::LastUsedBeginFrameArgs() const { 170 const BeginFrameArgs& SurfaceDependencyTracker::LastUsedBeginFrameArgs() const {
167 return last_begin_frame_args_; 171 return last_begin_frame_args_;
168 } 172 }
169 173
170 void SurfaceDependencyTracker::OnBeginFrameSourcePausedChanged(bool paused) {} 174 void SurfaceDependencyTracker::OnBeginFrameSourcePausedChanged(bool paused) {}
171 175
172 void SurfaceDependencyTracker::NotifySurfaceIdAvailable( 176 void SurfaceDependencyTracker::NotifySurfaceIdAvailable(
173 const SurfaceId& surface_id) { 177 const SurfaceId& surface_id) {
174 auto it = blocked_surfaces_from_dependency_.find(surface_id); 178 auto it = blocked_surfaces_from_dependency_.find(surface_id);
175 if (it == blocked_surfaces_from_dependency_.end()) 179 if (it == blocked_surfaces_from_dependency_.end())
176 return; 180 return;
177 181
178 // Unblock surfaces that depend on this |surface_id|. 182 // Unblock surfaces that depend on this |surface_id|.
179 base::flat_set<SurfaceId> blocked_surfaces_by_id(it->second); 183 base::flat_set<SurfaceId> blocked_surfaces_by_id(it->second);
180 blocked_surfaces_from_dependency_.erase(it); 184 blocked_surfaces_from_dependency_.erase(it);
181 // If there are no more blockers in the system, then we no longer need to 185 // If there are no more blockers in the system, then we no longer need to
182 // have a deadline. 186 // have a deadline.
183 if (blocked_surfaces_from_dependency_.empty()) 187 if (blocked_surfaces_from_dependency_.empty() && frames_since_deadline_set_) {
184 frames_since_deadline_set_.reset(); 188 frames_since_deadline_set_.reset();
189 begin_frame_source_->RemoveObserver(this);
190 }
185 191
186 // Tell each surface about the availability of its blocker. 192 // Tell each surface about the availability of its blocker.
187 for (const SurfaceId& blocked_surface_by_id : blocked_surfaces_by_id) { 193 for (const SurfaceId& blocked_surface_by_id : blocked_surfaces_by_id) {
188 Surface* blocked_surface = 194 Surface* blocked_surface =
189 surface_manager_->GetSurfaceForId(blocked_surface_by_id); 195 surface_manager_->GetSurfaceForId(blocked_surface_by_id);
190 if (!blocked_surface) { 196 if (!blocked_surface) {
191 // A blocked surface may have been garbage collected during dependency 197 // A blocked surface may have been garbage collected during dependency
192 // resolution. 198 // resolution.
193 DCHECK(!blocked_surfaces_by_id_.count(blocked_surface_by_id)); 199 DCHECK(!blocked_surfaces_by_id_.count(blocked_surface_by_id));
194 continue; 200 continue;
195 } 201 }
196 blocked_surface->NotifySurfaceIdAvailable(surface_id); 202 blocked_surface->NotifySurfaceIdAvailable(surface_id);
197 } 203 }
198 } 204 }
199 205
200 } // namespace cc 206 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698