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

Unified Diff: cc/surfaces/display_compositor_lock_manager.cc

Issue 2582823002: WIP: Surface Synchronization System
Patch Set: Only create ClientSurfaceEmbedder if window is visible. Trash it otherwise. Created 3 years, 11 months 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
Index: cc/surfaces/display_compositor_lock_manager.cc
diff --git a/cc/surfaces/display_compositor_lock_manager.cc b/cc/surfaces/display_compositor_lock_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..28b8235015fbfda3d8c85e72ad915e08fb876100
--- /dev/null
+++ b/cc/surfaces/display_compositor_lock_manager.cc
@@ -0,0 +1,172 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/surfaces/display_compositor_lock_manager.h"
+
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_info.h"
+#include "cc/surfaces/surface_manager.h"
+
+namespace cc {
+
+namespace {
+static constexpr uint32_t MAX_BEGIN_FRAME_COUNT = 4;
+}
+
+DisplayCompositorLockManager::DisplayCompositorLockManager(
+ SurfaceManager* surface_manager,
+ BeginFrameSource* begin_frame_source)
+ : surface_manager_(surface_manager),
+ begin_frame_source_(begin_frame_source) {
+ surface_manager_->AddObserver(this);
+}
+
+DisplayCompositorLockManager::~DisplayCompositorLockManager() {
+ surface_manager_->RemoveObserver(this);
+}
+
+void DisplayCompositorLockManager::RequestSurfaceResolution(
+ Surface* pending_surface) {
+ const base::Optional<CompositorFrame>& current_frame =
+ pending_surface->GetPendingFrame();
+ if (!current_frame)
+ return;
+
+ bool needs_begin_frame = current_frame->metadata.respect_deadline;
+
+ // Referenced surface IDs that aren't currently known to the surface manager
+ // block this frame.
+ for (const SurfaceId& surface_id :
+ current_frame->metadata.referenced_surfaces) {
+ if (!surface_manager_->GetSurfaceForId(surface_id))
+ blocking_surfaces_[surface_id].insert(pending_surface);
+ }
+
+ if (!pending_surfaces_.count(pending_surface)) {
+ pending_surface->AddObserver(this);
+ pending_surfaces_.insert(pending_surface);
+ }
+
+ if (needs_begin_frame && !observing_begin_frames_) {
+ begin_frame_source_->AddObserver(this);
+ observing_begin_frames_ = true;
+ }
+}
+
+void DisplayCompositorLockManager::OnBeginFrame(const BeginFrameArgs& args) {
+ last_begin_frame_args_ = args;
+ if (++begin_frame_count_ == MAX_BEGIN_FRAME_COUNT) {
+ // Activate all surfaces that respect the deadline.
+ PendingSurfaceSet pending_surfaces(pending_surfaces_);
+ for (Surface* pending_surface : pending_surfaces)
+ pending_surface->ActivatePendingFrameForDeadline();
+
+ if (observing_begin_frames_) {
+ begin_frame_source_->RemoveObserver(this);
+ observing_begin_frames_ = false;
+ }
+ begin_frame_count_ = 0;
+ }
+}
+
+const BeginFrameArgs& DisplayCompositorLockManager::LastUsedBeginFrameArgs()
+ const {
+ return last_begin_frame_args_;
+}
+
+void DisplayCompositorLockManager::OnBeginFrameSourcePausedChanged(
+ bool paused) {}
+
+void DisplayCompositorLockManager::OnSurfaceDiscarded(
+ Surface* pending_surface) {
+ fprintf(stderr, ">>>%s\n", __PRETTY_FUNCTION__);
+ const CompositorFrame& current_frame = pending_surface->GetEligibleFrame();
+ if (current_frame.metadata.referenced_surfaces.empty())
+ return;
+
+ for (const SurfaceId& surface_id :
+ current_frame.metadata.referenced_surfaces) {
+ auto it = blocking_surfaces_.find(surface_id);
+ if (it != blocking_surfaces_.end()) {
+ auto& pending_surface_set = it->second;
+ auto pending_surface_it = pending_surface_set.find(pending_surface);
+ if (pending_surface_it != pending_surface_set.end()) {
+ pending_surface_set.erase(pending_surface);
+ if (pending_surface_set.empty())
+ blocking_surfaces_.erase(surface_id);
+ }
+ }
+ }
+
+ if (observing_begin_frames_ && blocking_surfaces_.empty()) {
+ begin_frame_source_->RemoveObserver(this);
+ observing_begin_frames_ = false;
+ }
+
+ pending_surfaces_.erase(pending_surface);
+ pending_surface->RemoveObserver(this);
+}
+
+void DisplayCompositorLockManager::OnSurfaceActivated(
+ Surface* pending_surface) {
+ fprintf(stderr, ">>>DisplayCompositorLockManager::OnSurfaceActivated %s\n",
+ pending_surface->surface_id().ToString().c_str());
+ pending_surface->RemoveObserver(this);
+ pending_surfaces_.erase(pending_surface);
+ ReportSurfaceIdAvailable(pending_surface->surface_id());
+}
+
+void DisplayCompositorLockManager::OnSurfaceChanged(
+ Surface* pending_surface,
+ const SurfaceDependencies& added_dependencies,
+ const SurfaceDependencies& removed_dependencies) {
+ fprintf(stderr, ">>>%s added_deps: %d removed_deps: %d\n",
+ __PRETTY_FUNCTION__, (uint32_t)added_dependencies.size(),
+ (uint32_t)removed_dependencies.size());
+ for (const SurfaceId& surface_id : added_dependencies)
+ blocking_surfaces_[surface_id].insert(pending_surface);
+
+ for (const SurfaceId& surface_id : removed_dependencies) {
+ blocking_surfaces_[surface_id].erase(pending_surface);
+ if (blocking_surfaces_[surface_id].empty())
+ blocking_surfaces_.erase(surface_id);
+ }
+
+ // If there are no more dependencies to resolve then we don't need to listen
+ // to BeginFrames.
+ if (blocking_surfaces_.empty() && observing_begin_frames_) {
+ begin_frame_source_->RemoveObserver(this);
+ observing_begin_frames_ = false;
+ }
+}
+
+// SurfaceObserver implementation:
+void DisplayCompositorLockManager::OnSurfaceCreated(
+ const SurfaceInfo& surface_info) {
+ fprintf(stderr, ">>>SurfaceCreated %s\n",
+ surface_info.id().ToString().c_str());
+ ReportSurfaceIdAvailable(surface_info.id());
+}
+
+void DisplayCompositorLockManager::OnSurfaceDamaged(const SurfaceId& surface_id,
+ bool* changed) {}
+
+void DisplayCompositorLockManager::ReportSurfaceIdAvailable(
+ const SurfaceId& surface_id) {
+ auto it = blocking_surfaces_.find(surface_id);
+ if (it == blocking_surfaces_.end())
+ return;
+
+ // Unblock surfaces that depend on this pending surface.
+ PendingSurfaceSet blocked_pending_surface_set(it->second);
+ blocking_surfaces_.erase(it);
+ if (observing_begin_frames_ && blocking_surfaces_.empty()) {
+ begin_frame_source_->RemoveObserver(this);
+ observing_begin_frames_ = false;
+ }
+ for (Surface* blocked_pending_surface : blocked_pending_surface_set)
+ blocked_pending_surface->ReportSurfaceIdAvailable(surface_id);
+}
+
+} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698