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

Unified Diff: cc/surfaces/surface_manager.cc

Issue 2540783004: Add SurfaceManager option to use references exclusively. (Closed)
Patch Set: Add .push(). 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/surfaces/surface_manager.h ('k') | services/ui/surfaces/display_compositor.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/surfaces/surface_manager.cc
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc
index b95954aab2659af9264ca1d6977304f64427dfd8..7c716d0eeb0c975b6ac7ed43e81412252967ca0d 100644
--- a/cc/surfaces/surface_manager.cc
+++ b/cc/surfaces/surface_manager.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <queue>
#include <utility>
#include "base/logging.h"
@@ -27,9 +28,10 @@ SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() {
<< ", children: " << children.size();
}
-SurfaceManager::SurfaceManager()
- : kRootSurfaceId(FrameSinkId(0u, 0u),
- LocalFrameId(0u, base::UnguessableToken::Create())) {
+SurfaceManager::SurfaceManager(LifetimeType lifetime_type)
+ : lifetime_type_(lifetime_type),
+ root_surface_id_(FrameSinkId(0u, 0u),
+ LocalFrameId(1u, base::UnguessableToken::Create())) {
thread_checker_.DetachFromThread();
}
@@ -74,6 +76,7 @@ void SurfaceManager::Destroy(std::unique_ptr<Surface> surface) {
void SurfaceManager::DidSatisfySequences(const FrameSinkId& frame_sink_id,
std::vector<uint32_t>* sequence) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_EQ(lifetime_type_, LifetimeType::SEQUENCES);
for (uint32_t value : *sequence)
satisfied_sequences_.insert(SurfaceSequence(frame_sink_id, value));
sequence->clear();
@@ -91,7 +94,7 @@ void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) {
}
const SurfaceId& SurfaceManager::GetRootSurfaceId() const {
- return kRootSurfaceId;
+ return root_surface_id_;
}
void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id,
@@ -104,7 +107,7 @@ void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id,
LOG(ERROR) << "Cannot add self reference for " << parent_id.ToString();
return;
}
- if (parent_id != kRootSurfaceId && surface_map_.count(parent_id) == 0) {
+ if (parent_id != root_surface_id_ && surface_map_.count(parent_id) == 0) {
LOG(ERROR) << "No surface in map for " << parent_id.ToString();
return;
}
@@ -150,7 +153,55 @@ size_t SurfaceManager::GetReferencedSurfaceCount(
return iter->second.size();
}
+void SurfaceManager::GarbageCollectSurfacesFromRoot() {
+ DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES);
+
+ if (surfaces_to_destroy_.empty())
+ return;
+
+ std::unordered_set<SurfaceId, SurfaceIdHash> reachable_surfaces;
+
+ // Walk down from the root and mark each SurfaceId we encounter as reachable.
+ std::queue<SurfaceId> surface_queue;
+ surface_queue.push(root_surface_id_);
+ while (!surface_queue.empty()) {
+ const SurfaceId& surface_id = surface_queue.front();
+ auto iter = parent_to_child_refs_.find(surface_id);
+ if (iter != parent_to_child_refs_.end()) {
+ for (const SurfaceId& child_id : iter->second) {
+ // Check for cycles when inserting into |reachable_surfaces|.
+ if (reachable_surfaces.insert(child_id).second)
+ surface_queue.push(child_id);
+ }
+ }
+ surface_queue.pop();
+ }
+
+ std::vector<std::unique_ptr<Surface>> surfaces_to_delete;
+
+ // Delete all destroyed and unreachable surfaces.
+ for (auto iter = surfaces_to_destroy_.begin();
+ iter != surfaces_to_destroy_.end();) {
+ SurfaceId surface_id = (*iter)->surface_id();
+ if (reachable_surfaces.count(surface_id) == 0) {
+ DeregisterSurface(surface_id);
+ surfaces_to_delete.push_back(std::move(*iter));
+ iter = surfaces_to_destroy_.erase(iter);
+ } else {
+ ++iter;
+ }
+ }
+
+ // ~Surface() draw callback could modify |surfaces_to_destroy_|.
+ surfaces_to_delete.clear();
+}
+
void SurfaceManager::GarbageCollectSurfaces() {
+ if (lifetime_type_ == LifetimeType::REFERENCES) {
+ GarbageCollectSurfacesFromRoot();
+ return;
+ }
+
// Simple mark and sweep GC.
// TODO(jbauman): Reduce the amount of work when nothing needs to be
// destroyed.
« no previous file with comments | « cc/surfaces/surface_manager.h ('k') | services/ui/surfaces/display_compositor.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698