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 |