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

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

Issue 2940183002: cc: Move ownership of surfaces to SurfaceManager (Closed)
Patch Set: Address comments Created 3 years, 5 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 <algorithm> 10 #include <algorithm>
(...skipping 20 matching lines...) Expand all
31 SurfaceManager::SurfaceManager(LifetimeType lifetime_type) 31 SurfaceManager::SurfaceManager(LifetimeType lifetime_type)
32 : lifetime_type_(lifetime_type), 32 : lifetime_type_(lifetime_type),
33 root_surface_id_(FrameSinkId(0u, 0u), 33 root_surface_id_(FrameSinkId(0u, 0u),
34 LocalSurfaceId(1u, base::UnguessableToken::Create())), 34 LocalSurfaceId(1u, base::UnguessableToken::Create())),
35 weak_factory_(this) { 35 weak_factory_(this) {
36 thread_checker_.DetachFromThread(); 36 thread_checker_.DetachFromThread();
37 reference_factory_ = 37 reference_factory_ =
38 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr()); 38 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr());
39 } 39 }
40 40
41 SurfaceManager::~SurfaceManager() { 41 SurfaceManager::~SurfaceManager() = default;
danakj 2017/06/27 18:21:32 should we dcheck that all surfaces are destroyed b
Saman Sami 2017/06/28 14:19:43 All Surfaces are owned by SurfaceManager. When it'
danakj 2017/06/28 15:59:45 What about during the lifetime of the browser? I d
Saman Sami 2017/06/28 18:01:00 We can check if all the remaining surfaces in the
danakj 2017/06/28 18:16:24 Ok thanks. That's better than nothing, though woul
42 DCHECK(thread_checker_.CalledOnValidThread());
43
44 // Remove all temporary references on shutdown.
45 temporary_references_.clear();
46 temporary_reference_ranges_.clear();
47
48 GarbageCollectSurfaces();
49
50 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
51 it != surfaces_to_destroy_.end();
52 ++it) {
53 UnregisterSurface((*it)->surface_id());
54 }
55 surfaces_to_destroy_.clear();
56 }
57 42
58 #if DCHECK_IS_ON() 43 #if DCHECK_IS_ON()
59 std::string SurfaceManager::SurfaceReferencesToString() { 44 std::string SurfaceManager::SurfaceReferencesToString() {
60 std::stringstream str; 45 std::stringstream str;
61 SurfaceReferencesToStringImpl(root_surface_id_, "", &str); 46 SurfaceReferencesToStringImpl(root_surface_id_, "", &str);
62 // Temporary references will have an asterisk in front of them. 47 // Temporary references will have an asterisk in front of them.
63 for (auto& map_entry : temporary_references_) 48 for (auto& map_entry : temporary_references_)
64 SurfaceReferencesToStringImpl(map_entry.first, "* ", &str); 49 SurfaceReferencesToStringImpl(map_entry.first, "* ", &str);
65 50
66 return str.str(); 51 return str.str();
67 } 52 }
68 #endif 53 #endif
69 54
70 void SurfaceManager::SetDependencyTracker( 55 void SurfaceManager::SetDependencyTracker(
71 SurfaceDependencyTracker* dependency_tracker) { 56 SurfaceDependencyTracker* dependency_tracker) {
72 dependency_tracker_ = dependency_tracker; 57 dependency_tracker_ = dependency_tracker;
73 } 58 }
74 59
75 void SurfaceManager::RequestSurfaceResolution(Surface* pending_surface) { 60 void SurfaceManager::RequestSurfaceResolution(Surface* pending_surface) {
76 if (dependency_tracker_) 61 if (dependency_tracker_)
77 dependency_tracker_->RequestSurfaceResolution(pending_surface); 62 dependency_tracker_->RequestSurfaceResolution(pending_surface);
78 } 63 }
79 64
80 std::unique_ptr<Surface> SurfaceManager::CreateSurface( 65 Surface* SurfaceManager::CreateSurface(
81 base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support, 66 base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support,
82 const SurfaceInfo& surface_info) { 67 const SurfaceInfo& surface_info) {
83 DCHECK(thread_checker_.CalledOnValidThread()); 68 DCHECK(thread_checker_.CalledOnValidThread());
84 DCHECK(surface_info.is_valid()); 69 DCHECK(surface_info.is_valid());
85 DCHECK(compositor_frame_sink_support); 70 DCHECK(compositor_frame_sink_support);
86 DCHECK_EQ(surface_info.id().frame_sink_id(), 71 DCHECK_EQ(surface_info.id().frame_sink_id(),
87 compositor_frame_sink_support->frame_sink_id()); 72 compositor_frame_sink_support->frame_sink_id());
88 73
89 // If no surface with this SurfaceId exists, simply create the surface and 74 // If no surface with this SurfaceId exists, simply create the surface and
90 // return. 75 // return.
91 auto surface_iter = surface_map_.find(surface_info.id()); 76 auto it = surface_map_.find(surface_info.id());
92 if (surface_iter == surface_map_.end()) { 77 if (it == surface_map_.end()) {
93 auto surface = 78 surface_map_[surface_info.id()] =
94 base::MakeUnique<Surface>(surface_info, compositor_frame_sink_support); 79 base::MakeUnique<Surface>(surface_info, compositor_frame_sink_support);
95 surface_map_[surface->surface_id()] = surface.get(); 80 return surface_map_[surface_info.id()].get();
96 return surface;
97 } 81 }
98 82
99 // If a surface with this SurfaceId exists and it's not marked as destroyed, 83 // 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 84 // Otherwise, we wouldn't receive a request to reuse the same SurfaceId.
101 // SurfaceId. 85 // Remove the surface out of the garbage collector's queue and reuse it.
102 DCHECK(surface_iter->second->destroyed()); 86 Surface* surface = it->second.get();
103 87 DCHECK(IsMarkedForDestruction(surface_info.id()));
104 // If a surface with this SurfaceId exists and it's marked as destroyed, 88 surfaces_to_destroy_.erase(surface_info.id());
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);
116 DCHECK_EQ(compositor_frame_sink_support.get(), 89 DCHECK_EQ(compositor_frame_sink_support.get(),
117 surface->compositor_frame_sink_support().get()); 90 surface->compositor_frame_sink_support().get());
118 return surface; 91 return surface;
119 } 92 }
120 93
121 void SurfaceManager::DestroySurface(std::unique_ptr<Surface> surface) { 94 void SurfaceManager::DestroySurface(const SurfaceId& surface_id) {
122 DCHECK(thread_checker_.CalledOnValidThread()); 95 DCHECK(thread_checker_.CalledOnValidThread());
123 surface->set_destroyed(true); 96 DCHECK(surface_map_.count(surface_id));
97 if (IsMarkedForDestruction(surface_id))
danakj 2017/06/27 18:21:32 We want to be able to destroy a surface twice?
Saman Sami 2017/06/28 14:19:43 I think I can get rid of this now. Earlier patch s
98 return;
124 for (auto& observer : observer_list_) 99 for (auto& observer : observer_list_)
125 observer.OnSurfaceDestroyed(surface->surface_id()); 100 observer.OnSurfaceDestroyed(surface_id);
126 surfaces_to_destroy_.push_back(std::move(surface)); 101 surfaces_to_destroy_.insert(surface_id);
127 GarbageCollectSurfaces(); 102 GarbageCollectSurfaces();
128 } 103 }
129 104
130 void SurfaceManager::SurfaceWillDraw(const SurfaceId& surface_id) { 105 void SurfaceManager::SurfaceWillDraw(const SurfaceId& surface_id) {
131 DCHECK(thread_checker_.CalledOnValidThread()); 106 DCHECK(thread_checker_.CalledOnValidThread());
132 for (auto& observer : observer_list_) 107 for (auto& observer : observer_list_)
133 observer.OnSurfaceWillDraw(surface_id); 108 observer.OnSurfaceWillDraw(surface_id);
134 } 109 }
135 110
136 void SurfaceManager::RequireSequence(const SurfaceId& surface_id, 111 void SurfaceManager::RequireSequence(const SurfaceId& surface_id,
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 206 }
232 207
233 void SurfaceManager::GarbageCollectSurfaces() { 208 void SurfaceManager::GarbageCollectSurfaces() {
234 if (surfaces_to_destroy_.empty()) 209 if (surfaces_to_destroy_.empty())
235 return; 210 return;
236 211
237 SurfaceIdSet reachable_surfaces = using_surface_references() 212 SurfaceIdSet reachable_surfaces = using_surface_references()
238 ? GetLiveSurfacesForReferences() 213 ? GetLiveSurfacesForReferences()
239 : GetLiveSurfacesForSequences(); 214 : GetLiveSurfacesForSequences();
240 215
241 std::vector<std::unique_ptr<Surface>> surfaces_to_delete; 216 std::vector<SurfaceId> surfaces_to_delete;
242 217
243 // Delete all destroyed and unreachable surfaces. 218 // Delete all destroyed and unreachable surfaces.
244 for (auto iter = surfaces_to_destroy_.begin(); 219 for (auto iter = surfaces_to_destroy_.begin();
245 iter != surfaces_to_destroy_.end();) { 220 iter != surfaces_to_destroy_.end();) {
246 SurfaceId surface_id = (*iter)->surface_id(); 221 if (reachable_surfaces.count(*iter) == 0) {
247 if (reachable_surfaces.count(surface_id) == 0) { 222 surfaces_to_delete.push_back(*iter);
248 UnregisterSurface(surface_id);
249 surfaces_to_delete.push_back(std::move(*iter));
250 iter = surfaces_to_destroy_.erase(iter); 223 iter = surfaces_to_destroy_.erase(iter);
251 } else { 224 } else {
252 ++iter; 225 ++iter;
253 } 226 }
254 } 227 }
255 228
256 // ~Surface() draw callback could modify |surfaces_to_destroy_|. 229 // ~Surface() draw callback could modify |surfaces_to_destroy_|.
257 surfaces_to_delete.clear(); 230 for (const SurfaceId& surface_id : surfaces_to_delete)
231 DestroySurfaceInternal(surface_id);
258 } 232 }
259 233
260 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { 234 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() {
261 DCHECK(using_surface_references()); 235 DCHECK(using_surface_references());
262 236
263 SurfaceIdSet reachable_surfaces; 237 SurfaceIdSet reachable_surfaces;
264 238
265 // Walk down from the root and mark each SurfaceId we encounter as reachable. 239 // Walk down from the root and mark each SurfaceId we encounter as reachable.
266 std::queue<SurfaceId> surface_queue; 240 std::queue<SurfaceId> surface_queue;
267 surface_queue.push(root_surface_id_); 241 surface_queue.push(root_surface_id_);
(...skipping 23 matching lines...) Expand all
291 // Simple mark and sweep GC. 265 // Simple mark and sweep GC.
292 // TODO(jbauman): Reduce the amount of work when nothing needs to be 266 // TODO(jbauman): Reduce the amount of work when nothing needs to be
293 // destroyed. 267 // destroyed.
294 std::vector<SurfaceId> live_surfaces; 268 std::vector<SurfaceId> live_surfaces;
295 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; 269 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set;
296 270
297 // GC roots are surfaces that have not been destroyed, or have not had all 271 // GC roots are surfaces that have not been destroyed, or have not had all
298 // their destruction dependencies satisfied. 272 // their destruction dependencies satisfied.
299 for (auto& map_entry : surface_map_) { 273 for (auto& map_entry : surface_map_) {
300 const SurfaceId& surface_id = map_entry.first; 274 const SurfaceId& surface_id = map_entry.first;
301 Surface* surface = map_entry.second; 275 Surface* surface = map_entry.second.get();
302 surface->SatisfyDestructionDependencies(&satisfied_sequences_, 276 surface->SatisfyDestructionDependencies(&satisfied_sequences_,
303 framesink_manager_.GetValidFrameSinkIds()); 277 framesink_manager_.GetValidFrameSinkIds());
304 278
305 if (!surface->destroyed() || surface->GetDestructionDependencyCount() > 0) { 279 if (!IsMarkedForDestruction(surface_id) ||
280 surface->GetDestructionDependencyCount() > 0) {
306 live_surfaces_set.insert(surface_id); 281 live_surfaces_set.insert(surface_id);
307 live_surfaces.push_back(surface_id); 282 live_surfaces.push_back(surface_id);
308 } 283 }
309 } 284 }
310 285
311 // Mark all surfaces reachable from live surfaces by adding them to 286 // Mark all surfaces reachable from live surfaces by adding them to
312 // live_surfaces and live_surfaces_set. 287 // live_surfaces and live_surfaces_set.
313 for (size_t i = 0; i < live_surfaces.size(); i++) { 288 for (size_t i = 0; i < live_surfaces.size(); i++) {
314 Surface* surf = surface_map_[live_surfaces[i]]; 289 Surface* surf = surface_map_[live_surfaces[i]].get();
315 DCHECK(surf); 290 DCHECK(surf);
316 291
317 const auto& children = GetSurfacesReferencedByParent(surf->surface_id()); 292 const auto& children = GetSurfacesReferencedByParent(surf->surface_id());
318 for (const SurfaceId& id : children) { 293 for (const SurfaceId& id : children) {
319 if (live_surfaces_set.count(id)) 294 if (live_surfaces_set.count(id))
320 continue; 295 continue;
321 296
322 Surface* surf2 = GetSurfaceForId(id); 297 Surface* surf2 = GetSurfaceForId(id);
323 if (surf2) { 298 if (surf2) {
324 live_surfaces.push_back(id); 299 live_surfaces.push_back(id);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 const FrameSinkId& child_frame_sink_id) { 436 const FrameSinkId& child_frame_sink_id) {
462 framesink_manager_.UnregisterFrameSinkHierarchy(parent_frame_sink_id, 437 framesink_manager_.UnregisterFrameSinkHierarchy(parent_frame_sink_id,
463 child_frame_sink_id); 438 child_frame_sink_id);
464 } 439 }
465 440
466 Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) { 441 Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) {
467 DCHECK(thread_checker_.CalledOnValidThread()); 442 DCHECK(thread_checker_.CalledOnValidThread());
468 SurfaceMap::iterator it = surface_map_.find(surface_id); 443 SurfaceMap::iterator it = surface_map_.find(surface_id);
469 if (it == surface_map_.end()) 444 if (it == surface_map_.end())
470 return nullptr; 445 return nullptr;
471 return it->second; 446 return it->second.get();
472 } 447 }
473 448
474 bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id, 449 bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id,
475 const BeginFrameAck& ack) { 450 const BeginFrameAck& ack) {
476 CHECK(thread_checker_.CalledOnValidThread()); 451 CHECK(thread_checker_.CalledOnValidThread());
477 bool changed = false; 452 bool changed = false;
478 for (auto& observer : observer_list_) 453 for (auto& observer : observer_list_)
479 changed |= observer.OnSurfaceDamaged(surface_id, ack); 454 changed |= observer.OnSurfaceDamaged(surface_id, ack);
480 return changed; 455 return changed;
481 } 456 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 dependency_tracker_->OnSurfaceDiscarded(surface); 494 dependency_tracker_->OnSurfaceDiscarded(surface);
520 } 495 }
521 496
522 void SurfaceManager::SurfaceDamageExpected(const SurfaceId& surface_id, 497 void SurfaceManager::SurfaceDamageExpected(const SurfaceId& surface_id,
523 const BeginFrameArgs& args) { 498 const BeginFrameArgs& args) {
524 DCHECK(thread_checker_.CalledOnValidThread()); 499 DCHECK(thread_checker_.CalledOnValidThread());
525 for (auto& observer : observer_list_) 500 for (auto& observer : observer_list_)
526 observer.OnSurfaceDamageExpected(surface_id, args); 501 observer.OnSurfaceDamageExpected(surface_id, args);
527 } 502 }
528 503
529 void SurfaceManager::UnregisterSurface(const SurfaceId& surface_id) { 504 void SurfaceManager::DestroySurfaceInternal(const SurfaceId& surface_id) {
530 DCHECK(thread_checker_.CalledOnValidThread()); 505 DCHECK(thread_checker_.CalledOnValidThread());
531 SurfaceMap::iterator it = surface_map_.find(surface_id); 506 SurfaceMap::iterator it = surface_map_.find(surface_id);
532 DCHECK(it != surface_map_.end()); 507 DCHECK(it != surface_map_.end());
508 std::unique_ptr<Surface> doomed = std::move(it->second);
danakj 2017/06/27 18:21:31 do you mean to keep this |doomed| alive until the
Saman Sami 2017/06/28 14:19:44 Yes, I want the surface to be removed from the map
danakj 2017/06/28 15:59:45 Can you explain this in a comment? Is there a test
Saman Sami 2017/06/28 18:01:00 Sure. CompositorFrameSinkSupportTest_AddDuringEvic
533 surface_map_.erase(it); 509 surface_map_.erase(it);
534 RemoveAllSurfaceReferences(surface_id); 510 RemoveAllSurfaceReferences(surface_id);
535 } 511 }
536 512
537 #if DCHECK_IS_ON() 513 #if DCHECK_IS_ON()
538 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, 514 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id,
539 std::string indent, 515 std::string indent,
540 std::stringstream* str) { 516 std::stringstream* str) {
541 *str << indent; 517 *str << indent;
542 518
543 // Print the current line for |surface_id|. 519 // Print the current line for |surface_id|.
544 Surface* surface = GetSurfaceForId(surface_id); 520 Surface* surface = GetSurfaceForId(surface_id);
545 if (surface) { 521 if (surface) {
546 *str << surface->surface_id().ToString(); 522 *str << surface->surface_id().ToString();
547 *str << (surface->destroyed() ? " destroyed" : " live"); 523 *str << (IsMarkedForDestruction(surface_id) ? " destroyed" : " live");
548 524
549 if (surface->HasPendingFrame()) { 525 if (surface->HasPendingFrame()) {
550 // This provides the surface size from the root render pass. 526 // This provides the surface size from the root render pass.
551 const CompositorFrame& frame = surface->GetPendingFrame(); 527 const CompositorFrame& frame = surface->GetPendingFrame();
552 *str << " pending " 528 *str << " pending "
553 << frame.render_pass_list.back()->output_rect.size().ToString(); 529 << frame.render_pass_list.back()->output_rect.size().ToString();
554 } 530 }
555 531
556 if (surface->HasActiveFrame()) { 532 if (surface->HasActiveFrame()) {
557 // This provides the surface size from the root render pass. 533 // This provides the surface size from the root render pass.
558 const CompositorFrame& frame = surface->GetActiveFrame(); 534 const CompositorFrame& frame = surface->GetActiveFrame();
559 *str << " active " 535 *str << " active "
560 << frame.render_pass_list.back()->output_rect.size().ToString(); 536 << frame.render_pass_list.back()->output_rect.size().ToString();
561 } 537 }
562 } else { 538 } else {
563 *str << surface_id; 539 *str << surface_id;
564 } 540 }
565 *str << "\n"; 541 *str << "\n";
566 542
567 // 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
568 // references for each child. 544 // references for each child.
569 for (const SurfaceId& child_id : GetSurfacesReferencedByParent(surface_id)) 545 for (const SurfaceId& child_id : GetSurfacesReferencedByParent(surface_id))
570 SurfaceReferencesToStringImpl(child_id, indent + " ", str); 546 SurfaceReferencesToStringImpl(child_id, indent + " ", str);
571 } 547 }
572 #endif // DCHECK_IS_ON() 548 #endif // DCHECK_IS_ON()
573 549
550 bool SurfaceManager::IsMarkedForDestruction(const SurfaceId& surface_id) {
551 return surfaces_to_destroy_.count(surface_id) != 0;
552 }
553
574 } // namespace cc 554 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698