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> |
(...skipping 29 matching lines...) Expand all Loading... |
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 asterisk in front of them. |
| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 GarbageCollectSurfaces(); | 139 GarbageCollectSurfaces(); |
140 } | 140 } |
141 | 141 |
142 const SurfaceId& SurfaceManager::GetRootSurfaceId() const { | 142 const SurfaceId& SurfaceManager::GetRootSurfaceId() const { |
143 return root_surface_id_; | 143 return root_surface_id_; |
144 } | 144 } |
145 | 145 |
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( | 146 void SurfaceManager::AddSurfaceReferences( |
225 const std::vector<SurfaceReference>& references) { | 147 const std::vector<SurfaceReference>& references) { |
226 DCHECK(thread_checker_.CalledOnValidThread()); | 148 DCHECK(thread_checker_.CalledOnValidThread()); |
| 149 DCHECK(using_surface_references()); |
227 | 150 |
228 for (const auto& reference : references) | 151 for (const auto& reference : references) |
229 AddSurfaceReference(reference.parent_id(), reference.child_id()); | 152 AddSurfaceReferenceImpl(reference.parent_id(), reference.child_id()); |
230 } | 153 } |
231 | 154 |
232 void SurfaceManager::RemoveSurfaceReferences( | 155 void SurfaceManager::RemoveSurfaceReferences( |
233 const std::vector<SurfaceReference>& references) { | 156 const std::vector<SurfaceReference>& references) { |
234 DCHECK(thread_checker_.CalledOnValidThread()); | 157 DCHECK(thread_checker_.CalledOnValidThread()); |
| 158 DCHECK(using_surface_references()); |
235 | 159 |
236 for (const auto& reference : references) | 160 for (const auto& reference : references) |
237 RemoveSurfaceReference(reference.parent_id(), reference.child_id()); | 161 RemoveSurfaceReferenceImpl(reference.parent_id(), reference.child_id()); |
238 | 162 |
239 GarbageCollectSurfaces(); | 163 GarbageCollectSurfaces(); |
240 } | 164 } |
241 | 165 |
242 void SurfaceManager::GarbageCollectSurfaces() { | 166 void SurfaceManager::GarbageCollectSurfaces() { |
243 if (surfaces_to_destroy_.empty()) | 167 if (surfaces_to_destroy_.empty()) |
244 return; | 168 return; |
245 | 169 |
246 SurfaceIdSet reachable_surfaces = lifetime_type_ == LifetimeType::REFERENCES | 170 SurfaceIdSet reachable_surfaces = using_surface_references() |
247 ? GetLiveSurfacesForReferences() | 171 ? GetLiveSurfacesForReferences() |
248 : GetLiveSurfacesForSequences(); | 172 : GetLiveSurfacesForSequences(); |
249 | 173 |
250 std::vector<std::unique_ptr<Surface>> surfaces_to_delete; | 174 std::vector<std::unique_ptr<Surface>> surfaces_to_delete; |
251 | 175 |
252 // Delete all destroyed and unreachable surfaces. | 176 // Delete all destroyed and unreachable surfaces. |
253 for (auto iter = surfaces_to_destroy_.begin(); | 177 for (auto iter = surfaces_to_destroy_.begin(); |
254 iter != surfaces_to_destroy_.end();) { | 178 iter != surfaces_to_destroy_.end();) { |
255 SurfaceId surface_id = (*iter)->surface_id(); | 179 SurfaceId surface_id = (*iter)->surface_id(); |
256 if (reachable_surfaces.count(surface_id) == 0) { | 180 if (reachable_surfaces.count(surface_id) == 0) { |
257 DeregisterSurface(surface_id); | 181 DeregisterSurface(surface_id); |
258 surfaces_to_delete.push_back(std::move(*iter)); | 182 surfaces_to_delete.push_back(std::move(*iter)); |
259 iter = surfaces_to_destroy_.erase(iter); | 183 iter = surfaces_to_destroy_.erase(iter); |
260 } else { | 184 } else { |
261 ++iter; | 185 ++iter; |
262 } | 186 } |
263 } | 187 } |
264 | 188 |
265 // ~Surface() draw callback could modify |surfaces_to_destroy_|. | 189 // ~Surface() draw callback could modify |surfaces_to_destroy_|. |
266 surfaces_to_delete.clear(); | 190 surfaces_to_delete.clear(); |
267 } | 191 } |
268 | 192 |
269 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { | 193 SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { |
270 DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES); | 194 DCHECK(using_surface_references()); |
271 | 195 |
272 SurfaceIdSet reachable_surfaces; | 196 SurfaceIdSet reachable_surfaces; |
273 | 197 |
274 // Walk down from the root and mark each SurfaceId we encounter as reachable. | 198 // Walk down from the root and mark each SurfaceId we encounter as reachable. |
275 std::queue<SurfaceId> surface_queue; | 199 std::queue<SurfaceId> surface_queue; |
276 surface_queue.push(root_surface_id_); | 200 surface_queue.push(root_surface_id_); |
| 201 |
| 202 // All temporary references are also reachable. |
| 203 for (auto& map_entry : temporary_references_) { |
| 204 reachable_surfaces.insert(map_entry.first); |
| 205 surface_queue.push(map_entry.first); |
| 206 } |
| 207 |
277 while (!surface_queue.empty()) { | 208 while (!surface_queue.empty()) { |
278 const SurfaceId& surface_id = surface_queue.front(); | 209 const SurfaceId& surface_id = surface_queue.front(); |
279 auto iter = parent_to_child_refs_.find(surface_id); | 210 auto iter = parent_to_child_refs_.find(surface_id); |
280 if (iter != parent_to_child_refs_.end()) { | 211 if (iter != parent_to_child_refs_.end()) { |
281 for (const SurfaceId& child_id : iter->second) { | 212 for (const SurfaceId& child_id : iter->second) { |
282 // Check for cycles when inserting into |reachable_surfaces|. | 213 // Check for cycles when inserting into |reachable_surfaces|. |
283 if (reachable_surfaces.insert(child_id).second) | 214 if (reachable_surfaces.insert(child_id).second) |
284 surface_queue.push(child_id); | 215 surface_queue.push(child_id); |
285 } | 216 } |
286 } | 217 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 live_surfaces_set.insert(id); | 265 live_surfaces_set.insert(id); |
335 } | 266 } |
336 } | 267 } |
337 } | 268 } |
338 | 269 |
339 return live_surfaces_set; | 270 return live_surfaces_set; |
340 } | 271 } |
341 | 272 |
342 void SurfaceManager::AddSurfaceReferenceImpl(const SurfaceId& parent_id, | 273 void SurfaceManager::AddSurfaceReferenceImpl(const SurfaceId& parent_id, |
343 const SurfaceId& child_id) { | 274 const SurfaceId& child_id) { |
| 275 if (parent_id.frame_sink_id() == child_id.frame_sink_id()) { |
| 276 DLOG(ERROR) << "Cannot add self reference from " << parent_id << " to " |
| 277 << child_id; |
| 278 return; |
| 279 } |
| 280 |
344 parent_to_child_refs_[parent_id].insert(child_id); | 281 parent_to_child_refs_[parent_id].insert(child_id); |
345 child_to_parent_refs_[child_id].insert(parent_id); | 282 child_to_parent_refs_[child_id].insert(parent_id); |
| 283 |
| 284 if (HasTemporaryReference(child_id)) |
| 285 RemoveTemporaryReference(child_id, true); |
346 } | 286 } |
347 | 287 |
348 void SurfaceManager::RemoveSurfaceReferenceImpl(const SurfaceId& parent_id, | 288 void SurfaceManager::RemoveSurfaceReferenceImpl(const SurfaceId& parent_id, |
349 const SurfaceId& child_id) { | 289 const SurfaceId& child_id) { |
| 290 if (parent_to_child_refs_.count(parent_id) == 0 || |
| 291 parent_to_child_refs_[parent_id].count(child_id) == 0) { |
| 292 DLOG(ERROR) << "No reference from " << parent_id << " to " << child_id; |
| 293 return; |
| 294 } |
| 295 |
350 parent_to_child_refs_[parent_id].erase(child_id); | 296 parent_to_child_refs_[parent_id].erase(child_id); |
351 child_to_parent_refs_[child_id].erase(parent_id); | 297 child_to_parent_refs_[child_id].erase(parent_id); |
352 } | 298 } |
353 | 299 |
354 void SurfaceManager::RemoveAllSurfaceReferences(const SurfaceId& surface_id) { | 300 void SurfaceManager::RemoveAllSurfaceReferences(const SurfaceId& surface_id) { |
355 // Remove all references from |surface_id| to a child surface. | 301 // Remove all references from |surface_id| to a child surface. |
356 auto iter = parent_to_child_refs_.find(surface_id); | 302 auto iter = parent_to_child_refs_.find(surface_id); |
357 if (iter != parent_to_child_refs_.end()) { | 303 if (iter != parent_to_child_refs_.end()) { |
358 for (const SurfaceId& child_id : iter->second) | 304 for (const SurfaceId& child_id : iter->second) |
359 child_to_parent_refs_[child_id].erase(surface_id); | 305 child_to_parent_refs_[child_id].erase(surface_id); |
360 parent_to_child_refs_.erase(iter); | 306 parent_to_child_refs_.erase(iter); |
361 } | 307 } |
362 | 308 |
363 // Remove all reference from parent surface to |surface_id|. | 309 // Remove all reference from parent surface to |surface_id|. |
364 iter = child_to_parent_refs_.find(surface_id); | 310 iter = child_to_parent_refs_.find(surface_id); |
365 if (iter != child_to_parent_refs_.end()) { | 311 if (iter != child_to_parent_refs_.end()) { |
366 for (const SurfaceId& parent_id : iter->second) | 312 for (const SurfaceId& parent_id : iter->second) |
367 parent_to_child_refs_[parent_id].erase(surface_id); | 313 parent_to_child_refs_[parent_id].erase(surface_id); |
368 child_to_parent_refs_.erase(iter); | 314 child_to_parent_refs_.erase(iter); |
369 } | 315 } |
370 } | 316 } |
371 | 317 |
| 318 bool SurfaceManager::HasTemporaryReference(const SurfaceId& surface_id) const { |
| 319 return temporary_references_.count(surface_id) != 0; |
| 320 } |
| 321 |
| 322 void SurfaceManager::AddTemporaryReference(const SurfaceId& surface_id) { |
| 323 DCHECK(!HasTemporaryReference(surface_id)); |
| 324 |
| 325 // Add an entry to |temporary_references_| with no owner for the temporary |
| 326 // reference. Also add a range tracking entry so we know the order that |
| 327 // surfaces were created for the FrameSinkId. |
| 328 temporary_references_[surface_id] = base::Optional<FrameSinkId>(); |
| 329 temporary_reference_ranges_[surface_id.frame_sink_id()].push_back( |
| 330 surface_id.local_surface_id()); |
| 331 } |
| 332 |
| 333 void SurfaceManager::RemoveTemporaryReference(const SurfaceId& surface_id, |
| 334 bool remove_range) { |
| 335 DCHECK(HasTemporaryReference(surface_id)); |
| 336 |
| 337 const FrameSinkId& frame_sink_id = surface_id.frame_sink_id(); |
| 338 std::vector<LocalSurfaceId>& frame_sink_temp_refs = |
| 339 temporary_reference_ranges_[frame_sink_id]; |
| 340 |
| 341 // Find the iterator to the range tracking entry for |surface_id|. Use that |
| 342 // iterator and |remove_range| to find the right begin and end iterators for |
| 343 // the temporary references we want to remove. |
| 344 auto surface_id_iter = |
| 345 std::find(frame_sink_temp_refs.begin(), frame_sink_temp_refs.end(), |
| 346 surface_id.local_surface_id()); |
| 347 auto begin_iter = |
| 348 remove_range ? frame_sink_temp_refs.begin() : surface_id_iter; |
| 349 auto end_iter = surface_id_iter + 1; |
| 350 |
| 351 // Remove temporary references and range tracking information. |
| 352 for (auto iter = begin_iter; iter != end_iter; ++iter) |
| 353 temporary_references_.erase(SurfaceId(frame_sink_id, *iter)); |
| 354 frame_sink_temp_refs.erase(begin_iter, end_iter); |
| 355 |
| 356 // If last temporary reference is removed for |frame_sink_id| then cleanup |
| 357 // range tracking map entry. |
| 358 if (frame_sink_temp_refs.empty()) |
| 359 temporary_reference_ranges_.erase(frame_sink_id); |
| 360 } |
| 361 |
372 void SurfaceManager::RegisterSurfaceFactoryClient( | 362 void SurfaceManager::RegisterSurfaceFactoryClient( |
373 const FrameSinkId& frame_sink_id, | 363 const FrameSinkId& frame_sink_id, |
374 SurfaceFactoryClient* client) { | 364 SurfaceFactoryClient* client) { |
375 DCHECK(client); | 365 DCHECK(client); |
376 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); | 366 DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); |
377 | 367 |
378 // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary. | 368 // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary. |
379 FrameSinkSourceMapping& frame_sink_source = | 369 FrameSinkSourceMapping& frame_sink_source = |
380 frame_sink_source_map_[frame_sink_id]; | 370 frame_sink_source_map_[frame_sink_id]; |
381 DCHECK(!frame_sink_source.client); | 371 DCHECK(!frame_sink_source.client); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 // frame. When the second frame with a new size arrives, the first will be | 569 // frame. When the second frame with a new size arrives, the first will be |
580 // destroyed in SurfaceFactory and then if there are no references it will | 570 // destroyed in SurfaceFactory and then if there are no references it will |
581 // be deleted during surface GC. A temporary reference, removed when a | 571 // be deleted during surface GC. A temporary reference, removed when a |
582 // real reference is received, is added to prevent this from happening. | 572 // real reference is received, is added to prevent this from happening. |
583 auto it = child_to_parent_refs_.find(surface_info.id()); | 573 auto it = child_to_parent_refs_.find(surface_info.id()); |
584 // TODO(fsamuel): Tests create empty sets and so we also need to check that | 574 // TODO(fsamuel): Tests create empty sets and so we also need to check that |
585 // they're not empty here. Ideally tests shouldn't do that and we shouldn't | 575 // they're not empty here. Ideally tests shouldn't do that and we shouldn't |
586 // use array notation into maps in tests (see https://crbug.com/691115). | 576 // use array notation into maps in tests (see https://crbug.com/691115). |
587 bool has_real_reference = | 577 bool has_real_reference = |
588 it != child_to_parent_refs_.end() && !it->second.empty(); | 578 it != child_to_parent_refs_.end() && !it->second.empty(); |
589 if (!has_real_reference) { | 579 if (!has_real_reference) |
590 AddSurfaceReferenceImpl(GetRootSurfaceId(), surface_info.id()); | 580 AddTemporaryReference(surface_info.id()); |
591 temp_references_[surface_info.id().frame_sink_id()].push_back( | |
592 surface_info.id().local_surface_id()); | |
593 } | |
594 } | 581 } |
595 | 582 |
596 for (auto& observer : observer_list_) | 583 for (auto& observer : observer_list_) |
597 observer.OnSurfaceCreated(surface_info); | 584 observer.OnSurfaceCreated(surface_info); |
598 } | 585 } |
599 | 586 |
600 #if DCHECK_IS_ON() | 587 #if DCHECK_IS_ON() |
601 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, | 588 void SurfaceManager::SurfaceReferencesToStringImpl(const SurfaceId& surface_id, |
602 std::string indent, | 589 std::string indent, |
603 std::stringstream* str) { | 590 std::stringstream* str) { |
604 *str << indent; | 591 *str << indent; |
605 | 592 |
606 // Print the current line for |surface_id|. | 593 // Print the current line for |surface_id|. |
607 Surface* surface = GetSurfaceForId(surface_id); | 594 Surface* surface = GetSurfaceForId(surface_id); |
608 if (surface) { | 595 if (surface) { |
609 *str << surface->surface_id().ToString(); | 596 *str << surface->surface_id().ToString(); |
610 *str << (surface->destroyed() ? " destroyed " : " live "); | 597 *str << (surface->destroyed() ? " destroyed" : " live"); |
611 | 598 |
612 if (surface->HasPendingFrame()) { | 599 if (surface->HasPendingFrame()) { |
613 // This provides the surface size from the root render pass. | 600 // This provides the surface size from the root render pass. |
614 const CompositorFrame& frame = surface->GetPendingFrame(); | 601 const CompositorFrame& frame = surface->GetPendingFrame(); |
615 *str << "pending " | 602 if (!frame.render_pass_list.empty()) { |
616 << frame.render_pass_list.back()->output_rect.size().ToString() | 603 *str << " pending " |
617 << " "; | 604 << frame.render_pass_list.back()->output_rect.size().ToString(); |
| 605 } |
618 } | 606 } |
619 | 607 |
620 if (surface->HasActiveFrame()) { | 608 if (surface->HasActiveFrame()) { |
621 // This provides the surface size from the root render pass. | 609 // This provides the surface size from the root render pass. |
622 const CompositorFrame& frame = surface->GetActiveFrame(); | 610 const CompositorFrame& frame = surface->GetActiveFrame(); |
623 *str << "active " | 611 if (!frame.render_pass_list.empty()) { |
624 << frame.render_pass_list.back()->output_rect.size().ToString(); | 612 *str << " active " |
| 613 << frame.render_pass_list.back()->output_rect.size().ToString(); |
| 614 } |
625 } | 615 } |
626 } else { | 616 } else { |
627 *str << surface_id; | 617 *str << surface_id; |
628 } | 618 } |
629 *str << "\n"; | 619 *str << "\n"; |
630 | 620 |
631 // If the current surface has references to children, sort children and print | 621 // If the current surface has references to children, sort children and print |
632 // references for each child. | 622 // references for each child. |
633 auto iter = parent_to_child_refs_.find(surface_id); | 623 auto iter = parent_to_child_refs_.find(surface_id); |
634 if (iter != parent_to_child_refs_.end()) { | 624 if (iter != parent_to_child_refs_.end()) { |
635 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); | 625 std::vector<SurfaceId> children(iter->second.begin(), iter->second.end()); |
636 std::sort(children.begin(), children.end()); | 626 std::sort(children.begin(), children.end()); |
637 | 627 |
638 for (const SurfaceId& child_id : children) | 628 for (const SurfaceId& child_id : children) |
639 SurfaceReferencesToStringImpl(child_id, indent + " ", str); | 629 SurfaceReferencesToStringImpl(child_id, indent + " ", str); |
640 } | 630 } |
641 } | 631 } |
642 #endif // DCHECK_IS_ON() | 632 #endif // DCHECK_IS_ON() |
643 | 633 |
644 } // namespace cc | 634 } // namespace cc |
OLD | NEW |