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

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

Issue 2676373004: Implement service-side surface synchronization (Closed)
Patch Set: Better unit test name Created 3 years, 10 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
kylechar 2017/02/09 15:50:31 2017
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/surfaces/surface_dependency_tracker.h"
6
7 #include "cc/surfaces/surface.h"
kylechar 2017/02/09 15:50:32 Duplicate include.
8 #include "cc/surfaces/surface_info.h"
9 #include "cc/surfaces/surface_manager.h"
10
11 namespace cc {
12
13 namespace {
14 constexpr uint32_t kMaxBeginFrameCount = 4;
15 }
kylechar 2017/02/09 15:50:31 } // namespace
16
17 SurfaceDependencyTracker::SurfaceDependencyTracker(
18 SurfaceManager* surface_manager,
19 BeginFrameSource* begin_frame_source)
20 : surface_manager_(surface_manager),
21 begin_frame_source_(begin_frame_source) {
22 surface_manager_->AddObserver(this);
23 begin_frame_source_->AddObserver(this);
24 }
25
26 SurfaceDependencyTracker::~SurfaceDependencyTracker() {
27 surface_manager_->RemoveObserver(this);
28 begin_frame_source_->RemoveObserver(this);
29 }
30
31 void SurfaceDependencyTracker::RequestSurfaceResolution(Surface* surface) {
32 DCHECK(surface->HasPendingFrame());
33
34 const CompositorFrame& pending_frame = surface->GetPendingFrame();
35 bool needs_begin_frame =
36 pending_frame.metadata.can_activate_before_dependencies;
37
38 // Referenced surface IDs that aren't currently known to the surface manager
39 // or do not have an active CompsotiorFrame block this frame.
40 for (const SurfaceId& surface_id :
41 pending_frame.metadata.referenced_surfaces) {
42 Surface* surface_dependency = surface_manager_->GetSurfaceForId(surface_id);
43 if (!surface_dependency || !surface_dependency->HasActiveFrame())
44 blocked_surfaces_[surface_id].insert(surface);
45 }
46
47 if (!pending_surfaces_.count(surface)) {
48 surface->AddObserver(this);
49 pending_surfaces_.insert(surface);
50 }
51
52 if (needs_begin_frame && !frames_since_deadline_set_)
53 frames_since_deadline_set_ = 0;
54 }
55
56 void SurfaceDependencyTracker::OnBeginFrame(const BeginFrameArgs& args) {
57 // If no deadline is set then we have nothing to do.
58 if (!frames_since_deadline_set_)
59 return;
60
61 // TODO(fsamuel, kylechar): We have a single global deadline here. We should
62 // scope deadlines to surface subtrees. We cannot do that until
63 // SurfaceReferences have been fully implemented
64 // (see https://crbug.com/689719).
65 last_begin_frame_args_ = args;
66 // Nothing to do if we haven't hit a deadline yet.
67 if (++(*frames_since_deadline_set_) != kMaxBeginFrameCount)
68 return;
69
70 // Activate all surfaces that respect the deadline.
71 PendingSurfaceSet pending_surfaces(pending_surfaces_);
72 for (Surface* pending_surface : pending_surfaces)
73 pending_surface->ActivatePendingFrameForDeadline();
74
75 frames_since_deadline_set_.reset();
76 }
77
78 const BeginFrameArgs& SurfaceDependencyTracker::LastUsedBeginFrameArgs() const {
79 return last_begin_frame_args_;
80 }
81
82 void SurfaceDependencyTracker::OnBeginFrameSourcePausedChanged(bool paused) {}
83
84 void SurfaceDependencyTracker::OnSurfaceDiscarded(Surface* surface) {
85 // If the surface being destroyed doesn't have a pending frame then we have
86 // nothing to do here.
87 if (!surface->HasPendingFrame())
88 return;
89
90 const CompositorFrame& pending_frame = surface->GetPendingFrame();
91
92 DCHECK(!pending_frame.metadata.referenced_surfaces.empty());
93
94 for (const SurfaceId& surface_id :
95 pending_frame.metadata.referenced_surfaces) {
96 auto it = blocked_surfaces_.find(surface_id);
97 if (it == blocked_surfaces_.end())
98 continue;
99
100 auto& pending_surface_set = it->second;
101 auto pending_surface_it = pending_surface_set.find(surface);
102 if (pending_surface_it != pending_surface_set.end()) {
103 pending_surface_set.erase(surface);
104 if (pending_surface_set.empty())
105 blocked_surfaces_.erase(surface_id);
106 }
107 }
108
109 if (blocked_surfaces_.empty())
110 frames_since_deadline_set_.reset();
111
112 pending_surfaces_.erase(surface);
113 surface->RemoveObserver(this);
114
115 // TODO(fsamuel): We should consider removing this surface as a dependency on
116 // other surfaces. This dependency will be removed when the deadline hits
117 // anyway but maybe we should try to actiate these frames early (see
118 // https://crbug.com/689725).
119 }
120
121 void SurfaceDependencyTracker::OnSurfaceActivated(Surface* surface) {
122 surface->RemoveObserver(this);
123 pending_surfaces_.erase(surface);
124 NotifySurfaceIdAvailable(surface->surface_id());
125 }
126
127 void SurfaceDependencyTracker::OnSurfaceDependenciesChanged(
128 Surface* surface,
129 const SurfaceDependencies& added_dependencies,
130 const SurfaceDependencies& removed_dependencies) {
131 // Update the |blocked_surfaces_| map with the changes in dependencies.
132 for (const SurfaceId& surface_id : added_dependencies)
133 blocked_surfaces_[surface_id].insert(surface);
134
135 for (const SurfaceId& surface_id : removed_dependencies) {
136 auto it = blocked_surfaces_.find(surface_id);
137 it->second.erase(surface);
138 if (it->second.empty())
139 blocked_surfaces_.erase(it);
140 }
141
142 // If there are no more dependencies to resolve then we don't need to have a
143 // deadline.
144 if (blocked_surfaces_.empty())
145 frames_since_deadline_set_.reset();
146 }
147
148 // SurfaceObserver implementation:
149 void SurfaceDependencyTracker::OnSurfaceCreated(
150 const SurfaceInfo& surface_info) {
151 // This is called when a Surface has an activated frame for the first time.
152 // SurfaceDependencyTracker only observes Surfaces that contain pending
153 // frames. SurfaceDependencyTracker becomes aware of CompositorFrames that
154 // activate immediately go through here.
155 NotifySurfaceIdAvailable(surface_info.id());
156 }
157
158 void SurfaceDependencyTracker::OnSurfaceDamaged(const SurfaceId& surface_id,
159 bool* changed) {}
160
161 void SurfaceDependencyTracker::NotifySurfaceIdAvailable(
162 const SurfaceId& surface_id) {
163 auto it = blocked_surfaces_.find(surface_id);
164 if (it == blocked_surfaces_.end())
165 return;
166
167 // Unblock surfaces that depend on this |surface_id|.
168 PendingSurfaceSet blocked_pending_surface_set(it->second);
169 blocked_surfaces_.erase(it);
170 // If there are no more blockers in the system, then we no longer need to
171 // have a deadline.
172 if (blocked_surfaces_.empty())
173 frames_since_deadline_set_.reset();
174
175 // Tell each surface about the availability of its blocker.
176 for (Surface* blocked_pending_surface : blocked_pending_surface_set)
177 blocked_pending_surface->NotifySurfaceIdAvailable(surface_id);
178 }
179
180 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698