| OLD | NEW |
| 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/local_surface_id_allocator.h" | 15 #include "cc/surfaces/local_surface_id_allocator.h" |
| 16 #include "cc/surfaces/surface.h" | 16 #include "cc/surfaces/surface.h" |
| 17 #include "cc/surfaces/surface_factory_client.h" | 17 #include "cc/surfaces/surface_factory_client.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() | 26 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping() |
| 27 : client(nullptr), source(nullptr) {} | 27 : source(nullptr) {} |
| 28 | 28 |
| 29 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping( | 29 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping( |
| 30 const FrameSinkSourceMapping& other) = default; | 30 const FrameSinkSourceMapping& other) = default; |
| 31 | 31 |
| 32 SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() { | 32 SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() { |
| 33 DCHECK(is_empty()) << "client: " << client | |
| 34 << ", children: " << children.size(); | |
| 35 } | 33 } |
| 36 | 34 |
| 37 SurfaceManager::SurfaceManager(LifetimeType lifetime_type) | 35 SurfaceManager::SurfaceManager(LifetimeType lifetime_type) |
| 38 : lifetime_type_(lifetime_type), | 36 : lifetime_type_(lifetime_type), |
| 39 root_surface_id_(FrameSinkId(0u, 0u), | 37 root_surface_id_(FrameSinkId(0u, 0u), |
| 40 LocalSurfaceId(1u, base::UnguessableToken::Create())), | 38 LocalSurfaceId(1u, base::UnguessableToken::Create())), |
| 41 weak_factory_(this) { | 39 weak_factory_(this) { |
| 42 thread_checker_.DetachFromThread(); | 40 thread_checker_.DetachFromThread(); |
| 43 reference_factory_ = | 41 reference_factory_ = |
| 44 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr()); | 42 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 55 GarbageCollectSurfaces(); | 53 GarbageCollectSurfaces(); |
| 56 } | 54 } |
| 57 | 55 |
| 58 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); | 56 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); |
| 59 it != surfaces_to_destroy_.end(); | 57 it != surfaces_to_destroy_.end(); |
| 60 ++it) { | 58 ++it) { |
| 61 DeregisterSurface((*it)->surface_id()); | 59 DeregisterSurface((*it)->surface_id()); |
| 62 } | 60 } |
| 63 surfaces_to_destroy_.clear(); | 61 surfaces_to_destroy_.clear(); |
| 64 | 62 |
| 65 // All hierarchies, sources, and surface factory clients should be | 63 // All surface factory clients should be unregistered prior to SurfaceManager |
| 66 // unregistered prior to SurfaceManager destruction. | 64 // destruction. |
| 67 DCHECK_EQ(frame_sink_source_map_.size(), 0u); | 65 DCHECK_EQ(clients_.size(), 0u); |
| 68 DCHECK_EQ(registered_sources_.size(), 0u); | 66 DCHECK_EQ(registered_sources_.size(), 0u); |
| 69 } | 67 } |
| 70 | 68 |
| 71 #if DCHECK_IS_ON() | 69 #if DCHECK_IS_ON() |
| 72 std::string SurfaceManager::SurfaceReferencesToString() { | 70 std::string SurfaceManager::SurfaceReferencesToString() { |
| 73 std::stringstream str; | 71 std::stringstream str; |
| 74 SurfaceReferencesToStringImpl(root_surface_id_, "", &str); | 72 SurfaceReferencesToStringImpl(root_surface_id_, "", &str); |
| 75 // Temporary references will have an asterisk in front of them. | 73 // Temporary references will have an asterisk in front of them. |
| 76 for (auto& map_entry : temporary_references_) | 74 for (auto& map_entry : temporary_references_) |
| 77 SurfaceReferencesToStringImpl(map_entry.first, "* ", &str); | 75 SurfaceReferencesToStringImpl(map_entry.first, "* ", &str); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 if (frame_sink_temp_refs.empty()) | 391 if (frame_sink_temp_refs.empty()) |
| 394 temporary_reference_ranges_.erase(frame_sink_id); | 392 temporary_reference_ranges_.erase(frame_sink_id); |
| 395 } | 393 } |
| 396 | 394 |
| 397 void SurfaceManager::RegisterSurfaceFactoryClient( | 395 void SurfaceManager::RegisterSurfaceFactoryClient( |
| 398 const FrameSinkId& frame_sink_id, | 396 const FrameSinkId& frame_sink_id, |
| 399 SurfaceFactoryClient* client) { | 397 SurfaceFactoryClient* client) { |
| 400 DCHECK(client); | 398 DCHECK(client); |
| 401 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); | 399 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); |
| 402 | 400 |
| 403 // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary. | 401 clients_[frame_sink_id] = client; |
| 404 FrameSinkSourceMapping& frame_sink_source = | |
| 405 frame_sink_source_map_[frame_sink_id]; | |
| 406 DCHECK(!frame_sink_source.client); | |
| 407 frame_sink_source.client = client; | |
| 408 | 402 |
| 409 // Propagate any previously set sources to the new client. | 403 auto it = frame_sink_source_map_.find(frame_sink_id); |
| 410 if (frame_sink_source.source) | 404 if (it != frame_sink_source_map_.end()) { |
| 411 client->SetBeginFrameSource(frame_sink_source.source); | 405 if (it->second.source) |
| 406 client->SetBeginFrameSource(it->second.source); |
| 407 } |
| 412 } | 408 } |
| 413 | 409 |
| 414 void SurfaceManager::UnregisterSurfaceFactoryClient( | 410 void SurfaceManager::UnregisterSurfaceFactoryClient( |
| 415 const FrameSinkId& frame_sink_id) { | 411 const FrameSinkId& frame_sink_id) { |
| 416 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); | 412 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); |
| 417 DCHECK_EQ(frame_sink_source_map_.count(frame_sink_id), 1u); | 413 auto client_iter = clients_.find(frame_sink_id); |
| 414 DCHECK(client_iter != clients_.end()); |
| 418 | 415 |
| 419 auto iter = frame_sink_source_map_.find(frame_sink_id); | 416 auto source_iter = frame_sink_source_map_.find(frame_sink_id); |
| 420 if (iter->second.source) | 417 if (source_iter != frame_sink_source_map_.end()) { |
| 421 iter->second.client->SetBeginFrameSource(nullptr); | 418 if (source_iter->second.source) |
| 422 iter->second.client = nullptr; | 419 client_iter->second->SetBeginFrameSource(nullptr); |
| 423 | 420 if (!source_iter->second.has_children()) |
| 424 // The SurfaceFactoryClient and hierarchy can be registered/unregistered | 421 frame_sink_source_map_.erase(source_iter); |
| 425 // in either order, so empty namespace_client_map entries need to be | 422 } |
| 426 // checked when removing either clients or relationships. | 423 clients_.erase(client_iter); |
| 427 if (iter->second.is_empty()) | |
| 428 frame_sink_source_map_.erase(iter); | |
| 429 } | 424 } |
| 430 | 425 |
| 431 void SurfaceManager::RegisterBeginFrameSource( | 426 void SurfaceManager::RegisterBeginFrameSource( |
| 432 BeginFrameSource* source, | 427 BeginFrameSource* source, |
| 433 const FrameSinkId& frame_sink_id) { | 428 const FrameSinkId& frame_sink_id) { |
| 434 DCHECK(source); | 429 DCHECK(source); |
| 435 DCHECK_EQ(registered_sources_.count(source), 0u); | 430 DCHECK_EQ(registered_sources_.count(source), 0u); |
| 436 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); | 431 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); |
| 437 | 432 |
| 438 registered_sources_[source] = frame_sink_id; | 433 registered_sources_[source] = frame_sink_id; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 457 for (auto source_iter : registered_sources_) | 452 for (auto source_iter : registered_sources_) |
| 458 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first); | 453 RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first); |
| 459 } | 454 } |
| 460 | 455 |
| 461 void SurfaceManager::RecursivelyAttachBeginFrameSource( | 456 void SurfaceManager::RecursivelyAttachBeginFrameSource( |
| 462 const FrameSinkId& frame_sink_id, | 457 const FrameSinkId& frame_sink_id, |
| 463 BeginFrameSource* source) { | 458 BeginFrameSource* source) { |
| 464 FrameSinkSourceMapping& mapping = frame_sink_source_map_[frame_sink_id]; | 459 FrameSinkSourceMapping& mapping = frame_sink_source_map_[frame_sink_id]; |
| 465 if (!mapping.source) { | 460 if (!mapping.source) { |
| 466 mapping.source = source; | 461 mapping.source = source; |
| 467 if (mapping.client) | 462 auto client_iter = clients_.find(frame_sink_id); |
| 468 mapping.client->SetBeginFrameSource(source); | 463 if (client_iter != clients_.end()) |
| 464 client_iter->second->SetBeginFrameSource(source); |
| 469 } | 465 } |
| 470 for (size_t i = 0; i < mapping.children.size(); ++i) | 466 for (size_t i = 0; i < mapping.children.size(); ++i) |
| 471 RecursivelyAttachBeginFrameSource(mapping.children[i], source); | 467 RecursivelyAttachBeginFrameSource(mapping.children[i], source); |
| 472 } | 468 } |
| 473 | 469 |
| 474 void SurfaceManager::RecursivelyDetachBeginFrameSource( | 470 void SurfaceManager::RecursivelyDetachBeginFrameSource( |
| 475 const FrameSinkId& frame_sink_id, | 471 const FrameSinkId& frame_sink_id, |
| 476 BeginFrameSource* source) { | 472 BeginFrameSource* source) { |
| 477 auto iter = frame_sink_source_map_.find(frame_sink_id); | 473 auto iter = frame_sink_source_map_.find(frame_sink_id); |
| 478 if (iter == frame_sink_source_map_.end()) | 474 if (iter == frame_sink_source_map_.end()) |
| 479 return; | 475 return; |
| 480 if (iter->second.source == source) { | 476 if (iter->second.source == source) { |
| 481 iter->second.source = nullptr; | 477 iter->second.source = nullptr; |
| 482 if (iter->second.client) | 478 auto client_iter = clients_.find(frame_sink_id); |
| 483 iter->second.client->SetBeginFrameSource(nullptr); | 479 if (client_iter != clients_.end()) |
| 480 client_iter->second->SetBeginFrameSource(nullptr); |
| 484 } | 481 } |
| 485 | 482 |
| 486 if (iter->second.is_empty()) { | 483 if (!iter->second.has_children() && !clients_.count(frame_sink_id)) { |
| 487 frame_sink_source_map_.erase(iter); | 484 frame_sink_source_map_.erase(iter); |
| 488 return; | 485 return; |
| 489 } | 486 } |
| 490 | 487 |
| 491 std::vector<FrameSinkId>& children = iter->second.children; | 488 std::vector<FrameSinkId>& children = iter->second.children; |
| 492 for (size_t i = 0; i < children.size(); ++i) { | 489 for (size_t i = 0; i < children.size(); ++i) { |
| 493 RecursivelyDetachBeginFrameSource(children[i], source); | 490 RecursivelyDetachBeginFrameSource(children[i], source); |
| 494 } | 491 } |
| 495 } | 492 } |
| 496 | 493 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 if (!parent_source) | 528 if (!parent_source) |
| 532 return; | 529 return; |
| 533 | 530 |
| 534 DCHECK_EQ(registered_sources_.count(parent_source), 1u); | 531 DCHECK_EQ(registered_sources_.count(parent_source), 1u); |
| 535 RecursivelyAttachBeginFrameSource(child_frame_sink_id, parent_source); | 532 RecursivelyAttachBeginFrameSource(child_frame_sink_id, parent_source); |
| 536 } | 533 } |
| 537 | 534 |
| 538 void SurfaceManager::UnregisterFrameSinkHierarchy( | 535 void SurfaceManager::UnregisterFrameSinkHierarchy( |
| 539 const FrameSinkId& parent_frame_sink_id, | 536 const FrameSinkId& parent_frame_sink_id, |
| 540 const FrameSinkId& child_frame_sink_id) { | 537 const FrameSinkId& child_frame_sink_id) { |
| 541 // Deliberately do not check validity of either parent or child namespace | 538 // Deliberately do not check validity of either parent or child FrameSinkId |
| 542 // here. They were valid during the registration, so were valid at some | 539 // here. They were valid during the registration, so were valid at some |
| 543 // point in time. This makes it possible to invalidate parent and child | 540 // point in time. This makes it possible to invalidate parent and child |
| 544 // namespaces independently of each other and not have an ordering dependency | 541 // FrameSinkIds independently of each other and not have an ordering |
| 545 // of unregistering the hierarchy first before either of them. | 542 // dependency of unregistering the hierarchy first before either of them. |
| 546 DCHECK_EQ(frame_sink_source_map_.count(parent_frame_sink_id), 1u); | 543 DCHECK_EQ(frame_sink_source_map_.count(parent_frame_sink_id), 1u); |
| 547 | 544 |
| 548 auto iter = frame_sink_source_map_.find(parent_frame_sink_id); | 545 auto iter = frame_sink_source_map_.find(parent_frame_sink_id); |
| 549 | 546 |
| 550 std::vector<FrameSinkId>& children = iter->second.children; | 547 std::vector<FrameSinkId>& children = iter->second.children; |
| 551 bool found_child = false; | 548 bool found_child = false; |
| 552 for (size_t i = 0; i < children.size(); ++i) { | 549 for (size_t i = 0; i < children.size(); ++i) { |
| 553 if (children[i] == child_frame_sink_id) { | 550 if (children[i] == child_frame_sink_id) { |
| 554 found_child = true; | 551 found_child = true; |
| 555 children[i] = children.back(); | 552 children[i] = children.back(); |
| 556 children.resize(children.size() - 1); | 553 children.resize(children.size() - 1); |
| 557 break; | 554 break; |
| 558 } | 555 } |
| 559 } | 556 } |
| 560 DCHECK(found_child); | 557 DCHECK(found_child); |
| 561 | 558 |
| 562 // The SurfaceFactoryClient and hierarchy can be registered/unregistered | 559 // The SurfaceFactoryClient and hierarchy can be registered/unregistered |
| 563 // in either order, so empty namespace_client_map entries need to be | 560 // in either order, so empty frame_sink_source_map entries need to be |
| 564 // checked when removing either clients or relationships. | 561 // checked when removing either clients or relationships. |
| 565 if (iter->second.is_empty()) { | 562 if (!iter->second.has_children() && !clients_.count(parent_frame_sink_id)) { |
| 566 frame_sink_source_map_.erase(iter); | 563 frame_sink_source_map_.erase(iter); |
| 567 return; | 564 return; |
| 568 } | 565 } |
| 569 | 566 |
| 570 // If the parent does not have a begin frame source, then disconnecting it | 567 // If the parent does not have a begin frame source, then disconnecting it |
| 571 // will not change any of its children. | 568 // will not change any of its children. |
| 572 BeginFrameSource* parent_source = iter->second.source; | 569 BeginFrameSource* parent_source = iter->second.source; |
| 573 if (!parent_source) | 570 if (!parent_source) |
| 574 return; | 571 return; |
| 575 | 572 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); | 657 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); |
| 661 std::sort(children.begin(), children.end()); | 658 std::sort(children.begin(), children.end()); |
| 662 | 659 |
| 663 for (const SurfaceId& child_id : children) | 660 for (const SurfaceId& child_id : children) |
| 664 SurfaceReferencesToStringImpl(child_id, indent + " ", str); | 661 SurfaceReferencesToStringImpl(child_id, indent + " ", str); |
| 665 } | 662 } |
| 666 } | 663 } |
| 667 #endif // DCHECK_IS_ON() | 664 #endif // DCHECK_IS_ON() |
| 668 | 665 |
| 669 } // namespace cc | 666 } // namespace cc |
| OLD | NEW |