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

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

Issue 1673783004: Hook up BeginFrameSource to SurfaceFactoryClient via SurfaceManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Register id namespace on Android Created 4 years, 9 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_manager.h ('k') | cc/surfaces/surface_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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_manager.h" 5 #include "cc/surfaces/surface_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "cc/surfaces/surface.h" 11 #include "cc/surfaces/surface.h"
12 #include "cc/surfaces/surface_factory_client.h"
12 #include "cc/surfaces/surface_id_allocator.h" 13 #include "cc/surfaces/surface_id_allocator.h"
13 14
14 namespace cc { 15 namespace cc {
15 16
17 SurfaceManager::ClientSourceMapping::ClientSourceMapping()
18 : client(nullptr), source(nullptr) {}
19
20 SurfaceManager::ClientSourceMapping::~ClientSourceMapping() {
21 DCHECK(is_empty()) << "client: " << client
22 << ", children: " << children.size();
23 }
24
16 SurfaceManager::SurfaceManager() { 25 SurfaceManager::SurfaceManager() {
17 thread_checker_.DetachFromThread(); 26 thread_checker_.DetachFromThread();
18 } 27 }
19 28
20 SurfaceManager::~SurfaceManager() { 29 SurfaceManager::~SurfaceManager() {
21 DCHECK(thread_checker_.CalledOnValidThread()); 30 DCHECK(thread_checker_.CalledOnValidThread());
22 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); 31 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
23 it != surfaces_to_destroy_.end(); 32 it != surfaces_to_destroy_.end();
24 ++it) { 33 ++it) {
25 DeregisterSurface((*it)->surface_id()); 34 DeregisterSurface((*it)->surface_id());
26 delete *it; 35 delete *it;
27 } 36 }
37 // All hierarchies, sources, and surface factory clients should be
38 // unregistered prior to SurfaceManager destruction.
39 DCHECK_EQ(namespace_client_map_.size(), 0u);
40 DCHECK_EQ(registered_sources_.size(), 0u);
28 } 41 }
29 42
30 void SurfaceManager::RegisterSurface(Surface* surface) { 43 void SurfaceManager::RegisterSurface(Surface* surface) {
31 DCHECK(thread_checker_.CalledOnValidThread()); 44 DCHECK(thread_checker_.CalledOnValidThread());
32 DCHECK(surface); 45 DCHECK(surface);
33 DCHECK(!surface_map_.count(surface->surface_id())); 46 DCHECK(!surface_map_.count(surface->surface_id()));
34 surface_map_[surface->surface_id()] = surface; 47 surface_map_[surface->surface_id()] = surface;
35 } 48 }
36 49
37 void SurfaceManager::DeregisterSurface(SurfaceId surface_id) { 50 void SurfaceManager::DeregisterSurface(SurfaceId surface_id) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 if (!live_surfaces_set.count((*dest_it)->surface_id())) { 126 if (!live_surfaces_set.count((*dest_it)->surface_id())) {
114 scoped_ptr<Surface> surf(*dest_it); 127 scoped_ptr<Surface> surf(*dest_it);
115 DeregisterSurface(surf->surface_id()); 128 DeregisterSurface(surf->surface_id());
116 dest_it = surfaces_to_destroy_.erase(dest_it); 129 dest_it = surfaces_to_destroy_.erase(dest_it);
117 } else { 130 } else {
118 ++dest_it; 131 ++dest_it;
119 } 132 }
120 } 133 }
121 } 134 }
122 135
136 void SurfaceManager::RegisterSurfaceFactoryClient(
137 uint32_t id_namespace,
138 SurfaceFactoryClient* client) {
139 DCHECK(client);
140 DCHECK(!namespace_client_map_[id_namespace].client);
141 DCHECK_EQ(valid_surface_id_namespaces_.count(id_namespace), 1u);
142
143 auto iter = namespace_client_map_.find(id_namespace);
144 if (iter == namespace_client_map_.end()) {
145 auto insert_result = namespace_client_map_.insert(
146 std::make_pair(id_namespace, ClientSourceMapping()));
147 DCHECK(insert_result.second);
148 iter = insert_result.first;
149 }
150 iter->second.client = client;
151
152 // Propagate any previously set sources to the new client.
153 if (iter->second.source)
154 client->SetBeginFrameSource(iter->second.source);
155 }
156
157 void SurfaceManager::UnregisterSurfaceFactoryClient(uint32_t id_namespace) {
158 DCHECK_EQ(valid_surface_id_namespaces_.count(id_namespace), 1u);
159 DCHECK_EQ(namespace_client_map_.count(id_namespace), 1u);
160
161 auto iter = namespace_client_map_.find(id_namespace);
162 if (iter->second.source)
163 iter->second.client->SetBeginFrameSource(nullptr);
164 iter->second.client = nullptr;
165
166 // The SurfaceFactoryClient and hierarchy can be registered/unregistered
167 // in either order, so empty namespace_client_map entries need to be
168 // checked when removing either clients or relationships.
169 if (iter->second.is_empty())
170 namespace_client_map_.erase(iter);
171 }
172
173 void SurfaceManager::RegisterBeginFrameSource(BeginFrameSource* source,
174 uint32_t id_namespace) {
175 DCHECK(source);
176 DCHECK_EQ(registered_sources_.count(source), 0u);
177 DCHECK_EQ(valid_surface_id_namespaces_.count(id_namespace), 1u);
178
179 registered_sources_[source] = id_namespace;
180 RecursivelyAttachBeginFrameSource(id_namespace, source);
181 }
182
183 void SurfaceManager::UnregisterBeginFrameSource(BeginFrameSource* source) {
184 DCHECK(source);
185 DCHECK_EQ(registered_sources_.count(source), 1u);
186
187 uint32_t id_namespace = registered_sources_[source];
188 registered_sources_.erase(source);
189
190 if (namespace_client_map_.count(id_namespace) == 0u)
191 return;
192
193 // TODO(enne): these walks could be done in one step.
194 // Remove this begin frame source from its subtree.
195 RecursivelyDetachBeginFrameSource(id_namespace, source);
196 // Then flush every remaining registered source to fix any sources that
197 // became null because of the previous step but that have an alternative.
198 for (auto source_iter : registered_sources_)
199 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first);
200 }
201
202 void SurfaceManager::RecursivelyAttachBeginFrameSource(
203 uint32_t id_namespace,
204 BeginFrameSource* source) {
205 ClientSourceMapping& mapping = namespace_client_map_[id_namespace];
206 if (!mapping.source) {
207 mapping.source = source;
208 if (mapping.client)
209 mapping.client->SetBeginFrameSource(source);
210 }
211 for (size_t i = 0; i < mapping.children.size(); ++i)
212 RecursivelyAttachBeginFrameSource(mapping.children[i], source);
213 }
214
215 void SurfaceManager::RecursivelyDetachBeginFrameSource(
216 uint32_t id_namespace,
217 BeginFrameSource* source) {
218 auto iter = namespace_client_map_.find(id_namespace);
219 if (iter == namespace_client_map_.end())
220 return;
221 if (iter->second.source == source) {
222 iter->second.source = nullptr;
223 if (iter->second.client)
224 iter->second.client->SetBeginFrameSource(nullptr);
225 }
226
227 if (iter->second.is_empty()) {
228 namespace_client_map_.erase(iter);
229 return;
230 }
231
232 std::vector<uint32_t>& children = iter->second.children;
233 for (size_t i = 0; i < children.size(); ++i) {
234 RecursivelyDetachBeginFrameSource(children[i], source);
235 }
236 }
237
238 bool SurfaceManager::ChildContains(uint32_t child_namespace,
239 uint32_t search_namespace) const {
240 auto iter = namespace_client_map_.find(child_namespace);
241 if (iter == namespace_client_map_.end())
242 return false;
243
244 const std::vector<uint32_t>& children = iter->second.children;
245 for (size_t i = 0; i < children.size(); ++i) {
246 if (children[i] == search_namespace)
247 return true;
248 if (ChildContains(children[i], search_namespace))
249 return true;
250 }
251 return false;
252 }
253
254 void SurfaceManager::RegisterSurfaceNamespaceHierarchy(
255 uint32_t parent_namespace,
256 uint32_t child_namespace) {
257 DCHECK_EQ(valid_surface_id_namespaces_.count(parent_namespace), 1u);
258 DCHECK_EQ(valid_surface_id_namespaces_.count(child_namespace), 1u);
259
260 // If it's possible to reach the parent through the child's descendant chain,
261 // then this will create an infinite loop. Might as well just crash here.
262 CHECK(!ChildContains(child_namespace, parent_namespace));
263
264 std::vector<uint32_t>& children =
265 namespace_client_map_[parent_namespace].children;
266 for (size_t i = 0; i < children.size(); ++i)
267 DCHECK_NE(children[i], child_namespace);
268 children.push_back(child_namespace);
269
270 // If the parent has no source, then attaching it to this child will
271 // not change any downstream sources.
272 BeginFrameSource* parent_source =
273 namespace_client_map_[parent_namespace].source;
274 if (!parent_source)
275 return;
276
277 DCHECK_EQ(registered_sources_.count(parent_source), 1u);
278 RecursivelyAttachBeginFrameSource(child_namespace, parent_source);
279 }
280
281 void SurfaceManager::UnregisterSurfaceNamespaceHierarchy(
282 uint32_t parent_namespace,
283 uint32_t child_namespace) {
284 DCHECK_EQ(valid_surface_id_namespaces_.count(parent_namespace), 1u);
285 DCHECK_EQ(valid_surface_id_namespaces_.count(child_namespace), 1u);
286 DCHECK_EQ(namespace_client_map_.count(parent_namespace), 1u);
287
288 auto iter = namespace_client_map_.find(parent_namespace);
289
290 std::vector<uint32_t>& children = iter->second.children;
291 bool found_child = false;
292 for (size_t i = 0; i < children.size(); ++i) {
293 if (children[i] == child_namespace) {
294 found_child = true;
295 children[i] = children[children.size() - 1];
296 children.resize(children.size() - 1);
297 break;
298 }
299 }
300 DCHECK(found_child);
301
302 // The SurfaceFactoryClient and hierarchy can be registered/unregistered
303 // in either order, so empty namespace_client_map entries need to be
304 // checked when removing either clients or relationships.
305 if (iter->second.is_empty()) {
306 namespace_client_map_.erase(iter);
307 return;
308 }
309
310 // If the parent does not have a begin frame source, then disconnecting it
311 // will not change any of its children.
312 BeginFrameSource* parent_source = iter->second.source;
313 if (!parent_source)
314 return;
315
316 // TODO(enne): these walks could be done in one step.
317 RecursivelyDetachBeginFrameSource(child_namespace, parent_source);
318 for (auto source_iter : registered_sources_)
319 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first);
320 }
321
123 Surface* SurfaceManager::GetSurfaceForId(SurfaceId surface_id) { 322 Surface* SurfaceManager::GetSurfaceForId(SurfaceId surface_id) {
124 DCHECK(thread_checker_.CalledOnValidThread()); 323 DCHECK(thread_checker_.CalledOnValidThread());
125 SurfaceMap::iterator it = surface_map_.find(surface_id); 324 SurfaceMap::iterator it = surface_map_.find(surface_id);
126 if (it == surface_map_.end()) 325 if (it == surface_map_.end())
127 return NULL; 326 return NULL;
128 return it->second; 327 return it->second;
129 } 328 }
130 329
131 bool SurfaceManager::SurfaceModified(SurfaceId surface_id) { 330 bool SurfaceManager::SurfaceModified(SurfaceId surface_id) {
132 DCHECK(thread_checker_.CalledOnValidThread()); 331 CHECK(thread_checker_.CalledOnValidThread());
133 bool changed = false; 332 bool changed = false;
134 FOR_EACH_OBSERVER(SurfaceDamageObserver, observer_list_, 333 FOR_EACH_OBSERVER(SurfaceDamageObserver, observer_list_,
135 OnSurfaceDamaged(surface_id, &changed)); 334 OnSurfaceDamaged(surface_id, &changed));
136 return changed; 335 return changed;
137 } 336 }
138 337
139 } // namespace cc 338 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/surface_manager.h ('k') | cc/surfaces/surface_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698