| 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 <utility> | 10 #include <utility> |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping( | 22 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping( |
| 23 const FrameSinkSourceMapping& other) = default; | 23 const FrameSinkSourceMapping& other) = default; |
| 24 | 24 |
| 25 SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() { | 25 SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() { |
| 26 DCHECK(is_empty()) << "client: " << client | 26 DCHECK(is_empty()) << "client: " << client |
| 27 << ", children: " << children.size(); | 27 << ", children: " << children.size(); |
| 28 } | 28 } |
| 29 | 29 |
| 30 SurfaceManager::SurfaceManager() | 30 SurfaceManager::SurfaceManager() |
| 31 : kRootSurfaceId(FrameSinkId(0u, 0u), | 31 : root_surface_id_(FrameSinkId(0u, 0u), |
| 32 LocalFrameId(0u, base::UnguessableToken::Create())) { | 32 LocalFrameId(0u, base::UnguessableToken::Create())) { |
| 33 thread_checker_.DetachFromThread(); | 33 thread_checker_.DetachFromThread(); |
| 34 } | 34 } |
| 35 | 35 |
| 36 SurfaceManager::~SurfaceManager() { | 36 SurfaceManager::~SurfaceManager() { |
| 37 DCHECK(thread_checker_.CalledOnValidThread()); | 37 DCHECK(thread_checker_.CalledOnValidThread()); |
| 38 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); | 38 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); |
| 39 it != surfaces_to_destroy_.end(); | 39 it != surfaces_to_destroy_.end(); |
| 40 ++it) { | 40 ++it) { |
| 41 DeregisterSurface((*it)->surface_id()); | 41 DeregisterSurface((*it)->surface_id()); |
| 42 } | 42 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second; | 84 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second; |
| 85 DCHECK(inserted); | 85 DCHECK(inserted); |
| 86 } | 86 } |
| 87 | 87 |
| 88 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) { | 88 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) { |
| 89 valid_frame_sink_ids_.erase(frame_sink_id); | 89 valid_frame_sink_ids_.erase(frame_sink_id); |
| 90 GarbageCollectSurfaces(); | 90 GarbageCollectSurfaces(); |
| 91 } | 91 } |
| 92 | 92 |
| 93 const SurfaceId& SurfaceManager::GetRootSurfaceId() const { | 93 const SurfaceId& SurfaceManager::GetRootSurfaceId() const { |
| 94 return kRootSurfaceId; | 94 return root_surface_id_; |
| 95 } | 95 } |
| 96 | 96 |
| 97 void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id, | 97 bool SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id, |
| 98 const SurfaceId& child_id) { | 98 const SurfaceId& child_id) { |
| 99 DCHECK(thread_checker_.CalledOnValidThread()); | 99 DCHECK(thread_checker_.CalledOnValidThread()); |
| 100 | 100 |
| 101 // Check some conditions that should never happen. We don't want to crash on | 101 // Check some conditions that should never happen. We don't want to crash on |
| 102 // bad input from a compromised client so just return early. | 102 // bad input from a compromised client so just return early. |
| 103 if (parent_id == child_id) { | 103 if (parent_id == child_id) { |
| 104 LOG(ERROR) << "Cannot add self reference for " << parent_id.ToString(); | 104 LOG(ERROR) << "Cannot add self reference for " << parent_id.ToString(); |
| 105 return; | 105 return false; |
| 106 } | 106 } |
| 107 if (parent_id != kRootSurfaceId && surface_map_.count(parent_id) == 0) { | 107 if (parent_id != root_surface_id_ && surface_map_.count(parent_id) == 0) { |
| 108 LOG(ERROR) << "No surface in map for " << parent_id.ToString(); | 108 LOG(ERROR) << "No surface in map for " << parent_id.ToString(); |
| 109 return; | 109 return false; |
| 110 } | 110 } |
| 111 if (surface_map_.count(child_id) == 0) { | 111 if (surface_map_.count(child_id) == 0) { |
| 112 LOG(ERROR) << "No surface in map for " << child_id.ToString(); | 112 LOG(ERROR) << "No surface in map for " << child_id.ToString(); |
| 113 return; | 113 return false; |
| 114 } | 114 } |
| 115 | 115 |
| 116 parent_to_child_refs_[parent_id].insert(child_id); | 116 parent_to_child_refs_[parent_id].insert(child_id); |
| 117 child_to_parent_refs_[child_id].insert(parent_id); | 117 child_to_parent_refs_[child_id].insert(parent_id); |
| 118 return true; |
| 118 } | 119 } |
| 119 | 120 |
| 120 void SurfaceManager::RemoveSurfaceReference(const SurfaceId& parent_id, | 121 bool SurfaceManager::RemoveSurfaceReference(const SurfaceId& parent_id, |
| 121 const SurfaceId& child_id) { | 122 const SurfaceId& child_id) { |
| 122 DCHECK(thread_checker_.CalledOnValidThread()); | 123 DCHECK(thread_checker_.CalledOnValidThread()); |
| 123 | 124 |
| 124 // Check if we have the reference that is requested to be removed. We don't | 125 // Check if we have the reference that is requested to be removed. We don't |
| 125 // want to crash on bad input from a compromised client so just return early. | 126 // want to crash on bad input from a compromised client so just return early. |
| 126 if (parent_to_child_refs_.count(parent_id) == 0 || | 127 if (parent_to_child_refs_.count(parent_id) == 0 || |
| 127 parent_to_child_refs_[parent_id].count(child_id) == 0) { | 128 parent_to_child_refs_[parent_id].count(child_id) == 0) { |
| 128 LOG(ERROR) << "No reference from " << parent_id.ToString() << " to " | 129 LOG(ERROR) << "No reference from " << parent_id.ToString() << " to " |
| 129 << child_id.ToString(); | 130 << child_id.ToString(); |
| 130 return; | 131 return false; |
| 131 } | 132 } |
| 132 | 133 |
| 133 RemoveSurfaceReferenceImpl(parent_id, child_id); | 134 RemoveSurfaceReferenceImpl(parent_id, child_id); |
| 134 GarbageCollectSurfaces(); | 135 GarbageCollectSurfaces(); |
| 136 return true; |
| 137 } |
| 138 |
| 139 void SurfaceManager::PrintReferenceTree(const std::string& name) { |
| 140 std::string str = "PrintReferenceTree[" + name + "]\n"; |
| 141 PrintReferenceTreeImpl(root_surface_id_, " ", &str); |
| 142 LOG(ERROR) << str; |
| 135 } | 143 } |
| 136 | 144 |
| 137 size_t SurfaceManager::GetSurfaceReferenceCount( | 145 size_t SurfaceManager::GetSurfaceReferenceCount( |
| 138 const SurfaceId& surface_id) const { | 146 const SurfaceId& surface_id) const { |
| 139 auto iter = child_to_parent_refs_.find(surface_id); | 147 auto iter = child_to_parent_refs_.find(surface_id); |
| 140 if (iter == child_to_parent_refs_.end()) | 148 if (iter == child_to_parent_refs_.end()) |
| 141 return 0; | 149 return 0; |
| 142 return iter->second.size(); | 150 return iter->second.size(); |
| 143 } | 151 } |
| 144 | 152 |
| 145 size_t SurfaceManager::GetReferencedSurfaceCount( | 153 size_t SurfaceManager::GetReferencedSurfaceCount( |
| 146 const SurfaceId& surface_id) const { | 154 const SurfaceId& surface_id) const { |
| 147 auto iter = parent_to_child_refs_.find(surface_id); | 155 auto iter = parent_to_child_refs_.find(surface_id); |
| 148 if (iter == parent_to_child_refs_.end()) | 156 if (iter == parent_to_child_refs_.end()) |
| 149 return 0; | 157 return 0; |
| 150 return iter->second.size(); | 158 return iter->second.size(); |
| 151 } | 159 } |
| 152 | 160 |
| 161 void SurfaceManager::PrintReferenceTreeImpl(const SurfaceId& surface_id, |
| 162 std::string indent, |
| 163 std::string* str) { |
| 164 Surface* surface = GetSurfaceForId(surface_id); |
| 165 std::string description; |
| 166 if (surface) { |
| 167 if (surface->destroyed()) |
| 168 description = " destroyed "; |
| 169 else |
| 170 description = " live "; |
| 171 |
| 172 if (surface->HasFrame()) { |
| 173 description += surface->GetEligibleFrame() |
| 174 .render_pass_list[0] |
| 175 ->output_rect.size() |
| 176 .ToString(); |
| 177 } |
| 178 } |
| 179 |
| 180 *str += indent + surface_id.ToString() + description + "\n"; |
| 181 auto iter = parent_to_child_refs_.find(surface_id); |
| 182 if (iter != parent_to_child_refs_.end()) { |
| 183 const SurfaceIdSet& children = iter->second; |
| 184 std::vector<SurfaceId> list(children.begin(), children.end()); |
| 185 std::sort(list.begin(), list.end()); |
| 186 for (const SurfaceId& child_id : list) { |
| 187 PrintReferenceTreeImpl(child_id, indent + " ", str); |
| 188 } |
| 189 } |
| 190 } |
| 191 |
| 153 void SurfaceManager::GarbageCollectSurfaces() { | 192 void SurfaceManager::GarbageCollectSurfaces() { |
| 154 // Simple mark and sweep GC. | 193 // Simple mark and sweep GC. |
| 155 // TODO(jbauman): Reduce the amount of work when nothing needs to be | 194 // TODO(jbauman): Reduce the amount of work when nothing needs to be |
| 156 // destroyed. | 195 // destroyed. |
| 157 std::vector<SurfaceId> live_surfaces; | 196 std::vector<SurfaceId> live_surfaces; |
| 158 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; | 197 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; |
| 159 | 198 |
| 160 // GC roots are surfaces that have not been destroyed, or have not had all | 199 // GC roots are surfaces that have not been destroyed, or have not had all |
| 161 // their destruction dependencies satisfied. | 200 // their destruction dependencies satisfied. |
| 162 for (auto& map_entry : surface_map_) { | 201 for (auto& map_entry : surface_map_) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 | 481 |
| 443 void SurfaceManager::SurfaceCreated(const SurfaceId& surface_id, | 482 void SurfaceManager::SurfaceCreated(const SurfaceId& surface_id, |
| 444 const gfx::Size& frame_size, | 483 const gfx::Size& frame_size, |
| 445 float device_scale_factor) { | 484 float device_scale_factor) { |
| 446 CHECK(thread_checker_.CalledOnValidThread()); | 485 CHECK(thread_checker_.CalledOnValidThread()); |
| 447 for (auto& observer : observer_list_) | 486 for (auto& observer : observer_list_) |
| 448 observer.OnSurfaceCreated(surface_id, frame_size, device_scale_factor); | 487 observer.OnSurfaceCreated(surface_id, frame_size, device_scale_factor); |
| 449 } | 488 } |
| 450 | 489 |
| 451 } // namespace cc | 490 } // namespace cc |
| OLD | NEW |