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 "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "cc/surfaces/surface.h" | 11 #include "cc/surfaces/surface.h" |
| 12 #include "cc/surfaces/surface_factory_client.h" | |
| 12 #include "cc/surfaces/surface_id_allocator.h" | 13 #include "cc/surfaces/surface_id_allocator.h" |
| 13 | 14 |
| 14 namespace cc { | 15 namespace cc { |
| 15 | 16 |
| 17 SurfaceManager::ClientSourceMapping::ClientSourceMapping() | |
| 18 : client(nullptr), source(nullptr) {} | |
| 19 | |
| 20 SurfaceManager::ClientSourceMapping::~ClientSourceMapping() { | |
| 21 DCHECK(is_empty()) << "client: " << client | |
| 22 << ", children: " << children.size(); | |
| 23 } | |
| 24 | |
| 16 SurfaceManager::SurfaceManager() { | 25 SurfaceManager::SurfaceManager() { |
| 17 thread_checker_.DetachFromThread(); | 26 thread_checker_.DetachFromThread(); |
| 18 } | 27 } |
| 19 | 28 |
| 20 SurfaceManager::~SurfaceManager() { | 29 SurfaceManager::~SurfaceManager() { |
| 21 DCHECK(thread_checker_.CalledOnValidThread()); | 30 DCHECK(thread_checker_.CalledOnValidThread()); |
| 22 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); | 31 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); |
| 23 it != surfaces_to_destroy_.end(); | 32 it != surfaces_to_destroy_.end(); |
| 24 ++it) { | 33 ++it) { |
| 25 DeregisterSurface((*it)->surface_id()); | 34 DeregisterSurface((*it)->surface_id()); |
| 26 delete *it; | 35 delete *it; |
| 27 } | 36 } |
| 28 } | 37 } |
| 29 | 38 |
| 30 void SurfaceManager::RegisterSurface(Surface* surface) { | 39 void SurfaceManager::RegisterSurface(Surface* surface) { |
| 31 DCHECK(thread_checker_.CalledOnValidThread()); | 40 DCHECK(thread_checker_.CalledOnValidThread()); |
| 32 DCHECK(surface); | 41 DCHECK(surface); |
| 33 DCHECK(!surface_map_.count(surface->surface_id())); | 42 DCHECK(!surface_map_.count(surface->surface_id())); |
| 34 surface_map_[surface->surface_id()] = surface; | 43 surface_map_[surface->surface_id()] = surface; |
| 44 // TODO(enne): verify surface namespace is registered | |
| 35 } | 45 } |
| 36 | 46 |
| 37 void SurfaceManager::DeregisterSurface(SurfaceId surface_id) { | 47 void SurfaceManager::DeregisterSurface(SurfaceId surface_id) { |
| 38 DCHECK(thread_checker_.CalledOnValidThread()); | 48 DCHECK(thread_checker_.CalledOnValidThread()); |
| 39 SurfaceMap::iterator it = surface_map_.find(surface_id); | 49 SurfaceMap::iterator it = surface_map_.find(surface_id); |
| 40 DCHECK(it != surface_map_.end()); | 50 DCHECK(it != surface_map_.end()); |
| 41 surface_map_.erase(it); | 51 surface_map_.erase(it); |
| 52 // TODO(enne): verify surface namespace is registered | |
| 42 } | 53 } |
| 43 | 54 |
| 44 void SurfaceManager::Destroy(scoped_ptr<Surface> surface) { | 55 void SurfaceManager::Destroy(scoped_ptr<Surface> surface) { |
| 45 DCHECK(thread_checker_.CalledOnValidThread()); | 56 DCHECK(thread_checker_.CalledOnValidThread()); |
| 46 surface->set_destroyed(true); | 57 surface->set_destroyed(true); |
| 47 surfaces_to_destroy_.push_back(surface.release()); | 58 surfaces_to_destroy_.push_back(surface.release()); |
| 48 GarbageCollectSurfaces(); | 59 GarbageCollectSurfaces(); |
| 49 } | 60 } |
| 50 | 61 |
| 51 void SurfaceManager::DidSatisfySequences(uint32_t id_namespace, | 62 void SurfaceManager::DidSatisfySequences(uint32_t id_namespace, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 if (!live_surfaces_set.count((*dest_it)->surface_id())) { | 124 if (!live_surfaces_set.count((*dest_it)->surface_id())) { |
| 114 scoped_ptr<Surface> surf(*dest_it); | 125 scoped_ptr<Surface> surf(*dest_it); |
| 115 DeregisterSurface(surf->surface_id()); | 126 DeregisterSurface(surf->surface_id()); |
| 116 dest_it = surfaces_to_destroy_.erase(dest_it); | 127 dest_it = surfaces_to_destroy_.erase(dest_it); |
| 117 } else { | 128 } else { |
| 118 ++dest_it; | 129 ++dest_it; |
| 119 } | 130 } |
| 120 } | 131 } |
| 121 } | 132 } |
| 122 | 133 |
| 134 void SurfaceManager::RegisterSurfaceFactoryClient( | |
| 135 uint32_t id_namespace, | |
| 136 SurfaceFactoryClient* client) { | |
|
brianderson
2016/02/18 23:01:07
DCHECK namespace is valid?
| |
| 137 if (client) { | |
| 138 DCHECK(!namespace_client_map_[id_namespace].client); | |
| 139 namespace_client_map_[id_namespace].client = client; | |
| 140 if (BeginFrameSource* source = namespace_client_map_[id_namespace].source) { | |
|
brianderson
2016/02/18 23:01:07
Cache map lookup?
| |
| 141 client->SetBeginFrameSource(source); | |
| 142 } | |
| 143 } else { | |
| 144 DCHECK_EQ(namespace_client_map_.count(id_namespace), 1u); | |
| 145 auto iter = namespace_client_map_.find(id_namespace); | |
| 146 if (iter->second.source) | |
| 147 iter->second.client->SetBeginFrameSource(nullptr); | |
| 148 iter->second.client = nullptr; | |
| 149 | |
| 150 // The begin frame source should be removed prior to removing this | |
| 151 // client. | |
| 152 for (auto iter : registered_sources_) | |
|
brianderson
2016/02/18 23:01:07
Maybe use a name other than "iter".
| |
| 153 DCHECK_NE(iter.second, id_namespace); | |
| 154 | |
| 155 if (iter->second.is_empty()) | |
| 156 namespace_client_map_.erase(iter); | |
|
brianderson
2016/02/18 23:01:07
Does it make a difference whether this is erased h
| |
| 157 } | |
| 158 } | |
| 159 | |
| 160 void SurfaceManager::RegisterBeginFrameSource(BeginFrameSource* source, | |
| 161 uint32_t id_namespace) { | |
| 162 DCHECK(source); | |
| 163 DCHECK_EQ(namespace_client_map_.count(id_namespace), 1u); | |
| 164 DCHECK_EQ(registered_sources_.count(source), 0u); | |
| 165 | |
| 166 registered_sources_[source] = id_namespace; | |
| 167 RecursivelyAttachBeginFrameSource(id_namespace, source); | |
| 168 } | |
| 169 | |
| 170 void SurfaceManager::UnregisterBeginFrameSource(BeginFrameSource* source) { | |
| 171 DCHECK(source); | |
| 172 DCHECK_EQ(registered_sources_.count(source), 1u); | |
| 173 | |
| 174 uint32_t id_namespace = registered_sources_[source]; | |
| 175 DCHECK_EQ(namespace_client_map_.count(id_namespace), 1u); | |
| 176 registered_sources_.erase(source); | |
| 177 | |
| 178 // TODO(enne): these walks could be done in one step. | |
| 179 // Remove this begin frame source from its subtree. | |
| 180 RecursivelyDetachBeginFrameSource(id_namespace, source); | |
| 181 // Then flush every remaining registered source to set anything null. | |
| 182 for (auto iter : registered_sources_) | |
|
brianderson
2016/02/18 23:01:07
Nice.
| |
| 183 RecursivelyAttachBeginFrameSource(iter.second, iter.first); | |
| 184 } | |
| 185 | |
| 186 void SurfaceManager::RecursivelyAttachBeginFrameSource( | |
| 187 uint32_t id_namespace, | |
| 188 BeginFrameSource* source) { | |
| 189 auto& data = namespace_client_map_[id_namespace]; | |
|
jbauman
2016/02/24 19:52:34
One thing we'll have to be careful of is to make s
enne (OOO)
2016/02/24 21:19:03
Mmm, that's a really good point. Rather than keep
| |
| 190 if (!data.source) { | |
|
brianderson
2016/02/18 23:01:07
Can you add a comment regarding the purpose of thi
| |
| 191 data.source = source; | |
| 192 if (data.client) | |
| 193 data.client->SetBeginFrameSource(source); | |
| 194 } | |
| 195 for (size_t i = 0; i < data.children.size(); ++i) { | |
| 196 RecursivelyAttachBeginFrameSource(data.children[i], source); | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 void SurfaceManager::RecursivelyDetachBeginFrameSource( | |
| 201 uint32_t id_namespace, | |
| 202 BeginFrameSource* source) { | |
|
brianderson
2016/02/18 23:01:07
Maybe add some DCHECKS like you have in the other
| |
| 203 auto iter = namespace_client_map_.find(id_namespace); | |
| 204 if (iter->second.source == source) { | |
| 205 iter->second.source = nullptr; | |
| 206 if (iter->second.client) | |
| 207 iter->second.client->SetBeginFrameSource(nullptr); | |
| 208 } | |
| 209 std::vector<uint32_t>& children = iter->second.children; | |
| 210 for (size_t i = 0; i < children.size(); ++i) { | |
| 211 RecursivelyDetachBeginFrameSource(children[i], source); | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 void SurfaceManager::RegisterSurfaceNamespaceHierarchy( | |
| 216 uint32_t parent_namespace, | |
| 217 uint32_t child_namespace) { | |
| 218 std::vector<uint32_t>& children = | |
| 219 namespace_client_map_[parent_namespace].children; | |
| 220 for (size_t i = 0; i < children.size(); ++i) | |
| 221 DCHECK_NE(children[i], child_namespace); | |
| 222 children.push_back(child_namespace); | |
| 223 | |
| 224 BeginFrameSource* parent_source = | |
| 225 namespace_client_map_[parent_namespace].source; | |
| 226 if (!parent_source) | |
| 227 return; | |
| 228 | |
| 229 DCHECK_EQ(registered_sources_.count(parent_source), 1u); | |
| 230 RecursivelyAttachBeginFrameSource(child_namespace, parent_source); | |
| 231 } | |
| 232 | |
| 233 void SurfaceManager::UnregisterSurfaceNamespaceHierarchy( | |
| 234 uint32_t parent_namespace, | |
| 235 uint32_t child_namespace) { | |
| 236 DCHECK_EQ(namespace_client_map_.count(parent_namespace), 1u); | |
| 237 | |
| 238 auto iter = namespace_client_map_.find(parent_namespace); | |
| 239 | |
| 240 std::vector<uint32_t>& children = iter->second.children; | |
| 241 bool found_child = false; | |
| 242 for (size_t i = 0; i < children.size(); ++i) { | |
| 243 if (children[i] == child_namespace) { | |
| 244 found_child = true; | |
| 245 children[i] = children[children.size() - 1]; | |
| 246 children.resize(children.size() - 1); | |
| 247 break; | |
| 248 } | |
| 249 } | |
| 250 DCHECK(found_child); | |
| 251 | |
| 252 BeginFrameSource* parent_source = iter->second.source; | |
| 253 if (!parent_source) | |
| 254 return; | |
| 255 | |
| 256 if (iter->second.is_empty()) | |
| 257 namespace_client_map_.erase(iter); | |
| 258 | |
| 259 // TODO(enne): these walks could be done in one step. | |
| 260 RecursivelyDetachBeginFrameSource(child_namespace, parent_source); | |
| 261 for (auto iter : registered_sources_) | |
| 262 RecursivelyAttachBeginFrameSource(iter.second, iter.first); | |
| 263 } | |
| 264 | |
| 123 Surface* SurfaceManager::GetSurfaceForId(SurfaceId surface_id) { | 265 Surface* SurfaceManager::GetSurfaceForId(SurfaceId surface_id) { |
| 124 DCHECK(thread_checker_.CalledOnValidThread()); | 266 DCHECK(thread_checker_.CalledOnValidThread()); |
| 125 SurfaceMap::iterator it = surface_map_.find(surface_id); | 267 SurfaceMap::iterator it = surface_map_.find(surface_id); |
| 126 if (it == surface_map_.end()) | 268 if (it == surface_map_.end()) |
| 127 return NULL; | 269 return NULL; |
| 128 return it->second; | 270 return it->second; |
| 129 } | 271 } |
| 130 | 272 |
| 131 bool SurfaceManager::SurfaceModified(SurfaceId surface_id) { | 273 bool SurfaceManager::SurfaceModified(SurfaceId surface_id) { |
| 132 DCHECK(thread_checker_.CalledOnValidThread()); | 274 CHECK(thread_checker_.CalledOnValidThread()); |
| 133 bool changed = false; | 275 bool changed = false; |
| 134 FOR_EACH_OBSERVER(SurfaceDamageObserver, observer_list_, | 276 FOR_EACH_OBSERVER(SurfaceDamageObserver, observer_list_, |
| 135 OnSurfaceDamaged(surface_id, &changed)); | 277 OnSurfaceDamaged(surface_id, &changed)); |
| 136 return changed; | 278 return changed; |
| 137 } | 279 } |
| 138 | 280 |
| 139 } // namespace cc | 281 } // namespace cc |
| OLD | NEW |