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

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

Issue 2716553004: Add temporary reference ownership to SurfaceManager. (Closed)
Patch Set: Cleanup. 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>
(...skipping 29 matching lines...) Expand all
40 LocalSurfaceId(1u, base::UnguessableToken::Create())), 40 LocalSurfaceId(1u, base::UnguessableToken::Create())),
41 weak_factory_(this) { 41 weak_factory_(this) {
42 thread_checker_.DetachFromThread(); 42 thread_checker_.DetachFromThread();
43 reference_factory_ = 43 reference_factory_ =
44 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr()); 44 new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr());
45 } 45 }
46 46
47 SurfaceManager::~SurfaceManager() { 47 SurfaceManager::~SurfaceManager() {
48 DCHECK(thread_checker_.CalledOnValidThread()); 48 DCHECK(thread_checker_.CalledOnValidThread());
49 49
50 if (lifetime_type_ == LifetimeType::REFERENCES) { 50 if (using_surface_references()) {
51 // Remove all temporary references on shutdown. 51 // Remove all temporary references on shutdown.
52 for (const auto& map_entry : temp_references_) { 52 temporary_references_.clear();
53 const FrameSinkId& frame_sink_id = map_entry.first; 53 temporary_reference_ranges_.clear();
54 for (const auto& local_surface_id : map_entry.second) { 54
55 RemoveSurfaceReferenceImpl(GetRootSurfaceId(),
56 SurfaceId(frame_sink_id, local_surface_id));
57 }
58 }
59 GarbageCollectSurfaces(); 55 GarbageCollectSurfaces();
60 } 56 }
61 57
62 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); 58 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
63 it != surfaces_to_destroy_.end(); 59 it != surfaces_to_destroy_.end();
64 ++it) { 60 ++it) {
65 DeregisterSurface((*it)->surface_id()); 61 DeregisterSurface((*it)->surface_id());
66 } 62 }
67 surfaces_to_destroy_.clear(); 63 surfaces_to_destroy_.clear();
68 64
69 // All hierarchies, sources, and surface factory clients should be 65 // All hierarchies, sources, and surface factory clients should be
70 // unregistered prior to SurfaceManager destruction. 66 // unregistered prior to SurfaceManager destruction.
71 DCHECK_EQ(frame_sink_source_map_.size(), 0u); 67 DCHECK_EQ(frame_sink_source_map_.size(), 0u);
72 DCHECK_EQ(registered_sources_.size(), 0u); 68 DCHECK_EQ(registered_sources_.size(), 0u);
73 } 69 }
74 70
75 #if DCHECK_IS_ON() 71 #if DCHECK_IS_ON()
76 std::string SurfaceManager::SurfaceReferencesToString() { 72 std::string SurfaceManager::SurfaceReferencesToString() {
77 std::stringstream str; 73 std::stringstream str;
78 SurfaceReferencesToStringImpl(root_surface_id_, "", &str); 74 SurfaceReferencesToStringImpl(root_surface_id_, "", &str);
75 // Temporary references will have an asterix in front of them.
Fady Samuel 2017/02/24 18:10:15 s/asterix/asterisk
kylechar 2017/02/24 19:57:29 Done.
76 for (auto& map_entry : temporary_references_)
77 SurfaceReferencesToStringImpl(map_entry.first, "* ", &str);
78
79 return str.str(); 79 return str.str();
80 } 80 }
81 #endif 81 #endif
82 82
83 void SurfaceManager::SetDependencyTracker( 83 void SurfaceManager::SetDependencyTracker(
84 std::unique_ptr<SurfaceDependencyTracker> dependency_tracker) { 84 std::unique_ptr<SurfaceDependencyTracker> dependency_tracker) {
85 dependency_tracker_ = std::move(dependency_tracker); 85 dependency_tracker_ = std::move(dependency_tracker);
86 } 86 }
87 87
88 void SurfaceManager::RequestSurfaceResolution(Surface* pending_surface) { 88 void SurfaceManager::RequestSurfaceResolution(Surface* pending_surface) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 GarbageCollectSurfaces(); 129 GarbageCollectSurfaces();
130 } 130 }
131 131
132 void SurfaceManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) { 132 void SurfaceManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) {
133 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second; 133 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second;
134 DCHECK(inserted); 134 DCHECK(inserted);
135 } 135 }
136 136
137 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) { 137 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) {
138 valid_frame_sink_ids_.erase(frame_sink_id); 138 valid_frame_sink_ids_.erase(frame_sink_id);
139
140 if (using_surface_references()) {
141 // Remove any temporary references owned by |frame_sink_id|.
142 std::vector<SurfaceId> temp_refs_to_clear;
143 for (auto& map_entry : temporary_references_) {
144 base::Optional<FrameSinkId>& owner = map_entry.second;
145 if (owner.has_value() && owner.value() == frame_sink_id)
146 temp_refs_to_clear.push_back(map_entry.first);
147 }
148
149 for (auto& surface_id : temp_refs_to_clear)
150 RemoveTemporaryReference(surface_id, false);
151 }
152
139 GarbageCollectSurfaces(); 153 GarbageCollectSurfaces();
140 } 154 }
141 155
142 const SurfaceId& SurfaceManager::GetRootSurfaceId() const { 156 const SurfaceId& SurfaceManager::GetRootSurfaceId() const {
143 return root_surface_id_; 157 return root_surface_id_;
144 } 158 }
145 159
146 void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id,
147 const SurfaceId& child_id) {
148 DCHECK(thread_checker_.CalledOnValidThread());
149 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
150
151 // Check some conditions that should never happen. We don't want to crash on
152 // bad input from a compromised client so just return early.
153 if (parent_id.frame_sink_id() == child_id.frame_sink_id()) {
154 DLOG(ERROR) << "Cannot add self reference from " << parent_id << " to "
155 << child_id;
156 return;
157 }
158
159 // There could be a temporary reference to |child_id| which we should now
160 // remove because a real reference is being added to it. To find out whether
161 // or not a temporary reference exists, we need to first look up the
162 // FrameSinkId of |child_id| in |temp_references_|, which returns a vector of
163 // LocalSurfaceIds, and then search for the LocalSurfaceId of |child_id| in
164 // the said vector. If there is no temporary reference, we can immediately add
165 // the reference from |parent_id| and return.
166 auto refs_iter = temp_references_.find(child_id.frame_sink_id());
167 if (refs_iter == temp_references_.end()) {
168 AddSurfaceReferenceImpl(parent_id, child_id);
169 return;
170 }
171 std::vector<LocalSurfaceId>& refs = refs_iter->second;
172 auto temp_ref_iter =
173 std::find(refs.begin(), refs.end(), child_id.local_surface_id());
174 if (temp_ref_iter == refs.end()) {
175 AddSurfaceReferenceImpl(parent_id, child_id);
176 return;
177 }
178
179 // Temporary references are implemented by holding a reference from the top
180 // level root to the child. If |parent_id| is the top level root, we do
181 // nothing because the reference already exists. Otherwise, remove the
182 // temporary reference and add the reference.
183 if (parent_id != GetRootSurfaceId()) {
184 AddSurfaceReferenceImpl(parent_id, child_id);
185 RemoveSurfaceReference(GetRootSurfaceId(), child_id);
186 }
187
188 // Remove temporary references for surfaces with the same FrameSinkId that
189 // were created before |child_id|. The earlier surfaces were never embedded in
190 // the parent and the parent is embedding a later surface, so we know the
191 // parent doesn't need them anymore.
192 for (auto iter = refs.begin(); iter != temp_ref_iter; ++iter) {
193 SurfaceId id = SurfaceId(child_id.frame_sink_id(), *iter);
194 RemoveSurfaceReference(GetRootSurfaceId(), id);
195 }
196
197 // Remove markers for temporary references up to |child_id|, as the temporary
198 // references they correspond to were removed above. If |temp_ref_iter| points
199 // at the last element in |refs| then we are removing all temporary references
200 // for the FrameSinkId and can remove the map entry entirely.
201 if (++temp_ref_iter == refs.end())
202 temp_references_.erase(child_id.frame_sink_id());
203 else
204 refs.erase(refs.begin(), temp_ref_iter);
205 }
206
207 void SurfaceManager::RemoveSurfaceReference(const SurfaceId& parent_id,
208 const SurfaceId& child_id) {
209 DCHECK(thread_checker_.CalledOnValidThread());
210 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
211
212 // Check if we have the reference that is requested to be removed. We don't
213 // want to crash on bad input from a compromised client so just return early.
214 if (parent_to_child_refs_.count(parent_id) == 0 ||
215 parent_to_child_refs_[parent_id].count(child_id) == 0) {
216 DLOG(ERROR) << "No reference from " << parent_id.ToString() << " to "
217 << child_id.ToString();
218 return;
219 }
220
221 RemoveSurfaceReferenceImpl(parent_id, child_id);
222 }
223
224 void SurfaceManager::AddSurfaceReferences( 160 void SurfaceManager::AddSurfaceReferences(
225 const std::vector<SurfaceReference>& references) { 161 const std::vector<SurfaceReference>& references) {
226 DCHECK(thread_checker_.CalledOnValidThread()); 162 DCHECK(thread_checker_.CalledOnValidThread());
163 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
227 164
228 for (const auto& reference : references) 165 for (const auto& reference : references)
229 AddSurfaceReference(reference.parent_id(), reference.child_id()); 166 AddSurfaceReferenceImpl(reference.parent_id(), reference.child_id());
230 } 167 }
231 168
232 void SurfaceManager::RemoveSurfaceReferences( 169 void SurfaceManager::RemoveSurfaceReferences(
233 const std::vector<SurfaceReference>& references) { 170 const std::vector<SurfaceReference>& references) {
234 DCHECK(thread_checker_.CalledOnValidThread()); 171 DCHECK(thread_checker_.CalledOnValidThread());
172 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
235 173
236 for (const auto& reference : references) 174 for (const auto& reference : references)
237 RemoveSurfaceReference(reference.parent_id(), reference.child_id()); 175 RemoveSurfaceReferenceImpl(reference.parent_id(), reference.child_id());
238 176
239 GarbageCollectSurfaces(); 177 GarbageCollectSurfaces();
240 } 178 }
241 179
180 void SurfaceManager::AssignTemporaryReference(
181 const SurfaceId& surface_id,
182 const FrameSinkId& frame_sink_id) {
183 DCHECK(thread_checker_.CalledOnValidThread());
184 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
185
186 if (!HasTemporaryReference(surface_id))
187 return;
188
189 temporary_references_[surface_id] = frame_sink_id;
190 }
191
192 void SurfaceManager::DropTemporaryReference(const SurfaceId& surface_id) {
193 DCHECK(thread_checker_.CalledOnValidThread());
194 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
195
196 if (!HasTemporaryReference(surface_id))
197 return;
198
199 RemoveTemporaryReference(surface_id, false);
200 }
201
242 void SurfaceManager::GarbageCollectSurfaces() { 202 void SurfaceManager::GarbageCollectSurfaces() {
243 if (surfaces_to_destroy_.empty()) 203 if (surfaces_to_destroy_.empty())
244 return; 204 return;
245 205
246 SurfaceIdSet reachable_surfaces = lifetime_type_ == LifetimeType::REFERENCES 206 SurfaceIdSet reachable_surfaces = using_surface_references()
247 ? GetLiveSurfacesForReferences() 207 ? GetLiveSurfacesForReferences()
248 : GetLiveSurfacesForSequences(); 208 : GetLiveSurfacesForSequences();
249 209
250 std::vector<std::unique_ptr<Surface>> surfaces_to_delete; 210 std::vector<std::unique_ptr<Surface>> surfaces_to_delete;
251 211
252 // Delete all destroyed and unreachable surfaces. 212 // Delete all destroyed and unreachable surfaces.
253 for (auto iter = surfaces_to_destroy_.begin(); 213 for (auto iter = surfaces_to_destroy_.begin();
254 iter != surfaces_to_destroy_.end();) { 214 iter != surfaces_to_destroy_.end();) {
255 SurfaceId surface_id = (*iter)->surface_id(); 215 SurfaceId surface_id = (*iter)->surface_id();
256 if (reachable_surfaces.count(surface_id) == 0) { 216 if (reachable_surfaces.count(surface_id) == 0) {
(...skipping 10 matching lines...) Expand all
267 } 227 }
268 228
269 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { 229 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() {
270 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES); 230 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
271 231
272 SurfaceIdSet reachable_surfaces; 232 SurfaceIdSet reachable_surfaces;
273 233
274 // Walk down from the root and mark each SurfaceId we encounter as reachable. 234 // Walk down from the root and mark each SurfaceId we encounter as reachable.
275 std::queue<SurfaceId> surface_queue; 235 std::queue<SurfaceId> surface_queue;
276 surface_queue.push(root_surface_id_); 236 surface_queue.push(root_surface_id_);
237
238 // All temporary references are reachable too.
239 for (auto& map_entry : temporary_references_) {
240 reachable_surfaces.insert(map_entry.first);
241 surface_queue.push(map_entry.first);
242 }
243
277 while (!surface_queue.empty()) { 244 while (!surface_queue.empty()) {
278 const SurfaceId& surface_id = surface_queue.front(); 245 const SurfaceId& surface_id = surface_queue.front();
279 auto iter = parent_to_child_refs_.find(surface_id); 246 auto iter = parent_to_child_refs_.find(surface_id);
280 if (iter != parent_to_child_refs_.end()) { 247 if (iter != parent_to_child_refs_.end()) {
281 for (const SurfaceId& child_id : iter->second) { 248 for (const SurfaceId& child_id : iter->second) {
282 // Check for cycles when inserting into |reachable_surfaces|. 249 // Check for cycles when inserting into |reachable_surfaces|.
283 if (reachable_surfaces.insert(child_id).second) 250 if (reachable_surfaces.insert(child_id).second)
284 surface_queue.push(child_id); 251 surface_queue.push(child_id);
285 } 252 }
286 } 253 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 live_surfaces_set.insert(id); 301 live_surfaces_set.insert(id);
335 } 302 }
336 } 303 }
337 } 304 }
338 305
339 return live_surfaces_set; 306 return live_surfaces_set;
340 } 307 }
341 308
342 void SurfaceManager::AddSurfaceReferenceImpl(const SurfaceId& parent_id, 309 void SurfaceManager::AddSurfaceReferenceImpl(const SurfaceId& parent_id,
343 const SurfaceId& child_id) { 310 const SurfaceId& child_id) {
311 if (parent_id.frame_sink_id() == child_id.frame_sink_id()) {
312 DLOG(ERROR) << "Cannot add self reference from " << parent_id << " to "
313 << child_id;
314 return;
315 }
316
344 parent_to_child_refs_[parent_id].insert(child_id); 317 parent_to_child_refs_[parent_id].insert(child_id);
345 child_to_parent_refs_[child_id].insert(parent_id); 318 child_to_parent_refs_[child_id].insert(parent_id);
319
320 if (HasTemporaryReference(child_id))
321 RemoveTemporaryReference(child_id, true);
346 } 322 }
347 323
348 void SurfaceManager::RemoveSurfaceReferenceImpl(const SurfaceId& parent_id, 324 void SurfaceManager::RemoveSurfaceReferenceImpl(const SurfaceId& parent_id,
349 const SurfaceId& child_id) { 325 const SurfaceId& child_id) {
326 // Check if we have the reference that is requested to be removed. We don't
327 // want to crash on bad input from a compromised client so just return early.
328 if (parent_to_child_refs_.count(parent_id) == 0 ||
329 parent_to_child_refs_[parent_id].count(child_id) == 0) {
330 DLOG(ERROR) << "No reference from " << parent_id.ToString() << " to "
331 << child_id.ToString();
332 return;
333 }
334
350 parent_to_child_refs_[parent_id].erase(child_id); 335 parent_to_child_refs_[parent_id].erase(child_id);
351 child_to_parent_refs_[child_id].erase(parent_id); 336 child_to_parent_refs_[child_id].erase(parent_id);
352 } 337 }
353 338
354 void SurfaceManager::RemoveAllSurfaceReferences(const SurfaceId& surface_id) { 339 void SurfaceManager::RemoveAllSurfaceReferences(const SurfaceId& surface_id) {
355 // Remove all references from |surface_id| to a child surface. 340 // Remove all references from |surface_id| to a child surface.
356 auto iter = parent_to_child_refs_.find(surface_id); 341 auto iter = parent_to_child_refs_.find(surface_id);
357 if (iter != parent_to_child_refs_.end()) { 342 if (iter != parent_to_child_refs_.end()) {
358 for (const SurfaceId& child_id : iter->second) 343 for (const SurfaceId& child_id : iter->second)
359 child_to_parent_refs_[child_id].erase(surface_id); 344 child_to_parent_refs_[child_id].erase(surface_id);
360 parent_to_child_refs_.erase(iter); 345 parent_to_child_refs_.erase(iter);
361 } 346 }
362 347
363 // Remove all reference from parent surface to |surface_id|. 348 // Remove all reference from parent surface to |surface_id|.
364 iter = child_to_parent_refs_.find(surface_id); 349 iter = child_to_parent_refs_.find(surface_id);
365 if (iter != child_to_parent_refs_.end()) { 350 if (iter != child_to_parent_refs_.end()) {
366 for (const SurfaceId& parent_id : iter->second) 351 for (const SurfaceId& parent_id : iter->second)
367 parent_to_child_refs_[parent_id].erase(surface_id); 352 parent_to_child_refs_[parent_id].erase(surface_id);
368 child_to_parent_refs_.erase(iter); 353 child_to_parent_refs_.erase(iter);
369 } 354 }
370 } 355 }
371 356
357 bool SurfaceManager::HasTemporaryReference(const SurfaceId& surface_id) const {
358 return temporary_references_.count(surface_id) != 0;
359 }
360
361 void SurfaceManager::AddTemporaryReference(const SurfaceId& surface_id) {
362 DCHECK(!HasTemporaryReference(surface_id));
363
364 // Add an entry to |temporary_references_| with no owner for the temporary
365 // reference. Also add a range tracking entry so we know the order that
366 // surfaces were created for the FrameSinkId.
367 temporary_references_[surface_id] = base::Optional<FrameSinkId>();
368 temporary_reference_ranges_[surface_id.frame_sink_id()].push_back(
369 surface_id.local_surface_id());
370 }
371
372 void SurfaceManager::RemoveTemporaryReference(const SurfaceId& surface_id,
373 bool remove_range) {
374 DCHECK(HasTemporaryReference(surface_id));
375
376 const FrameSinkId& frame_sink_id = surface_id.frame_sink_id();
377 std::vector<LocalSurfaceId>& frame_sink_temp_refs =
378 temporary_reference_ranges_[frame_sink_id];
379
380 // Find the iterator to the range tracking entry for |surface_id|. Use that
381 // iterator and |remove_range| to find the right begin and end iterators for
382 // the temporary references we want to remove.
383 auto surface_id_iter =
384 std::find(frame_sink_temp_refs.begin(), frame_sink_temp_refs.end(),
385 surface_id.local_surface_id());
386 auto begin_iter =
387 remove_range ? frame_sink_temp_refs.begin() : surface_id_iter;
388 auto end_iter = surface_id_iter + 1;
389
390 // Remove temporary references and range tracking information.
391 for (auto iter = begin_iter; iter != end_iter; ++iter)
392 temporary_references_.erase(SurfaceId(frame_sink_id, *iter));
393 frame_sink_temp_refs.erase(begin_iter, end_iter);
394
395 // If last temporary reference is removed for |frame_sink_id| then cleanup
396 // range tracking map entry.
397 if (frame_sink_temp_refs.empty())
398 temporary_reference_ranges_.erase(frame_sink_id);
399 }
400
372 void SurfaceManager::RegisterSurfaceFactoryClient( 401 void SurfaceManager::RegisterSurfaceFactoryClient(
373 const FrameSinkId& frame_sink_id, 402 const FrameSinkId& frame_sink_id,
374 SurfaceFactoryClient* client) { 403 SurfaceFactoryClient* client) {
375 DCHECK(client); 404 DCHECK(client);
376 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); 405 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u);
377 406
378 // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary. 407 // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary.
379 FrameSinkSourceMapping& frame_sink_source = 408 FrameSinkSourceMapping& frame_sink_source =
380 frame_sink_source_map_[frame_sink_id]; 409 frame_sink_source_map_[frame_sink_id];
381 DCHECK(!frame_sink_source.client); 410 DCHECK(!frame_sink_source.client);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 // frame. When the second frame with a new size arrives, the first will be 611 // frame. When the second frame with a new size arrives, the first will be
583 // destroyed in SurfaceFactory and then if there are no references it will 612 // destroyed in SurfaceFactory and then if there are no references it will
584 // be deleted during surface GC. A temporary reference, removed when a 613 // be deleted during surface GC. A temporary reference, removed when a
585 // real reference is received, is added to prevent this from happening. 614 // real reference is received, is added to prevent this from happening.
586 auto it = child_to_parent_refs_.find(surface_info.id()); 615 auto it = child_to_parent_refs_.find(surface_info.id());
587 // TODO(fsamuel): Tests create empty sets and so we also need to check that 616 // TODO(fsamuel): Tests create empty sets and so we also need to check that
588 // they're not empty here. Ideally tests shouldn't do that and we shouldn't 617 // they're not empty here. Ideally tests shouldn't do that and we shouldn't
589 // use array notation into maps in tests (see https://crbug.com/691115). 618 // use array notation into maps in tests (see https://crbug.com/691115).
590 bool has_real_reference = 619 bool has_real_reference =
591 it != child_to_parent_refs_.end() && !it->second.empty(); 620 it != child_to_parent_refs_.end() && !it->second.empty();
592 if (!has_real_reference) { 621 if (!has_real_reference)
593 AddSurfaceReferenceImpl(GetRootSurfaceId(), surface_info.id()); 622 AddTemporaryReference(surface_info.id());
594 temp_references_[surface_info.id().frame_sink_id()].push_back(
595 surface_info.id().local_surface_id());
596 }
597 } 623 }
598 624
599 for (auto& observer : observer_list_) 625 for (auto& observer : observer_list_)
600 observer.OnSurfaceCreated(surface_info); 626 observer.OnSurfaceCreated(surface_info);
601 } 627 }
602 628
603 #if DCHECK_IS_ON() 629 #if DCHECK_IS_ON()
604 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, 630 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id,
605 std::string indent, 631 std::string indent,
606 std::stringstream* str) { 632 std::stringstream* str) {
607 *str << indent; 633 *str << indent;
608 634
609 // Print the current line for |surface_id|. 635 // Print the current line for |surface_id|.
610 Surface* surface = GetSurfaceForId(surface_id); 636 Surface* surface = GetSurfaceForId(surface_id);
611 if (surface) { 637 if (surface) {
612 *str << surface->surface_id().ToString(); 638 *str << surface->surface_id().ToString();
613 *str << (surface->destroyed() ? " destroyed " : " live "); 639 *str << (surface->destroyed() ? " destroyed" : " live");
614 640
615 if (surface->HasPendingFrame()) { 641 if (surface->HasPendingFrame()) {
616 // This provides the surface size from the root render pass. 642 // This provides the surface size from the root render pass.
617 const CompositorFrame& frame = surface->GetPendingFrame(); 643 const CompositorFrame& frame = surface->GetPendingFrame();
618 *str << "pending " 644 if (!frame.render_pass_list.empty()) {
619 << frame.render_pass_list.back()->output_rect.size().ToString() 645 *str << " pending "
620 << " "; 646 << frame.render_pass_list.back()->output_rect.size().ToString();
647 }
621 } 648 }
622 649
623 if (surface->HasActiveFrame()) { 650 if (surface->HasActiveFrame()) {
624 // This provides the surface size from the root render pass. 651 // This provides the surface size from the root render pass.
625 const CompositorFrame& frame = surface->GetActiveFrame(); 652 const CompositorFrame& frame = surface->GetActiveFrame();
626 *str << "active " 653 if (!frame.render_pass_list.empty()) {
627 << frame.render_pass_list.back()->output_rect.size().ToString(); 654 *str << " active "
655 << frame.render_pass_list.back()->output_rect.size().ToString();
656 }
628 } 657 }
629 } else { 658 } else {
630 *str << surface_id; 659 *str << surface_id;
631 } 660 }
632 *str << "\n"; 661 *str << "\n";
633 662
634 // If the current surface has references to children, sort children and print 663 // If the current surface has references to children, sort children and print
635 // references for each child. 664 // references for each child.
636 auto iter = parent_to_child_refs_.find(surface_id); 665 auto iter = parent_to_child_refs_.find(surface_id);
637 if (iter != parent_to_child_refs_.end()) { 666 if (iter != parent_to_child_refs_.end()) {
638 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); 667 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end());
639 std::sort(children.begin(), children.end()); 668 std::sort(children.begin(), children.end());
640 669
641 for (const SurfaceId& child_id : children) 670 for (const SurfaceId& child_id : children)
642 SurfaceReferencesToStringImpl(child_id, indent + " ", str); 671 SurfaceReferencesToStringImpl(child_id, indent + " ", str);
643 } 672 }
644 } 673 }
645 #endif // DCHECK_IS_ON() 674 #endif // DCHECK_IS_ON()
646 675
647 } // namespace cc 676 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698