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

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

Issue 2684933003: Move frame_sink_id management to framesink_manager.cc/h from (Closed)
Patch Set: 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 2014 The Chromium Authors. All rights reserved.
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/framesink_manager.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <queue>
11 #include <utility>
12
13 #include "base/logging.h"
14
15 #if DCHECK_IS_ON()
16 #include <sstream>
17 #endif
18
19 namespace cc {
20
21 FrameSinkManager::FrameSinkSourceMapping::FrameSinkSourceMapping()
22 : client(nullptr), source(nullptr) {}
23
24 FrameSinkManager::FrameSinkSourceMapping::FrameSinkSourceMapping(
25 const FrameSinkSourceMapping& other) = default;
26
27 FrameSinkManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() {
28 DCHECK(is_empty()) << "client: " << client
29 << ", children: " << children.size();
30 }
31
32 FrameSinkManager::FrameSinkManager() {
33 thread_checker_.DetachFromThread();
34 }
35
36 FrameSinkManager::~FrameSinkManager() {
37 DCHECK(thread_checker_.CalledOnValidThread());
38
39 // All hierarchies, sources, and surface factory clients should be
40 // unregistered prior to SurfaceManager destruction.
41 DCHECK_EQ(frame_sink_source_map_.size(), 0u);
42 DCHECK_EQ(registered_sources_.size(), 0u);
43 }
44
45 void FrameSinkManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) {
46 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second;
47 DCHECK(inserted);
48 }
49
50 void FrameSinkManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) {
51 valid_frame_sink_ids_.erase(frame_sink_id);
52 }
53
54 void FrameSinkManager::RegisterSurfaceFactoryClient(
55 const FrameSinkId& frame_sink_id,
56 SurfaceFactoryClient* client) {
57 DCHECK(client);
58 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u);
59
60 // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary.
61 FrameSinkSourceMapping& frame_sink_source =
62 frame_sink_source_map_[frame_sink_id];
63 DCHECK(!frame_sink_source.client);
64 frame_sink_source.client = client;
65
66 // Propagate any previously set sources to the new client.
67 if (frame_sink_source.source)
68 client->SetBeginFrameSource(frame_sink_source.source);
69 }
70
71 void FrameSinkManager::UnregisterSurfaceFactoryClient(
72 const FrameSinkId& frame_sink_id) {
73 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u);
74 DCHECK_EQ(frame_sink_source_map_.count(frame_sink_id), 1u);
75
76 auto iter = frame_sink_source_map_.find(frame_sink_id);
77 if (iter->second.source)
78 iter->second.client->SetBeginFrameSource(nullptr);
79 iter->second.client = nullptr;
80
81 // The SurfaceFactoryClient and hierarchy can be registered/unregistered
82 // in either order, so empty namespace_client_map entries need to be
83 // checked when removing either clients or relationships.
84 if (iter->second.is_empty())
85 frame_sink_source_map_.erase(iter);
86 }
87
88 void FrameSinkManager::RegisterBeginFrameSource(
89 BeginFrameSource* source,
90 const FrameSinkId& frame_sink_id) {
91 DCHECK(source);
92 DCHECK_EQ(registered_sources_.count(source), 0u);
93 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u);
94
95 registered_sources_[source] = frame_sink_id;
96 RecursivelyAttachBeginFrameSource(frame_sink_id, source);
97 }
98
99 void FrameSinkManager::UnregisterBeginFrameSource(BeginFrameSource* source) {
100 DCHECK(source);
101 DCHECK_EQ(registered_sources_.count(source), 1u);
102
103 FrameSinkId frame_sink_id = registered_sources_[source];
104 registered_sources_.erase(source);
105
106 if (frame_sink_source_map_.count(frame_sink_id) == 0u)
107 return;
108
109 // TODO(enne): these walks could be done in one step.
110 // Remove this begin frame source from its subtree.
111 RecursivelyDetachBeginFrameSource(frame_sink_id, source);
112 // Then flush every remaining registered source to fix any sources that
113 // became null because of the previous step but that have an alternative.
114 for (auto source_iter : registered_sources_)
115 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first);
116 }
117
118 void FrameSinkManager::RecursivelyAttachBeginFrameSource(
119 const FrameSinkId& frame_sink_id,
120 BeginFrameSource* source) {
121 FrameSinkSourceMapping& mapping = frame_sink_source_map_[frame_sink_id];
122 if (!mapping.source) {
123 mapping.source = source;
124 if (mapping.client)
125 mapping.client->SetBeginFrameSource(source);
126 }
127 for (size_t i = 0; i < mapping.children.size(); ++i)
128 RecursivelyAttachBeginFrameSource(mapping.children[i], source);
129 }
130
131 void FrameSinkManager::RecursivelyDetachBeginFrameSource(
132 const FrameSinkId& frame_sink_id,
133 BeginFrameSource* source) {
134 auto iter = frame_sink_source_map_.find(frame_sink_id);
135 if (iter == frame_sink_source_map_.end())
136 return;
137 if (iter->second.source == source) {
138 iter->second.source = nullptr;
139 if (iter->second.client)
140 iter->second.client->SetBeginFrameSource(nullptr);
141 }
142
143 if (iter->second.is_empty()) {
144 frame_sink_source_map_.erase(iter);
145 return;
146 }
147
148 std::vector<FrameSinkId>& children = iter->second.children;
149 for (size_t i = 0; i < children.size(); ++i) {
150 RecursivelyDetachBeginFrameSource(children[i], source);
151 }
152 }
153
154 bool FrameSinkManager::ChildContains(
155 const FrameSinkId& child_frame_sink_id,
156 const FrameSinkId& search_frame_sink_id) const {
157 auto iter = frame_sink_source_map_.find(child_frame_sink_id);
158 if (iter == frame_sink_source_map_.end())
159 return false;
160
161 const std::vector<FrameSinkId>& children = iter->second.children;
162 for (size_t i = 0; i < children.size(); ++i) {
163 if (children[i] == search_frame_sink_id)
164 return true;
165 if (ChildContains(children[i], search_frame_sink_id))
166 return true;
167 }
168 return false;
169 }
170
171 void FrameSinkManager::RegisterFrameSinkHierarchy(
172 const FrameSinkId& parent_frame_sink_id,
173 const FrameSinkId& child_frame_sink_id) {
174 DCHECK_EQ(valid_frame_sink_ids_.count(parent_frame_sink_id), 1u);
175 DCHECK_EQ(valid_frame_sink_ids_.count(child_frame_sink_id), 1u);
176
177 // If it's possible to reach the parent through the child's descendant chain,
178 // then this will create an infinite loop. Might as well just crash here.
179 CHECK(!ChildContains(child_frame_sink_id, parent_frame_sink_id));
180
181 std::vector<FrameSinkId>& children =
182 frame_sink_source_map_[parent_frame_sink_id].children;
183 for (size_t i = 0; i < children.size(); ++i)
184 DCHECK(children[i] != child_frame_sink_id);
185 children.push_back(child_frame_sink_id);
186
187 // If the parent has no source, then attaching it to this child will
188 // not change any downstream sources.
189 BeginFrameSource* parent_source =
190 frame_sink_source_map_[parent_frame_sink_id].source;
191 if (!parent_source)
192 return;
193
194 DCHECK_EQ(registered_sources_.count(parent_source), 1u);
195 RecursivelyAttachBeginFrameSource(child_frame_sink_id, parent_source);
196 }
197
198 void FrameSinkManager::UnregisterFrameSinkHierarchy(
199 const FrameSinkId& parent_frame_sink_id,
200 const FrameSinkId& child_frame_sink_id) {
201 // Deliberately do not check validity of either parent or child namespace
202 // here. They were valid during the registration, so were valid at some
203 // point in time. This makes it possible to invalidate parent and child
204 // namespaces independently of each other and not have an ordering dependency
205 // of unregistering the hierarchy first before either of them.
206 DCHECK_EQ(frame_sink_source_map_.count(parent_frame_sink_id), 1u);
207
208 auto iter = frame_sink_source_map_.find(parent_frame_sink_id);
209
210 std::vector<FrameSinkId>& children = iter->second.children;
211 bool found_child = false;
212 for (size_t i = 0; i < children.size(); ++i) {
213 if (children[i] == child_frame_sink_id) {
214 found_child = true;
215 children[i] = children.back();
216 children.resize(children.size() - 1);
217 break;
218 }
219 }
220 DCHECK(found_child);
221
222 // The SurfaceFactoryClient and hierarchy can be registered/unregistered
223 // in either order, so empty namespace_client_map entries need to be
224 // checked when removing either clients or relationships.
225 if (iter->second.is_empty()) {
226 frame_sink_source_map_.erase(iter);
227 return;
228 }
229
230 // If the parent does not have a begin frame source, then disconnecting it
231 // will not change any of its children.
232 BeginFrameSource* parent_source = iter->second.source;
233 if (!parent_source)
234 return;
235
236 // TODO(enne): these walks could be done in one step.
237 RecursivelyDetachBeginFrameSource(child_frame_sink_id, parent_source);
238 for (auto source_iter : registered_sources_)
239 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first);
240 }
241
242 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698