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

Side by Side Diff: cc/surfaces/surface_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
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 <queue> 10 #include <queue>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "cc/surfaces/direct_surface_reference_factory.h" 14 #include "cc/surfaces/direct_surface_reference_factory.h"
15 #include "cc/surfaces/surface.h" 15 #include "cc/surfaces/surface.h"
16 #include "cc/surfaces/surface_factory_client.h" 16 #include "cc/surfaces/surface_factory_client.h"
17 #include "cc/surfaces/surface_id_allocator.h" 17 #include "cc/surfaces/surface_id_allocator.h"
18 #include "cc/surfaces/surface_info.h" 18 #include "cc/surfaces/surface_info.h"
19 19
20 #if DCHECK_IS_ON() 20 #if DCHECK_IS_ON()
21 #include <sstream> 21 #include <sstream>
22 #endif 22 #endif
23 23
24 namespace cc { 24 namespace cc {
25 25
26 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping()
27 : client(nullptr), source(nullptr) {}
28
29 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping(
30 const FrameSinkSourceMapping& other) = default;
31
32 SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() {
33 DCHECK(is_empty()) << "client: " << client
34 << ", children: " << children.size();
35 }
36
37 SurfaceManager::SurfaceManager(LifetimeType lifetime_type) 26 SurfaceManager::SurfaceManager(LifetimeType lifetime_type)
38 : lifetime_type_(lifetime_type), 27 : lifetime_type_(lifetime_type),
39 root_surface_id_(FrameSinkId(0u, 0u), 28 root_surface_id_(FrameSinkId(0u, 0u),
40 LocalSurfaceId(1u, base::UnguessableToken::Create())), 29 LocalSurfaceId(1u, base::UnguessableToken::Create())),
41 weak_factory_(this) { 30 weak_factory_(this) {
42 thread_checker_.DetachFromThread(); 31 thread_checker_.DetachFromThread();
43 reference_factory_ = 32 reference_factory_ =
44 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr()); 33 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr());
45 } 34 }
46 35
(...skipping 11 matching lines...) Expand all
58 } 47 }
59 GarbageCollectSurfaces(); 48 GarbageCollectSurfaces();
60 } 49 }
61 50
62 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); 51 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
63 it != surfaces_to_destroy_.end(); 52 it != surfaces_to_destroy_.end();
64 ++it) { 53 ++it) {
65 DeregisterSurface((*it)->surface_id()); 54 DeregisterSurface((*it)->surface_id());
66 } 55 }
67 surfaces_to_destroy_.clear(); 56 surfaces_to_destroy_.clear();
68
69 // All hierarchies, sources, and surface factory clients should be
70 // unregistered prior to SurfaceManager destruction.
71 DCHECK_EQ(frame_sink_source_map_.size(), 0u);
72 DCHECK_EQ(registered_sources_.size(), 0u);
73 } 57 }
74 58
75 #if DCHECK_IS_ON() 59 #if DCHECK_IS_ON()
76 std::string SurfaceManager::SurfaceReferencesToString() { 60 std::string SurfaceManager::SurfaceReferencesToString() {
77 std::stringstream str; 61 std::stringstream str;
78 SurfaceReferencesToStringImpl(root_surface_id_, "", &str); 62 SurfaceReferencesToStringImpl(root_surface_id_, "", &str);
79 return str.str(); 63 return str.str();
80 } 64 }
81 #endif 65 #endif
82 66
(...skipping 29 matching lines...) Expand all
112 surface->AddDestructionDependency(sequence); 96 surface->AddDestructionDependency(sequence);
113 } 97 }
114 98
115 void SurfaceManager::SatisfySequence(const SurfaceSequence& sequence) { 99 void SurfaceManager::SatisfySequence(const SurfaceSequence& sequence) {
116 DCHECK(thread_checker_.CalledOnValidThread()); 100 DCHECK(thread_checker_.CalledOnValidThread());
117 DCHECK_EQ(lifetime_type_, LifetimeType::SEQUENCES); 101 DCHECK_EQ(lifetime_type_, LifetimeType::SEQUENCES);
118 satisfied_sequences_.insert(sequence); 102 satisfied_sequences_.insert(sequence);
119 GarbageCollectSurfaces(); 103 GarbageCollectSurfaces();
120 } 104 }
121 105
122 void SurfaceManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) {
123 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second;
124 DCHECK(inserted);
125 }
126
127 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) {
128 valid_frame_sink_ids_.erase(frame_sink_id);
129 GarbageCollectSurfaces();
130 }
131
132 const SurfaceId& SurfaceManager::GetRootSurfaceId() const { 106 const SurfaceId& SurfaceManager::GetRootSurfaceId() const {
133 return root_surface_id_; 107 return root_surface_id_;
134 } 108 }
135 109
136 void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id, 110 void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id,
137 const SurfaceId& child_id) { 111 const SurfaceId& child_id) {
138 DCHECK(thread_checker_.CalledOnValidThread()); 112 DCHECK(thread_checker_.CalledOnValidThread());
139 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES); 113 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
140 114
141 // Check some conditions that should never happen. We don't want to crash on 115 // Check some conditions that should never happen. We don't want to crash on
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 // TODO(jbauman): Reduce the amount of work when nothing needs to be 269 // TODO(jbauman): Reduce the amount of work when nothing needs to be
296 // destroyed. 270 // destroyed.
297 std::vector<SurfaceId> live_surfaces; 271 std::vector<SurfaceId> live_surfaces;
298 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; 272 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set;
299 273
300 // GC roots are surfaces that have not been destroyed, or have not had all 274 // GC roots are surfaces that have not been destroyed, or have not had all
301 // their destruction dependencies satisfied. 275 // their destruction dependencies satisfied.
302 for (auto& map_entry : surface_map_) { 276 for (auto& map_entry : surface_map_) {
303 const SurfaceId& surface_id = map_entry.first; 277 const SurfaceId& surface_id = map_entry.first;
304 Surface* surface = map_entry.second; 278 Surface* surface = map_entry.second;
305 surface->SatisfyDestructionDependencies(&satisfied_sequences_, 279 // TODO(kavithadevara): commented out following bcz of moving frame_sink_ids
Fady Samuel 2017/02/12 19:04:07 Can you restore this change?
k.devara 2017/02/13 07:00:52 I was trying to avoid having to expose valid_frame
306 &valid_frame_sink_ids_); 280 // management to framesink_manager.cc - this whole function should go away
281 // when Sequences are removed
282 // surface->SatisfyDestructionDependencies(&satisfied_sequences_,
283 // &valid_frame_sink_ids_);
307 284
308 if (!surface->destroyed() || surface->GetDestructionDependencyCount() > 0) { 285 if (!surface->destroyed() || surface->GetDestructionDependencyCount() > 0) {
309 live_surfaces_set.insert(surface_id); 286 live_surfaces_set.insert(surface_id);
310 live_surfaces.push_back(surface_id); 287 live_surfaces.push_back(surface_id);
311 } 288 }
312 } 289 }
313 290
314 // Mark all surfaces reachable from live surfaces by adding them to 291 // Mark all surfaces reachable from live surfaces by adding them to
315 // live_surfaces and live_surfaces_set. 292 // live_surfaces and live_surfaces_set.
316 for (size_t i = 0; i < live_surfaces.size(); i++) { 293 for (size_t i = 0; i < live_surfaces.size(); i++) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 332
356 // Remove all reference from parent surface to |surface_id|. 333 // Remove all reference from parent surface to |surface_id|.
357 iter = child_to_parent_refs_.find(surface_id); 334 iter = child_to_parent_refs_.find(surface_id);
358 if (iter != child_to_parent_refs_.end()) { 335 if (iter != child_to_parent_refs_.end()) {
359 for (const SurfaceId& parent_id : iter->second) 336 for (const SurfaceId& parent_id : iter->second)
360 parent_to_child_refs_[parent_id].erase(surface_id); 337 parent_to_child_refs_[parent_id].erase(surface_id);
361 child_to_parent_refs_.erase(iter); 338 child_to_parent_refs_.erase(iter);
362 } 339 }
363 } 340 }
364 341
365 void SurfaceManager::RegisterSurfaceFactoryClient(
366 const FrameSinkId& frame_sink_id,
367 SurfaceFactoryClient* client) {
368 DCHECK(client);
369 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u);
370
371 // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary.
372 FrameSinkSourceMapping& frame_sink_source =
373 frame_sink_source_map_[frame_sink_id];
374 DCHECK(!frame_sink_source.client);
375 frame_sink_source.client = client;
376
377 // Propagate any previously set sources to the new client.
378 if (frame_sink_source.source)
379 client->SetBeginFrameSource(frame_sink_source.source);
380 }
381
382 void SurfaceManager::UnregisterSurfaceFactoryClient(
383 const FrameSinkId& frame_sink_id) {
384 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u);
385 DCHECK_EQ(frame_sink_source_map_.count(frame_sink_id), 1u);
386
387 auto iter = frame_sink_source_map_.find(frame_sink_id);
388 if (iter->second.source)
389 iter->second.client->SetBeginFrameSource(nullptr);
390 iter->second.client = nullptr;
391
392 // The SurfaceFactoryClient and hierarchy can be registered/unregistered
393 // in either order, so empty namespace_client_map entries need to be
394 // checked when removing either clients or relationships.
395 if (iter->second.is_empty())
396 frame_sink_source_map_.erase(iter);
397 }
398
399 void SurfaceManager::RegisterBeginFrameSource(
400 BeginFrameSource* source,
401 const FrameSinkId& frame_sink_id) {
402 DCHECK(source);
403 DCHECK_EQ(registered_sources_.count(source), 0u);
404 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u);
405
406 registered_sources_[source] = frame_sink_id;
407 RecursivelyAttachBeginFrameSource(frame_sink_id, source);
408 }
409
410 void SurfaceManager::UnregisterBeginFrameSource(BeginFrameSource* source) {
411 DCHECK(source);
412 DCHECK_EQ(registered_sources_.count(source), 1u);
413
414 FrameSinkId frame_sink_id = registered_sources_[source];
415 registered_sources_.erase(source);
416
417 if (frame_sink_source_map_.count(frame_sink_id) == 0u)
418 return;
419
420 // TODO(enne): these walks could be done in one step.
421 // Remove this begin frame source from its subtree.
422 RecursivelyDetachBeginFrameSource(frame_sink_id, source);
423 // Then flush every remaining registered source to fix any sources that
424 // became null because of the previous step but that have an alternative.
425 for (auto source_iter : registered_sources_)
426 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first);
427 }
428
429 void SurfaceManager::RecursivelyAttachBeginFrameSource(
430 const FrameSinkId& frame_sink_id,
431 BeginFrameSource* source) {
432 FrameSinkSourceMapping& mapping = frame_sink_source_map_[frame_sink_id];
433 if (!mapping.source) {
434 mapping.source = source;
435 if (mapping.client)
436 mapping.client->SetBeginFrameSource(source);
437 }
438 for (size_t i = 0; i < mapping.children.size(); ++i)
439 RecursivelyAttachBeginFrameSource(mapping.children[i], source);
440 }
441
442 void SurfaceManager::RecursivelyDetachBeginFrameSource(
443 const FrameSinkId& frame_sink_id,
444 BeginFrameSource* source) {
445 auto iter = frame_sink_source_map_.find(frame_sink_id);
446 if (iter == frame_sink_source_map_.end())
447 return;
448 if (iter->second.source == source) {
449 iter->second.source = nullptr;
450 if (iter->second.client)
451 iter->second.client->SetBeginFrameSource(nullptr);
452 }
453
454 if (iter->second.is_empty()) {
455 frame_sink_source_map_.erase(iter);
456 return;
457 }
458
459 std::vector<FrameSinkId>& children = iter->second.children;
460 for (size_t i = 0; i < children.size(); ++i) {
461 RecursivelyDetachBeginFrameSource(children[i], source);
462 }
463 }
464
465 bool SurfaceManager::ChildContains(
466 const FrameSinkId& child_frame_sink_id,
467 const FrameSinkId& search_frame_sink_id) const {
468 auto iter = frame_sink_source_map_.find(child_frame_sink_id);
469 if (iter == frame_sink_source_map_.end())
470 return false;
471
472 const std::vector<FrameSinkId>& children = iter->second.children;
473 for (size_t i = 0; i < children.size(); ++i) {
474 if (children[i] == search_frame_sink_id)
475 return true;
476 if (ChildContains(children[i], search_frame_sink_id))
477 return true;
478 }
479 return false;
480 }
481
482 void SurfaceManager::RegisterFrameSinkHierarchy(
483 const FrameSinkId& parent_frame_sink_id,
484 const FrameSinkId& child_frame_sink_id) {
485 DCHECK_EQ(valid_frame_sink_ids_.count(parent_frame_sink_id), 1u);
486 DCHECK_EQ(valid_frame_sink_ids_.count(child_frame_sink_id), 1u);
487
488 // If it's possible to reach the parent through the child's descendant chain,
489 // then this will create an infinite loop. Might as well just crash here.
490 CHECK(!ChildContains(child_frame_sink_id, parent_frame_sink_id));
491
492 std::vector<FrameSinkId>& children =
493 frame_sink_source_map_[parent_frame_sink_id].children;
494 for (size_t i = 0; i < children.size(); ++i)
495 DCHECK(children[i] != child_frame_sink_id);
496 children.push_back(child_frame_sink_id);
497
498 // If the parent has no source, then attaching it to this child will
499 // not change any downstream sources.
500 BeginFrameSource* parent_source =
501 frame_sink_source_map_[parent_frame_sink_id].source;
502 if (!parent_source)
503 return;
504
505 DCHECK_EQ(registered_sources_.count(parent_source), 1u);
506 RecursivelyAttachBeginFrameSource(child_frame_sink_id, parent_source);
507 }
508
509 void SurfaceManager::UnregisterFrameSinkHierarchy(
510 const FrameSinkId& parent_frame_sink_id,
511 const FrameSinkId& child_frame_sink_id) {
512 // Deliberately do not check validity of either parent or child namespace
513 // here. They were valid during the registration, so were valid at some
514 // point in time. This makes it possible to invalidate parent and child
515 // namespaces independently of each other and not have an ordering dependency
516 // of unregistering the hierarchy first before either of them.
517 DCHECK_EQ(frame_sink_source_map_.count(parent_frame_sink_id), 1u);
518
519 auto iter = frame_sink_source_map_.find(parent_frame_sink_id);
520
521 std::vector<FrameSinkId>& children = iter->second.children;
522 bool found_child = false;
523 for (size_t i = 0; i < children.size(); ++i) {
524 if (children[i] == child_frame_sink_id) {
525 found_child = true;
526 children[i] = children.back();
527 children.resize(children.size() - 1);
528 break;
529 }
530 }
531 DCHECK(found_child);
532
533 // The SurfaceFactoryClient and hierarchy can be registered/unregistered
534 // in either order, so empty namespace_client_map entries need to be
535 // checked when removing either clients or relationships.
536 if (iter->second.is_empty()) {
537 frame_sink_source_map_.erase(iter);
538 return;
539 }
540
541 // If the parent does not have a begin frame source, then disconnecting it
542 // will not change any of its children.
543 BeginFrameSource* parent_source = iter->second.source;
544 if (!parent_source)
545 return;
546
547 // TODO(enne): these walks could be done in one step.
548 RecursivelyDetachBeginFrameSource(child_frame_sink_id, parent_source);
549 for (auto source_iter : registered_sources_)
550 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first);
551 }
552
553 Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) { 342 Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) {
554 DCHECK(thread_checker_.CalledOnValidThread()); 343 DCHECK(thread_checker_.CalledOnValidThread());
555 SurfaceMap::iterator it = surface_map_.find(surface_id); 344 SurfaceMap::iterator it = surface_map_.find(surface_id);
556 if (it == surface_map_.end()) 345 if (it == surface_map_.end())
557 return nullptr; 346 return nullptr;
558 return it->second; 347 return it->second;
559 } 348 }
560 349
561 bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id) { 350 bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id) {
562 CHECK(thread_checker_.CalledOnValidThread()); 351 CHECK(thread_checker_.CalledOnValidThread());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); 403 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end());
615 std::sort(children.begin(), children.end()); 404 std::sort(children.begin(), children.end());
616 405
617 for (const SurfaceId& child_id : children) 406 for (const SurfaceId& child_id : children)
618 SurfaceReferencesToStringImpl(child_id, indent + " ", str); 407 SurfaceReferencesToStringImpl(child_id, indent + " ", str);
619 } 408 }
620 } 409 }
621 #endif // DCHECK_IS_ON() 410 #endif // DCHECK_IS_ON()
622 411
623 } // namespace cc 412 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698