| 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
|
|
|