Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |