| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "cc/surfaces/display_compositor_lock_manager.h" |
| 6 |
| 7 #include "cc/surfaces/surface.h" |
| 8 #include "cc/surfaces/surface_info.h" |
| 9 #include "cc/surfaces/surface_manager.h" |
| 10 |
| 11 namespace cc { |
| 12 |
| 13 namespace { |
| 14 static constexpr uint32_t MAX_BEGIN_FRAME_COUNT = 4; |
| 15 } |
| 16 |
| 17 DisplayCompositorLockManager::DisplayCompositorLockManager( |
| 18 SurfaceManager* surface_manager, |
| 19 BeginFrameSource* begin_frame_source) |
| 20 : surface_manager_(surface_manager), |
| 21 begin_frame_source_(begin_frame_source) { |
| 22 surface_manager_->AddObserver(this); |
| 23 } |
| 24 |
| 25 DisplayCompositorLockManager::~DisplayCompositorLockManager() { |
| 26 surface_manager_->RemoveObserver(this); |
| 27 } |
| 28 |
| 29 void DisplayCompositorLockManager::RequestSurfaceResolution( |
| 30 Surface* pending_surface) { |
| 31 const base::Optional<CompositorFrame>& current_frame = |
| 32 pending_surface->GetPendingFrame(); |
| 33 if (!current_frame) |
| 34 return; |
| 35 |
| 36 bool needs_begin_frame = current_frame->metadata.respect_deadline; |
| 37 |
| 38 // Referenced surface IDs that aren't currently known to the surface manager |
| 39 // block this frame. |
| 40 for (const SurfaceId& surface_id : |
| 41 current_frame->metadata.referenced_surfaces) { |
| 42 if (!surface_manager_->GetSurfaceForId(surface_id)) |
| 43 blocking_surfaces_[surface_id].insert(pending_surface); |
| 44 } |
| 45 |
| 46 if (!pending_surfaces_.count(pending_surface)) { |
| 47 pending_surface->AddObserver(this); |
| 48 pending_surfaces_.insert(pending_surface); |
| 49 } |
| 50 |
| 51 if (needs_begin_frame && !observing_begin_frames_) { |
| 52 begin_frame_source_->AddObserver(this); |
| 53 observing_begin_frames_ = true; |
| 54 } |
| 55 } |
| 56 |
| 57 void DisplayCompositorLockManager::OnBeginFrame(const BeginFrameArgs& args) { |
| 58 last_begin_frame_args_ = args; |
| 59 if (++begin_frame_count_ == MAX_BEGIN_FRAME_COUNT) { |
| 60 // Activate all surfaces that respect the deadline. |
| 61 PendingSurfaceSet pending_surfaces(pending_surfaces_); |
| 62 for (Surface* pending_surface : pending_surfaces) |
| 63 pending_surface->ActivatePendingFrameForDeadline(); |
| 64 |
| 65 if (observing_begin_frames_) { |
| 66 begin_frame_source_->RemoveObserver(this); |
| 67 observing_begin_frames_ = false; |
| 68 } |
| 69 begin_frame_count_ = 0; |
| 70 } |
| 71 } |
| 72 |
| 73 const BeginFrameArgs& DisplayCompositorLockManager::LastUsedBeginFrameArgs() |
| 74 const { |
| 75 return last_begin_frame_args_; |
| 76 } |
| 77 |
| 78 void DisplayCompositorLockManager::OnBeginFrameSourcePausedChanged( |
| 79 bool paused) {} |
| 80 |
| 81 void DisplayCompositorLockManager::OnSurfaceDiscarded( |
| 82 Surface* pending_surface) { |
| 83 fprintf(stderr, ">>>%s\n", __PRETTY_FUNCTION__); |
| 84 const CompositorFrame& current_frame = pending_surface->GetEligibleFrame(); |
| 85 if (current_frame.metadata.referenced_surfaces.empty()) |
| 86 return; |
| 87 |
| 88 for (const SurfaceId& surface_id : |
| 89 current_frame.metadata.referenced_surfaces) { |
| 90 auto it = blocking_surfaces_.find(surface_id); |
| 91 if (it != blocking_surfaces_.end()) { |
| 92 auto& pending_surface_set = it->second; |
| 93 auto pending_surface_it = pending_surface_set.find(pending_surface); |
| 94 if (pending_surface_it != pending_surface_set.end()) { |
| 95 pending_surface_set.erase(pending_surface); |
| 96 if (pending_surface_set.empty()) |
| 97 blocking_surfaces_.erase(surface_id); |
| 98 } |
| 99 } |
| 100 } |
| 101 |
| 102 if (observing_begin_frames_ && blocking_surfaces_.empty()) { |
| 103 begin_frame_source_->RemoveObserver(this); |
| 104 observing_begin_frames_ = false; |
| 105 } |
| 106 |
| 107 pending_surfaces_.erase(pending_surface); |
| 108 pending_surface->RemoveObserver(this); |
| 109 } |
| 110 |
| 111 void DisplayCompositorLockManager::OnSurfaceActivated( |
| 112 Surface* pending_surface) { |
| 113 fprintf(stderr, ">>>DisplayCompositorLockManager::OnSurfaceActivated %s\n", |
| 114 pending_surface->surface_id().ToString().c_str()); |
| 115 pending_surface->RemoveObserver(this); |
| 116 pending_surfaces_.erase(pending_surface); |
| 117 ReportSurfaceIdAvailable(pending_surface->surface_id()); |
| 118 } |
| 119 |
| 120 void DisplayCompositorLockManager::OnSurfaceChanged( |
| 121 Surface* pending_surface, |
| 122 const SurfaceDependencies& added_dependencies, |
| 123 const SurfaceDependencies& removed_dependencies) { |
| 124 fprintf(stderr, ">>>%s added_deps: %d removed_deps: %d\n", |
| 125 __PRETTY_FUNCTION__, (uint32_t)added_dependencies.size(), |
| 126 (uint32_t)removed_dependencies.size()); |
| 127 for (const SurfaceId& surface_id : added_dependencies) |
| 128 blocking_surfaces_[surface_id].insert(pending_surface); |
| 129 |
| 130 for (const SurfaceId& surface_id : removed_dependencies) { |
| 131 blocking_surfaces_[surface_id].erase(pending_surface); |
| 132 if (blocking_surfaces_[surface_id].empty()) |
| 133 blocking_surfaces_.erase(surface_id); |
| 134 } |
| 135 |
| 136 // If there are no more dependencies to resolve then we don't need to listen |
| 137 // to BeginFrames. |
| 138 if (blocking_surfaces_.empty() && observing_begin_frames_) { |
| 139 begin_frame_source_->RemoveObserver(this); |
| 140 observing_begin_frames_ = false; |
| 141 } |
| 142 } |
| 143 |
| 144 // SurfaceObserver implementation: |
| 145 void DisplayCompositorLockManager::OnSurfaceCreated( |
| 146 const SurfaceInfo& surface_info) { |
| 147 fprintf(stderr, ">>>SurfaceCreated %s\n", |
| 148 surface_info.id().ToString().c_str()); |
| 149 ReportSurfaceIdAvailable(surface_info.id()); |
| 150 } |
| 151 |
| 152 void DisplayCompositorLockManager::OnSurfaceDamaged(const SurfaceId& surface_id, |
| 153 bool* changed) {} |
| 154 |
| 155 void DisplayCompositorLockManager::ReportSurfaceIdAvailable( |
| 156 const SurfaceId& surface_id) { |
| 157 auto it = blocking_surfaces_.find(surface_id); |
| 158 if (it == blocking_surfaces_.end()) |
| 159 return; |
| 160 |
| 161 // Unblock surfaces that depend on this pending surface. |
| 162 PendingSurfaceSet blocked_pending_surface_set(it->second); |
| 163 blocking_surfaces_.erase(it); |
| 164 if (observing_begin_frames_ && blocking_surfaces_.empty()) { |
| 165 begin_frame_source_->RemoveObserver(this); |
| 166 observing_begin_frames_ = false; |
| 167 } |
| 168 for (Surface* blocked_pending_surface : blocked_pending_surface_set) |
| 169 blocked_pending_surface->ReportSurfaceIdAvailable(surface_id); |
| 170 } |
| 171 |
| 172 } // namespace cc |
| OLD | NEW |