| 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 <algorithm> | 10 #include <algorithm> |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 SurfaceManager::~SurfaceManager() { | 41 SurfaceManager::~SurfaceManager() { |
| 42 DCHECK(thread_checker_.CalledOnValidThread()); | 42 DCHECK(thread_checker_.CalledOnValidThread()); |
| 43 | 43 |
| 44 // Remove all temporary references on shutdown. | 44 // Remove all temporary references on shutdown. |
| 45 temporary_references_.clear(); | 45 temporary_references_.clear(); |
| 46 temporary_reference_ranges_.clear(); | 46 temporary_reference_ranges_.clear(); |
| 47 | 47 |
| 48 GarbageCollectSurfaces(); | 48 GarbageCollectSurfaces(); |
| 49 | 49 |
| 50 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); | 50 for (auto it = surfaces_to_destroy_.begin(); it != surfaces_to_destroy_.end(); |
| 51 it != surfaces_to_destroy_.end(); | |
| 52 ++it) { | 51 ++it) { |
| 53 UnregisterSurface((*it)->surface_id()); | 52 DestroySurfaceInternal((*it)->surface_id()); |
| 54 } | 53 } |
| 55 surfaces_to_destroy_.clear(); | 54 surfaces_to_destroy_.clear(); |
| 56 } | 55 } |
| 57 | 56 |
| 58 #if DCHECK_IS_ON() | 57 #if DCHECK_IS_ON() |
| 59 std::string SurfaceManager::SurfaceReferencesToString() { | 58 std::string SurfaceManager::SurfaceReferencesToString() { |
| 60 std::stringstream str; | 59 std::stringstream str; |
| 61 SurfaceReferencesToStringImpl(root_surface_id_, "", &str); | 60 SurfaceReferencesToStringImpl(root_surface_id_, "", &str); |
| 62 // Temporary references will have an asterisk in front of them. | 61 // Temporary references will have an asterisk in front of them. |
| 63 for (auto& map_entry : temporary_references_) | 62 for (auto& map_entry : temporary_references_) |
| 64 SurfaceReferencesToStringImpl(map_entry.first, "* ", &str); | 63 SurfaceReferencesToStringImpl(map_entry.first, "* ", &str); |
| 65 | 64 |
| 66 return str.str(); | 65 return str.str(); |
| 67 } | 66 } |
| 68 #endif | 67 #endif |
| 69 | 68 |
| 70 void SurfaceManager::SetDependencyTracker( | 69 void SurfaceManager::SetDependencyTracker( |
| 71 SurfaceDependencyTracker* dependency_tracker) { | 70 SurfaceDependencyTracker* dependency_tracker) { |
| 72 dependency_tracker_ = dependency_tracker; | 71 dependency_tracker_ = dependency_tracker; |
| 73 } | 72 } |
| 74 | 73 |
| 75 void SurfaceManager::RequestSurfaceResolution(Surface* pending_surface) { | 74 void SurfaceManager::RequestSurfaceResolution(Surface* pending_surface) { |
| 76 if (dependency_tracker_) | 75 if (dependency_tracker_) |
| 77 dependency_tracker_->RequestSurfaceResolution(pending_surface); | 76 dependency_tracker_->RequestSurfaceResolution(pending_surface); |
| 78 } | 77 } |
| 79 | 78 |
| 80 std::unique_ptr<Surface> SurfaceManager::CreateSurface( | 79 Surface* SurfaceManager::CreateSurface( |
| 81 base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support, | 80 base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support, |
| 82 const SurfaceInfo& surface_info) { | 81 const SurfaceInfo& surface_info) { |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); | 82 DCHECK(thread_checker_.CalledOnValidThread()); |
| 84 DCHECK(surface_info.is_valid()); | 83 DCHECK(surface_info.is_valid()); |
| 85 DCHECK(compositor_frame_sink_support); | 84 DCHECK(compositor_frame_sink_support); |
| 86 DCHECK_EQ(surface_info.id().frame_sink_id(), | 85 DCHECK_EQ(surface_info.id().frame_sink_id(), |
| 87 compositor_frame_sink_support->frame_sink_id()); | 86 compositor_frame_sink_support->frame_sink_id()); |
| 88 | 87 |
| 89 // If no surface with this SurfaceId exists, simply create the surface and | 88 // If no surface with this SurfaceId exists, simply create the surface and |
| 90 // return. | 89 // return. |
| 91 auto surface_iter = surface_map_.find(surface_info.id()); | 90 auto it = surface_map_.find(surface_info.id()); |
| 92 if (surface_iter == surface_map_.end()) { | 91 if (it == surface_map_.end()) { |
| 93 auto surface = | 92 surface_map_[surface_info.id()] = |
| 94 base::MakeUnique<Surface>(surface_info, compositor_frame_sink_support); | 93 base::MakeUnique<Surface>(surface_info, compositor_frame_sink_support); |
| 95 surface_map_[surface->surface_id()] = surface.get(); | 94 return surface_map_[surface_info.id()].get(); |
| 96 return surface; | |
| 97 } | 95 } |
| 98 | 96 |
| 99 // If a surface with this SurfaceId exists and it's not marked as destroyed, | 97 // If a surface with this SurfaceId exists, it must be marked as destroyed. |
| 100 // we should not receive a request to create a new surface with the same | 98 // Otherwise, we wouldn't receive a request to reuse the same SurfaceId. |
| 101 // SurfaceId. | 99 // Remove the surface out of the garbage collector's queue and reuse it. |
| 102 DCHECK(surface_iter->second->destroyed()); | 100 Surface* surface = it->second.get(); |
| 103 | 101 DCHECK(surface->destroyed()); |
| 104 // If a surface with this SurfaceId exists and it's marked as destroyed, | 102 surfaces_to_destroy_.erase(surface); |
| 105 // it means it's in the garbage collector's queue. We simply take it out of | |
| 106 // the queue and reuse it. | |
| 107 auto it = | |
| 108 std::find_if(surfaces_to_destroy_.begin(), surfaces_to_destroy_.end(), | |
| 109 [&surface_info](const std::unique_ptr<Surface>& surface) { | |
| 110 return surface->surface_id() == surface_info.id(); | |
| 111 }); | |
| 112 DCHECK(it != surfaces_to_destroy_.end()); | |
| 113 std::unique_ptr<Surface> surface = std::move(*it); | |
| 114 surfaces_to_destroy_.erase(it); | |
| 115 surface->set_destroyed(false); | 103 surface->set_destroyed(false); |
| 116 DCHECK_EQ(compositor_frame_sink_support.get(), | 104 DCHECK_EQ(compositor_frame_sink_support.get(), |
| 117 surface->compositor_frame_sink_support().get()); | 105 surface->compositor_frame_sink_support().get()); |
| 118 return surface; | 106 return surface; |
| 119 } | 107 } |
| 120 | 108 |
| 121 void SurfaceManager::DestroySurface(std::unique_ptr<Surface> surface) { | 109 void SurfaceManager::DestroySurface(Surface* surface) { |
| 122 DCHECK(thread_checker_.CalledOnValidThread()); | 110 DCHECK(thread_checker_.CalledOnValidThread()); |
| 123 surface->set_destroyed(true); | 111 surface->set_destroyed(true); |
| 124 for (auto& observer : observer_list_) | 112 for (auto& observer : observer_list_) |
| 125 observer.OnSurfaceDestroyed(surface->surface_id()); | 113 observer.OnSurfaceDestroyed(surface->surface_id()); |
| 126 surfaces_to_destroy_.push_back(std::move(surface)); | 114 surfaces_to_destroy_.insert(surface); |
| 127 GarbageCollectSurfaces(); | 115 GarbageCollectSurfaces(); |
| 128 } | 116 } |
| 129 | 117 |
| 130 void SurfaceManager::RequireSequence(const SurfaceId& surface_id, | 118 void SurfaceManager::RequireSequence(const SurfaceId& surface_id, |
| 131 const SurfaceSequence& sequence) { | 119 const SurfaceSequence& sequence) { |
| 132 auto* surface = GetSurfaceForId(surface_id); | 120 auto* surface = GetSurfaceForId(surface_id); |
| 133 if (!surface) { | 121 if (!surface) { |
| 134 DLOG(ERROR) << "Attempting to require callback on nonexistent surface"; | 122 DLOG(ERROR) << "Attempting to require callback on nonexistent surface"; |
| 135 return; | 123 return; |
| 136 } | 124 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 } | 213 } |
| 226 | 214 |
| 227 void SurfaceManager::GarbageCollectSurfaces() { | 215 void SurfaceManager::GarbageCollectSurfaces() { |
| 228 if (surfaces_to_destroy_.empty()) | 216 if (surfaces_to_destroy_.empty()) |
| 229 return; | 217 return; |
| 230 | 218 |
| 231 SurfaceIdSet reachable_surfaces = using_surface_references() | 219 SurfaceIdSet reachable_surfaces = using_surface_references() |
| 232 ? GetLiveSurfacesForReferences() | 220 ? GetLiveSurfacesForReferences() |
| 233 : GetLiveSurfacesForSequences(); | 221 : GetLiveSurfacesForSequences(); |
| 234 | 222 |
| 235 std::vector<std::unique_ptr<Surface>> surfaces_to_delete; | |
| 236 | |
| 237 // Delete all destroyed and unreachable surfaces. | 223 // Delete all destroyed and unreachable surfaces. |
| 238 for (auto iter = surfaces_to_destroy_.begin(); | 224 for (auto iter = surfaces_to_destroy_.begin(); |
| 239 iter != surfaces_to_destroy_.end();) { | 225 iter != surfaces_to_destroy_.end();) { |
| 240 SurfaceId surface_id = (*iter)->surface_id(); | 226 SurfaceId surface_id = (*iter)->surface_id(); |
| 241 if (reachable_surfaces.count(surface_id) == 0) { | 227 if (reachable_surfaces.count(surface_id) == 0) { |
| 242 UnregisterSurface(surface_id); | 228 DestroySurfaceInternal(surface_id); |
| 243 surfaces_to_delete.push_back(std::move(*iter)); | |
| 244 iter = surfaces_to_destroy_.erase(iter); | 229 iter = surfaces_to_destroy_.erase(iter); |
| 245 } else { | 230 } else { |
| 246 ++iter; | 231 ++iter; |
| 247 } | 232 } |
| 248 } | 233 } |
| 249 | |
| 250 // ~Surface() draw callback could modify |surfaces_to_destroy_|. | |
| 251 surfaces_to_delete.clear(); | |
| 252 } | 234 } |
| 253 | 235 |
| 254 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { | 236 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { |
| 255 DCHECK(using_surface_references()); | 237 DCHECK(using_surface_references()); |
| 256 | 238 |
| 257 SurfaceIdSet reachable_surfaces; | 239 SurfaceIdSet reachable_surfaces; |
| 258 | 240 |
| 259 // Walk down from the root and mark each SurfaceId we encounter as reachable. | 241 // Walk down from the root and mark each SurfaceId we encounter as reachable. |
| 260 std::queue<SurfaceId> surface_queue; | 242 std::queue<SurfaceId> surface_queue; |
| 261 surface_queue.push(root_surface_id_); | 243 surface_queue.push(root_surface_id_); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 285 // Simple mark and sweep GC. | 267 // Simple mark and sweep GC. |
| 286 // TODO(jbauman): Reduce the amount of work when nothing needs to be | 268 // TODO(jbauman): Reduce the amount of work when nothing needs to be |
| 287 // destroyed. | 269 // destroyed. |
| 288 std::vector<SurfaceId> live_surfaces; | 270 std::vector<SurfaceId> live_surfaces; |
| 289 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; | 271 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; |
| 290 | 272 |
| 291 // GC roots are surfaces that have not been destroyed, or have not had all | 273 // GC roots are surfaces that have not been destroyed, or have not had all |
| 292 // their destruction dependencies satisfied. | 274 // their destruction dependencies satisfied. |
| 293 for (auto& map_entry : surface_map_) { | 275 for (auto& map_entry : surface_map_) { |
| 294 const SurfaceId& surface_id = map_entry.first; | 276 const SurfaceId& surface_id = map_entry.first; |
| 295 Surface* surface = map_entry.second; | 277 Surface* surface = map_entry.second.get(); |
| 296 surface->SatisfyDestructionDependencies(&satisfied_sequences_, | 278 surface->SatisfyDestructionDependencies(&satisfied_sequences_, |
| 297 framesink_manager_.GetValidFrameSinkIds()); | 279 framesink_manager_.GetValidFrameSinkIds()); |
| 298 | 280 |
| 299 if (!surface->destroyed() || surface->GetDestructionDependencyCount() > 0) { | 281 if (!surface->destroyed() || surface->GetDestructionDependencyCount() > 0) { |
| 300 live_surfaces_set.insert(surface_id); | 282 live_surfaces_set.insert(surface_id); |
| 301 live_surfaces.push_back(surface_id); | 283 live_surfaces.push_back(surface_id); |
| 302 } | 284 } |
| 303 } | 285 } |
| 304 | 286 |
| 305 // Mark all surfaces reachable from live surfaces by adding them to | 287 // Mark all surfaces reachable from live surfaces by adding them to |
| 306 // live_surfaces and live_surfaces_set. | 288 // live_surfaces and live_surfaces_set. |
| 307 for (size_t i = 0; i < live_surfaces.size(); i++) { | 289 for (size_t i = 0; i < live_surfaces.size(); i++) { |
| 308 Surface* surf = surface_map_[live_surfaces[i]]; | 290 Surface* surf = surface_map_[live_surfaces[i]].get(); |
| 309 DCHECK(surf); | 291 DCHECK(surf); |
| 310 | 292 |
| 311 const auto& children = GetSurfacesReferencedByParent(surf->surface_id()); | 293 const auto& children = GetSurfacesReferencedByParent(surf->surface_id()); |
| 312 for (const SurfaceId& id : children) { | 294 for (const SurfaceId& id : children) { |
| 313 if (live_surfaces_set.count(id)) | 295 if (live_surfaces_set.count(id)) |
| 314 continue; | 296 continue; |
| 315 | 297 |
| 316 Surface* surf2 = GetSurfaceForId(id); | 298 Surface* surf2 = GetSurfaceForId(id); |
| 317 if (surf2) { | 299 if (surf2) { |
| 318 live_surfaces.push_back(id); | 300 live_surfaces.push_back(id); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 const FrameSinkId& child_frame_sink_id) { | 437 const FrameSinkId& child_frame_sink_id) { |
| 456 framesink_manager_.UnregisterFrameSinkHierarchy(parent_frame_sink_id, | 438 framesink_manager_.UnregisterFrameSinkHierarchy(parent_frame_sink_id, |
| 457 child_frame_sink_id); | 439 child_frame_sink_id); |
| 458 } | 440 } |
| 459 | 441 |
| 460 Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) { | 442 Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) { |
| 461 DCHECK(thread_checker_.CalledOnValidThread()); | 443 DCHECK(thread_checker_.CalledOnValidThread()); |
| 462 SurfaceMap::iterator it = surface_map_.find(surface_id); | 444 SurfaceMap::iterator it = surface_map_.find(surface_id); |
| 463 if (it == surface_map_.end()) | 445 if (it == surface_map_.end()) |
| 464 return nullptr; | 446 return nullptr; |
| 465 return it->second; | 447 return it->second.get(); |
| 466 } | 448 } |
| 467 | 449 |
| 468 bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id, | 450 bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id, |
| 469 const BeginFrameAck& ack) { | 451 const BeginFrameAck& ack) { |
| 470 CHECK(thread_checker_.CalledOnValidThread()); | 452 CHECK(thread_checker_.CalledOnValidThread()); |
| 471 bool changed = false; | 453 bool changed = false; |
| 472 for (auto& observer : observer_list_) | 454 for (auto& observer : observer_list_) |
| 473 changed |= observer.OnSurfaceDamaged(surface_id, ack); | 455 changed |= observer.OnSurfaceDamaged(surface_id, ack); |
| 474 return changed; | 456 return changed; |
| 475 } | 457 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 dependency_tracker_->OnSurfaceDiscarded(surface); | 495 dependency_tracker_->OnSurfaceDiscarded(surface); |
| 514 } | 496 } |
| 515 | 497 |
| 516 void SurfaceManager::SurfaceDamageExpected(const SurfaceId& surface_id, | 498 void SurfaceManager::SurfaceDamageExpected(const SurfaceId& surface_id, |
| 517 const BeginFrameArgs& args) { | 499 const BeginFrameArgs& args) { |
| 518 DCHECK(thread_checker_.CalledOnValidThread()); | 500 DCHECK(thread_checker_.CalledOnValidThread()); |
| 519 for (auto& observer : observer_list_) | 501 for (auto& observer : observer_list_) |
| 520 observer.OnSurfaceDamageExpected(surface_id, args); | 502 observer.OnSurfaceDamageExpected(surface_id, args); |
| 521 } | 503 } |
| 522 | 504 |
| 523 void SurfaceManager::UnregisterSurface(const SurfaceId& surface_id) { | 505 void SurfaceManager::DestroySurfaceInternal(const SurfaceId& surface_id) { |
| 524 DCHECK(thread_checker_.CalledOnValidThread()); | 506 DCHECK(thread_checker_.CalledOnValidThread()); |
| 525 SurfaceMap::iterator it = surface_map_.find(surface_id); | 507 SurfaceMap::iterator it = surface_map_.find(surface_id); |
| 526 DCHECK(it != surface_map_.end()); | 508 DCHECK(it != surface_map_.end()); |
| 527 surface_map_.erase(it); | 509 surface_map_.erase(it); |
| 528 RemoveAllSurfaceReferences(surface_id); | 510 RemoveAllSurfaceReferences(surface_id); |
| 529 } | 511 } |
| 530 | 512 |
| 531 #if DCHECK_IS_ON() | 513 #if DCHECK_IS_ON() |
| 532 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, | 514 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, |
| 533 std::string indent, | 515 std::string indent, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 559 *str << "\n"; | 541 *str << "\n"; |
| 560 | 542 |
| 561 // If the current surface has references to children, sort children and print | 543 // If the current surface has references to children, sort children and print |
| 562 // references for each child. | 544 // references for each child. |
| 563 for (const SurfaceId& child_id : GetSurfacesReferencedByParent(surface_id)) | 545 for (const SurfaceId& child_id : GetSurfacesReferencedByParent(surface_id)) |
| 564 SurfaceReferencesToStringImpl(child_id, indent + " ", str); | 546 SurfaceReferencesToStringImpl(child_id, indent + " ", str); |
| 565 } | 547 } |
| 566 #endif // DCHECK_IS_ON() | 548 #endif // DCHECK_IS_ON() |
| 567 | 549 |
| 568 } // namespace cc | 550 } // namespace cc |
| OLD | NEW |