Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Side by Side Diff: cc/surfaces/surface_manager.cc

Issue 2540783004: Add SurfaceManager option to use references exclusively. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <utility> 11 #include <utility>
11 12
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "cc/surfaces/surface.h" 14 #include "cc/surfaces/surface.h"
14 #include "cc/surfaces/surface_factory_client.h" 15 #include "cc/surfaces/surface_factory_client.h"
15 #include "cc/surfaces/surface_id_allocator.h" 16 #include "cc/surfaces/surface_id_allocator.h"
16 17
17 namespace cc { 18 namespace cc {
18 19
19 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping() 20 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping()
20 : client(nullptr), source(nullptr) {} 21 : client(nullptr), source(nullptr) {}
21 22
22 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping( 23 SurfaceManager::FrameSinkSourceMapping::FrameSinkSourceMapping(
23 const FrameSinkSourceMapping& other) = default; 24 const FrameSinkSourceMapping& other) = default;
24 25
25 SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() { 26 SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() {
26 DCHECK(is_empty()) << "client: " << client 27 DCHECK(is_empty()) << "client: " << client
27 << ", children: " << children.size(); 28 << ", children: " << children.size();
28 } 29 }
29 30
30 SurfaceManager::SurfaceManager() 31 SurfaceManager::SurfaceManager(bool use_references)
31 : kRootSurfaceId(FrameSinkId(0u, 0u), 32 : use_references_(use_references),
32 LocalFrameId(0u, base::UnguessableToken::Create())) { 33 root_surface_id_(FrameSinkId(0u, 0u),
34 LocalFrameId(1u, base::UnguessableToken::Create())) {
vmpstr 2016/12/01 21:04:02 Why 1u change?
kylechar 2016/12/01 22:49:58 The LocalFrameId will be a valid value (local_fram
33 thread_checker_.DetachFromThread(); 35 thread_checker_.DetachFromThread();
34 } 36 }
35 37
36 SurfaceManager::~SurfaceManager() { 38 SurfaceManager::~SurfaceManager() {
37 DCHECK(thread_checker_.CalledOnValidThread()); 39 DCHECK(thread_checker_.CalledOnValidThread());
38 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin(); 40 for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
39 it != surfaces_to_destroy_.end(); 41 it != surfaces_to_destroy_.end();
40 ++it) { 42 ++it) {
41 DeregisterSurface((*it)->surface_id()); 43 DeregisterSurface((*it)->surface_id());
42 } 44 }
(...skipping 24 matching lines...) Expand all
67 void SurfaceManager::Destroy(std::unique_ptr<Surface> surface) { 69 void SurfaceManager::Destroy(std::unique_ptr<Surface> surface) {
68 DCHECK(thread_checker_.CalledOnValidThread()); 70 DCHECK(thread_checker_.CalledOnValidThread());
69 surface->set_destroyed(true); 71 surface->set_destroyed(true);
70 surfaces_to_destroy_.push_back(std::move(surface)); 72 surfaces_to_destroy_.push_back(std::move(surface));
71 GarbageCollectSurfaces(); 73 GarbageCollectSurfaces();
72 } 74 }
73 75
74 void SurfaceManager::DidSatisfySequences(const FrameSinkId& frame_sink_id, 76 void SurfaceManager::DidSatisfySequences(const FrameSinkId& frame_sink_id,
75 std::vector<uint32_t>* sequence) { 77 std::vector<uint32_t>* sequence) {
76 DCHECK(thread_checker_.CalledOnValidThread()); 78 DCHECK(thread_checker_.CalledOnValidThread());
79 DCHECK(!use_references_);
77 for (uint32_t value : *sequence) 80 for (uint32_t value : *sequence)
78 satisfied_sequences_.insert(SurfaceSequence(frame_sink_id, value)); 81 satisfied_sequences_.insert(SurfaceSequence(frame_sink_id, value));
79 sequence->clear(); 82 sequence->clear();
80 GarbageCollectSurfaces(); 83 GarbageCollectSurfaces();
81 } 84 }
82 85
83 void SurfaceManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) { 86 void SurfaceManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) {
84 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second; 87 bool inserted = valid_frame_sink_ids_.insert(frame_sink_id).second;
85 DCHECK(inserted); 88 DCHECK(inserted);
86 } 89 }
87 90
88 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) { 91 void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) {
89 valid_frame_sink_ids_.erase(frame_sink_id); 92 valid_frame_sink_ids_.erase(frame_sink_id);
90 GarbageCollectSurfaces(); 93 GarbageCollectSurfaces();
91 } 94 }
92 95
93 const SurfaceId& SurfaceManager::GetRootSurfaceId() const { 96 const SurfaceId& SurfaceManager::GetRootSurfaceId() const {
94 return kRootSurfaceId; 97 return root_surface_id_;
95 } 98 }
96 99
97 void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id, 100 void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id,
98 const SurfaceId& child_id) { 101 const SurfaceId& child_id) {
99 DCHECK(thread_checker_.CalledOnValidThread()); 102 DCHECK(thread_checker_.CalledOnValidThread());
100 103
101 // Check some conditions that should never happen. We don't want to crash on 104 // 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. 105 // bad input from a compromised client so just return early.
103 if (parent_id == child_id) { 106 if (parent_id == child_id) {
104 LOG(ERROR) << "Cannot add self reference for " << parent_id.ToString(); 107 LOG(ERROR) << "Cannot add self reference for " << parent_id.ToString();
105 return; 108 return;
106 } 109 }
107 if (parent_id != kRootSurfaceId && surface_map_.count(parent_id) == 0) { 110 if (parent_id != root_surface_id_ && surface_map_.count(parent_id) == 0) {
108 LOG(ERROR) << "No surface in map for " << parent_id.ToString(); 111 LOG(ERROR) << "No surface in map for " << parent_id.ToString();
109 return; 112 return;
110 } 113 }
111 if (surface_map_.count(child_id) == 0) { 114 if (surface_map_.count(child_id) == 0) {
112 LOG(ERROR) << "No surface in map for " << child_id.ToString(); 115 LOG(ERROR) << "No surface in map for " << child_id.ToString();
113 return; 116 return;
114 } 117 }
115 118
116 parent_to_child_refs_[parent_id].insert(child_id); 119 parent_to_child_refs_[parent_id].insert(child_id);
117 child_to_parent_refs_[child_id].insert(parent_id); 120 child_to_parent_refs_[child_id].insert(parent_id);
(...skipping 25 matching lines...) Expand all
143 } 146 }
144 147
145 size_t SurfaceManager::GetReferencedSurfaceCount( 148 size_t SurfaceManager::GetReferencedSurfaceCount(
146 const SurfaceId& surface_id) const { 149 const SurfaceId& surface_id) const {
147 auto iter = parent_to_child_refs_.find(surface_id); 150 auto iter = parent_to_child_refs_.find(surface_id);
148 if (iter == parent_to_child_refs_.end()) 151 if (iter == parent_to_child_refs_.end())
149 return 0; 152 return 0;
150 return iter->second.size(); 153 return iter->second.size();
151 } 154 }
152 155
156 void SurfaceManager::GarbageCollectSurfacesFromRoot() {
157 DCHECK(use_references_);
158
159 if (surfaces_to_destroy_.empty())
160 return;
161
162 std::unordered_set<SurfaceId, SurfaceIdHash> reachable_surfaces;
163
164 // Walk down from the root and mark each SurfaceId we encounter as reachable.
165 std::queue<SurfaceId> surface_queue({root_surface_id_});
vmpstr 2016/12/01 21:04:02 surface_queue{root_surface_id_}? Can you also ver
kylechar 2016/12/01 22:49:58 std::initializer_list are allowed now and I can't
166 while (!surface_queue.empty()) {
167 const SurfaceId& surface_id = surface_queue.front();
168 auto iter = parent_to_child_refs_.find(surface_id);
169 if (iter != parent_to_child_refs_.end()) {
170 for (const SurfaceId& child_id : iter->second) {
171 // Check for cycles when inserting into |reachable_surfaces|.
172 if (reachable_surfaces.insert(child_id).second)
173 surface_queue.push(child_id);
174 }
175 }
176 surface_queue.pop();
177 }
178
179 std::vector<std::unique_ptr<Surface>> surfaces_to_delete;
180
181 // Delete all destroyed and unreachable surfaces.
182 for (auto iter = surfaces_to_destroy_.begin();
183 iter != surfaces_to_destroy_.end();) {
184 SurfaceId surface_id = (*iter)->surface_id();
185 if (reachable_surfaces.count(surface_id) == 0) {
186 DeregisterSurface(surface_id);
187 surfaces_to_delete.push_back(std::move(*iter));
188 iter = surfaces_to_destroy_.erase(iter);
189 } else {
190 ++iter;
191 }
192 }
193
194 // ~Surface() draw callback could modify |surfaces_to_destroy_|.
195 surfaces_to_delete.clear();
196 }
197
153 void SurfaceManager::GarbageCollectSurfaces() { 198 void SurfaceManager::GarbageCollectSurfaces() {
199 if (use_references_) {
200 GarbageCollectSurfacesFromRoot();
201 return;
202 }
203
154 // Simple mark and sweep GC. 204 // Simple mark and sweep GC.
155 // TODO(jbauman): Reduce the amount of work when nothing needs to be 205 // TODO(jbauman): Reduce the amount of work when nothing needs to be
156 // destroyed. 206 // destroyed.
157 std::vector<SurfaceId> live_surfaces; 207 std::vector<SurfaceId> live_surfaces;
158 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; 208 std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set;
159 209
160 // GC roots are surfaces that have not been destroyed, or have not had all 210 // GC roots are surfaces that have not been destroyed, or have not had all
161 // their destruction dependencies satisfied. 211 // their destruction dependencies satisfied.
162 for (auto& map_entry : surface_map_) { 212 for (auto& map_entry : surface_map_) {
163 const SurfaceId& surface_id = map_entry.first; 213 const SurfaceId& surface_id = map_entry.first;
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 492
443 void SurfaceManager::SurfaceCreated(const SurfaceId& surface_id, 493 void SurfaceManager::SurfaceCreated(const SurfaceId& surface_id,
444 const gfx::Size& frame_size, 494 const gfx::Size& frame_size,
445 float device_scale_factor) { 495 float device_scale_factor) {
446 CHECK(thread_checker_.CalledOnValidThread()); 496 CHECK(thread_checker_.CalledOnValidThread());
447 for (auto& observer : observer_list_) 497 for (auto& observer : observer_list_)
448 observer.OnSurfaceCreated(surface_id, frame_size, device_scale_factor); 498 observer.OnSurfaceCreated(surface_id, frame_size, device_scale_factor);
449 } 499 }
450 500
451 } // namespace cc 501 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698