| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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/compositor_frame_sink_support.h" | 5 #include "cc/surfaces/compositor_frame_sink_support.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "cc/output/compositor_frame.h" | 10 #include "cc/output/compositor_frame.h" |
| 11 #include "cc/scheduler/begin_frame_source.h" | 11 #include "cc/scheduler/begin_frame_source.h" |
| 12 #include "cc/surfaces/compositor_frame_sink_support_client.h" | 12 #include "cc/surfaces/compositor_frame_sink_support_client.h" |
| 13 #include "cc/surfaces/display.h" | 13 #include "cc/surfaces/display.h" |
| 14 #include "cc/surfaces/surface.h" | 14 #include "cc/surfaces/surface.h" |
| 15 #include "cc/surfaces/surface_info.h" |
| 15 #include "cc/surfaces/surface_manager.h" | 16 #include "cc/surfaces/surface_manager.h" |
| 16 #include "cc/surfaces/surface_reference.h" | 17 #include "cc/surfaces/surface_reference.h" |
| 17 | 18 |
| 18 namespace cc { | 19 namespace cc { |
| 19 | 20 |
| 20 CompositorFrameSinkSupport::CompositorFrameSinkSupport( | 21 CompositorFrameSinkSupport::CompositorFrameSinkSupport( |
| 21 CompositorFrameSinkSupportClient* client, | 22 CompositorFrameSinkSupportClient* client, |
| 22 SurfaceManager* surface_manager, | 23 SurfaceManager* surface_manager, |
| 23 const FrameSinkId& frame_sink_id, | 24 const FrameSinkId& frame_sink_id, |
| 24 bool is_root, | 25 bool is_root, |
| 25 bool handles_frame_sink_id_invalidation, | 26 bool handles_frame_sink_id_invalidation, |
| 26 bool needs_sync_points) | 27 bool needs_sync_points) |
| 27 : client_(client), | 28 : client_(client), |
| 28 surface_manager_(surface_manager), | 29 surface_manager_(surface_manager), |
| 30 surface_resource_holder_(this), |
| 29 frame_sink_id_(frame_sink_id), | 31 frame_sink_id_(frame_sink_id), |
| 30 surface_factory_(frame_sink_id_, surface_manager_, this), | |
| 31 reference_tracker_(frame_sink_id), | 32 reference_tracker_(frame_sink_id), |
| 32 is_root_(is_root), | 33 is_root_(is_root), |
| 34 needs_sync_points_(needs_sync_points), |
| 33 handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation), | 35 handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation), |
| 34 weak_factory_(this) { | 36 weak_factory_(this) { |
| 35 surface_factory_.set_needs_sync_points(needs_sync_points); | |
| 36 if (handles_frame_sink_id_invalidation_) | 37 if (handles_frame_sink_id_invalidation_) |
| 37 surface_manager_->RegisterFrameSinkId(frame_sink_id_); | 38 surface_manager_->RegisterFrameSinkId(frame_sink_id_); |
| 38 surface_manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); | 39 surface_manager_->RegisterCompositorFrameSinkSupport(frame_sink_id_, this); |
| 39 } | 40 } |
| 40 | 41 |
| 41 CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { | 42 CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { |
| 42 // Unregister |this| as a BeginFrameObserver so that the BeginFrameSource does | 43 // Unregister |this| as a BeginFrameObserver so that the BeginFrameSource does |
| 43 // not call into |this| after it's deleted. | 44 // not call into |this| after it's deleted. |
| 44 SetNeedsBeginFrame(false); | 45 SetNeedsBeginFrame(false); |
| 45 | 46 |
| 46 // For display root surfaces, the surface is no longer going to be visible | 47 // For display root surfaces, the surface is no longer going to be visible |
| 47 // so make it unreachable from the top-level root. | 48 // so make it unreachable from the top-level root. |
| 48 if (surface_manager_->using_surface_references() && is_root_ && | 49 if (surface_manager_->using_surface_references() && is_root_ && |
| 49 reference_tracker_.current_surface_id().is_valid()) | 50 reference_tracker_.current_surface_id().is_valid()) |
| 50 RemoveTopLevelRootReference(reference_tracker_.current_surface_id()); | 51 RemoveTopLevelRootReference(reference_tracker_.current_surface_id()); |
| 51 | 52 |
| 52 // SurfaceFactory's destructor will attempt to return resources which will | 53 EvictFrame(); |
| 53 // call back into here and access |client_| so we should destroy | 54 surface_manager_->UnregisterCompositorFrameSinkSupport(frame_sink_id_); |
| 54 // |surface_factory_|'s resources early on. | |
| 55 surface_factory_.EvictSurface(); | |
| 56 surface_manager_->UnregisterSurfaceFactoryClient(frame_sink_id_); | |
| 57 if (handles_frame_sink_id_invalidation_) | 55 if (handles_frame_sink_id_invalidation_) |
| 58 surface_manager_->InvalidateFrameSinkId(frame_sink_id_); | 56 surface_manager_->InvalidateFrameSinkId(frame_sink_id_); |
| 59 } | 57 } |
| 60 | 58 |
| 61 void CompositorFrameSinkSupport::EvictFrame() { | 59 void CompositorFrameSinkSupport::EvictFrame() { |
| 62 surface_factory_.EvictSurface(); | 60 if (!current_surface_) |
| 61 return; |
| 62 DestroyCurrentSurface(); |
| 63 } | 63 } |
| 64 | 64 |
| 65 void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { | 65 void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { |
| 66 needs_begin_frame_ = needs_begin_frame; | 66 needs_begin_frame_ = needs_begin_frame; |
| 67 UpdateNeedsBeginFramesInternal(); | 67 UpdateNeedsBeginFramesInternal(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 void CompositorFrameSinkSupport::BeginFrameDidNotSwap( | 70 void CompositorFrameSinkSupport::BeginFrameDidNotSwap( |
| 71 const BeginFrameAck& ack) { | 71 const BeginFrameAck& ack) { |
| 72 // TODO(eseckler): While a pending CompositorFrame exists (see TODO below), we | 72 // TODO(eseckler): While a pending CompositorFrame exists (see TODO below), we |
| 73 // should not acknowledge immediately. Instead, we should update the ack that | 73 // should not acknowledge immediately. Instead, we should update the ack that |
| 74 // will be sent to DisplayScheduler when the pending frame is activated. | 74 // will be sent to DisplayScheduler when the pending frame is activated. |
| 75 if (ack.sequence_number < BeginFrameArgs::kStartingFrameNumber) { | 75 if (ack.sequence_number < BeginFrameArgs::kStartingFrameNumber) { |
| 76 DLOG(ERROR) << "Received BeginFrameDidNotSwap with invalid BeginFrameAck."; | 76 DLOG(ERROR) << "Received BeginFrameDidNotSwap with invalid BeginFrameAck."; |
| 77 return; | 77 return; |
| 78 } | 78 } |
| 79 | 79 |
| 80 // |has_damage| is not transmitted, but false by default. | 80 // |has_damage| is not transmitted, but false by default. |
| 81 DCHECK(!ack.has_damage); | 81 DCHECK(!ack.has_damage); |
| 82 if (begin_frame_source_) | 82 if (begin_frame_source_) |
| 83 begin_frame_source_->DidFinishFrame(this, ack); | 83 begin_frame_source_->DidFinishFrame(this, ack); |
| 84 } | 84 } |
| 85 | 85 |
| 86 void CompositorFrameSinkSupport::SubmitCompositorFrame( | 86 void CompositorFrameSinkSupport::SubmitCompositorFrame( |
| 87 const LocalSurfaceId& local_surface_id, | 87 const LocalSurfaceId& local_surface_id, |
| 88 CompositorFrame frame) { | 88 CompositorFrame frame) { |
| 89 DCHECK(local_surface_id.is_valid()); |
| 90 TRACE_EVENT0("cc", "CompositorFrameSinkSupport::SubmitCompositorFrame"); |
| 89 ++ack_pending_count_; | 91 ++ack_pending_count_; |
| 90 | 92 |
| 91 if (frame.metadata.begin_frame_ack.sequence_number < | 93 if (frame.metadata.begin_frame_ack.sequence_number < |
| 92 BeginFrameArgs::kStartingFrameNumber) { | 94 BeginFrameArgs::kStartingFrameNumber) { |
| 93 DLOG(ERROR) << "Received CompositorFrame with invalid BeginFrameAck."; | 95 DLOG(ERROR) << "Received CompositorFrame with invalid BeginFrameAck."; |
| 94 frame.metadata.begin_frame_ack.source_id = BeginFrameArgs::kManualSourceId; | 96 frame.metadata.begin_frame_ack.source_id = BeginFrameArgs::kManualSourceId; |
| 95 frame.metadata.begin_frame_ack.sequence_number = | 97 frame.metadata.begin_frame_ack.sequence_number = |
| 96 BeginFrameArgs::kStartingFrameNumber; | 98 BeginFrameArgs::kStartingFrameNumber; |
| 97 } | 99 } |
| 98 // |has_damage| is not transmitted. | 100 // |has_damage| is not transmitted. |
| 99 frame.metadata.begin_frame_ack.has_damage = true; | 101 frame.metadata.begin_frame_ack.has_damage = true; |
| 100 | 102 |
| 101 BeginFrameAck ack = frame.metadata.begin_frame_ack; | 103 BeginFrameAck ack = frame.metadata.begin_frame_ack; |
| 102 surface_factory_.SubmitCompositorFrame( | 104 |
| 103 local_surface_id, std::move(frame), | 105 DCHECK(local_surface_id.is_valid()); |
| 106 std::unique_ptr<Surface> surface; |
| 107 bool create_new_surface = |
| 108 (!current_surface_ || |
| 109 local_surface_id != current_surface_->surface_id().local_surface_id()); |
| 110 if (!create_new_surface) { |
| 111 surface = std::move(current_surface_); |
| 112 } else { |
| 113 surface = CreateSurface(local_surface_id); |
| 114 } |
| 115 surface->QueueFrame( |
| 116 std::move(frame), |
| 104 base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck, | 117 base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck, |
| 105 weak_factory_.GetWeakPtr())); | 118 weak_factory_.GetWeakPtr())); |
| 106 | 119 |
| 120 if (!surface_manager_->SurfaceModified( |
| 121 SurfaceId(frame_sink_id_, local_surface_id))) { |
| 122 TRACE_EVENT_INSTANT0("cc", "Damage not visible.", TRACE_EVENT_SCOPE_THREAD); |
| 123 surface->RunDrawCallbacks(); |
| 124 } |
| 125 if (current_surface_ && create_new_surface) { |
| 126 surface->SetPreviousFrameSurface(current_surface_.get()); |
| 127 DestroyCurrentSurface(); |
| 128 } |
| 129 current_surface_ = std::move(surface); |
| 130 |
| 107 // TODO(eseckler): The CompositorFrame submitted below might not be activated | 131 // TODO(eseckler): The CompositorFrame submitted below might not be activated |
| 108 // right away b/c of surface synchronization. We should only send the | 132 // right away b/c of surface synchronization. We should only send the |
| 109 // BeginFrameAck to DisplayScheduler when it is activated. This also means | 133 // BeginFrameAck to DisplayScheduler when it is activated. This also means |
| 110 // that we need to stay an active BFO while a CompositorFrame is pending. | 134 // that we need to stay an active BFO while a CompositorFrame is pending. |
| 111 // See https://crbug.com/703079. | 135 // See https://crbug.com/703079. |
| 112 if (begin_frame_source_) | 136 if (begin_frame_source_) |
| 113 begin_frame_source_->DidFinishFrame(this, ack); | 137 begin_frame_source_->DidFinishFrame(this, ack); |
| 114 } | 138 } |
| 115 | 139 |
| 116 void CompositorFrameSinkSupport::UpdateSurfaceReferences( | 140 void CompositorFrameSinkSupport::UpdateSurfaceReferences( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 // We return the resources before sending an ack so they can be reused in | 192 // We return the resources before sending an ack so they can be reused in |
| 169 // making the next CompositorFrame. | 193 // making the next CompositorFrame. |
| 170 if (!surface_returned_resources_.empty()) { | 194 if (!surface_returned_resources_.empty()) { |
| 171 client_->ReclaimResources(surface_returned_resources_); | 195 client_->ReclaimResources(surface_returned_resources_); |
| 172 surface_returned_resources_.clear(); | 196 surface_returned_resources_.clear(); |
| 173 } | 197 } |
| 174 client_->DidReceiveCompositorFrameAck(); | 198 client_->DidReceiveCompositorFrameAck(); |
| 175 } | 199 } |
| 176 | 200 |
| 177 void CompositorFrameSinkSupport::ForceReclaimResources() { | 201 void CompositorFrameSinkSupport::ForceReclaimResources() { |
| 178 surface_factory_.ClearSurface(); | 202 if (!current_surface_) |
| 203 return; |
| 204 current_surface_->EvictFrame(); |
| 205 surface_manager_->SurfaceModified(current_surface_->surface_id()); |
| 179 } | 206 } |
| 180 | 207 |
| 181 void CompositorFrameSinkSupport::ClaimTemporaryReference( | 208 void CompositorFrameSinkSupport::ClaimTemporaryReference( |
| 182 const SurfaceId& surface_id) { | 209 const SurfaceId& surface_id) { |
| 183 surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_); | 210 surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_); |
| 184 } | 211 } |
| 185 | 212 |
| 213 void CompositorFrameSinkSupport::ReceiveFromChild( |
| 214 const TransferableResourceArray& resources) { |
| 215 surface_resource_holder_.ReceiveFromChild(resources); |
| 216 } |
| 217 |
| 218 void CompositorFrameSinkSupport::RefResources( |
| 219 const TransferableResourceArray& resources) { |
| 220 surface_resource_holder_.RefResources(resources); |
| 221 } |
| 222 |
| 223 void CompositorFrameSinkSupport::UnrefResources( |
| 224 const ReturnedResourceArray& resources) { |
| 225 surface_resource_holder_.UnrefResources(resources); |
| 226 } |
| 227 |
| 186 BeginFrameSource* CompositorFrameSinkSupport::BeginFrameSourceForTesting() | 228 BeginFrameSource* CompositorFrameSinkSupport::BeginFrameSourceForTesting() |
| 187 const { | 229 const { |
| 188 return begin_frame_source_; | 230 return begin_frame_source_; |
| 189 } | 231 } |
| 190 | 232 |
| 191 void CompositorFrameSinkSupport::ReferencedSurfacesChanged( | |
| 192 const LocalSurfaceId& local_surface_id, | |
| 193 const std::vector<SurfaceId>* active_referenced_surfaces, | |
| 194 const std::vector<SurfaceId>* pending_referenced_surfaces) { | |
| 195 if (!surface_manager_->using_surface_references()) | |
| 196 return; | |
| 197 | |
| 198 SurfaceId last_surface_id = reference_tracker_.current_surface_id(); | |
| 199 | |
| 200 // Populate list of surface references to add and remove based on reference | |
| 201 // surfaces in current frame compared with the last frame. The list of | |
| 202 // surface references includes references from both the pending and active | |
| 203 // frame if any. | |
| 204 reference_tracker_.UpdateReferences(local_surface_id, | |
| 205 active_referenced_surfaces, | |
| 206 pending_referenced_surfaces); | |
| 207 | |
| 208 UpdateSurfaceReferences(last_surface_id, local_surface_id); | |
| 209 } | |
| 210 | |
| 211 void CompositorFrameSinkSupport::ReturnResources( | 233 void CompositorFrameSinkSupport::ReturnResources( |
| 212 const ReturnedResourceArray& resources) { | 234 const ReturnedResourceArray& resources) { |
| 213 if (resources.empty()) | 235 if (resources.empty()) |
| 214 return; | 236 return; |
| 215 | 237 |
| 216 if (!ack_pending_count_ && client_) { | 238 if (!ack_pending_count_ && client_) { |
| 217 client_->ReclaimResources(resources); | 239 client_->ReclaimResources(resources); |
| 218 return; | 240 return; |
| 219 } | 241 } |
| 220 | 242 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 246 client_->OnBeginFrame(args); | 268 client_->OnBeginFrame(args); |
| 247 } | 269 } |
| 248 | 270 |
| 249 const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs() | 271 const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs() |
| 250 const { | 272 const { |
| 251 return last_begin_frame_args_; | 273 return last_begin_frame_args_; |
| 252 } | 274 } |
| 253 | 275 |
| 254 void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} | 276 void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} |
| 255 | 277 |
| 278 void CompositorFrameSinkSupport::OnReferencedSurfacesChanged( |
| 279 Surface* surface, |
| 280 const std::vector<SurfaceId>* active_referenced_surfaces, |
| 281 const std::vector<SurfaceId>* pending_referenced_surfaces) { |
| 282 if (!surface_manager_->using_surface_references()) |
| 283 return; |
| 284 |
| 285 SurfaceId last_surface_id = reference_tracker_.current_surface_id(); |
| 286 LocalSurfaceId local_surface_id = surface->surface_id().local_surface_id(); |
| 287 // Populate list of surface references to add and remove based on reference |
| 288 // surfaces in current frame compared with the last frame. The list of |
| 289 // surface references includes references from both the pending and active |
| 290 // frame if any. |
| 291 reference_tracker_.UpdateReferences(local_surface_id, |
| 292 active_referenced_surfaces, |
| 293 pending_referenced_surfaces); |
| 294 |
| 295 UpdateSurfaceReferences(last_surface_id, local_surface_id); |
| 296 } |
| 297 |
| 298 void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) { |
| 299 DCHECK(surface->HasActiveFrame()); |
| 300 // TODO(staraz): Notify BeginFrameSource about the last activated sequence |
| 301 // number. |
| 302 if (seen_first_frame_activation_) |
| 303 return; |
| 304 |
| 305 seen_first_frame_activation_ = true; |
| 306 |
| 307 const CompositorFrame& frame = surface->GetActiveFrame(); |
| 308 // CompositorFrames might not be populated with a RenderPass in unit tests. |
| 309 gfx::Size frame_size; |
| 310 if (!frame.render_pass_list.empty()) |
| 311 frame_size = frame.render_pass_list.back()->output_rect.size(); |
| 312 |
| 313 // SurfaceCreated only applies for the first Surface activation. Thus, |
| 314 // CompositorFrameSinkSupport stops observing new activations after the first |
| 315 // one. |
| 316 surface_manager_->SurfaceCreated(SurfaceInfo( |
| 317 surface->surface_id(), frame.metadata.device_scale_factor, frame_size)); |
| 318 } |
| 319 |
| 320 void CompositorFrameSinkSupport::OnSurfaceDependenciesChanged( |
| 321 Surface* surface, |
| 322 const SurfaceDependencies& added_dependencies, |
| 323 const SurfaceDependencies& removed_dependencies) {} |
| 324 |
| 325 void CompositorFrameSinkSupport::OnSurfaceDiscarded(Surface* surface) {} |
| 326 |
| 256 void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { | 327 void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { |
| 257 if (!begin_frame_source_) | 328 if (!begin_frame_source_) |
| 258 return; | 329 return; |
| 259 | 330 |
| 260 if (needs_begin_frame_ == added_frame_observer_) | 331 if (needs_begin_frame_ == added_frame_observer_) |
| 261 return; | 332 return; |
| 262 | 333 |
| 263 added_frame_observer_ = needs_begin_frame_; | 334 added_frame_observer_ = needs_begin_frame_; |
| 264 if (needs_begin_frame_) | 335 if (needs_begin_frame_) |
| 265 begin_frame_source_->AddObserver(this); | 336 begin_frame_source_->AddObserver(this); |
| 266 else | 337 else |
| 267 begin_frame_source_->RemoveObserver(this); | 338 begin_frame_source_->RemoveObserver(this); |
| 268 } | 339 } |
| 269 | 340 |
| 341 std::unique_ptr<Surface> CompositorFrameSinkSupport::CreateSurface( |
| 342 const LocalSurfaceId& local_surface_id) { |
| 343 seen_first_frame_activation_ = false; |
| 344 std::unique_ptr<Surface> surface = surface_manager_->CreateSurface( |
| 345 weak_factory_.GetWeakPtr(), local_surface_id); |
| 346 surface->AddObserver(this); |
| 347 return surface; |
| 348 } |
| 349 |
| 350 void CompositorFrameSinkSupport::DestroyCurrentSurface() { |
| 351 current_surface_->RemoveObserver(this); |
| 352 surface_manager_->DestroySurface(std::move(current_surface_)); |
| 353 } |
| 354 |
| 270 void CompositorFrameSinkSupport::RequestCopyOfSurface( | 355 void CompositorFrameSinkSupport::RequestCopyOfSurface( |
| 271 std::unique_ptr<CopyOutputRequest> request) { | 356 std::unique_ptr<CopyOutputRequest> copy_request) { |
| 272 surface_factory_.RequestCopyOfSurface(std::move(request)); | 357 if (!current_surface_) { |
| 358 copy_request->SendEmptyResult(); |
| 359 return; |
| 360 } |
| 361 DCHECK(current_surface_->compositor_frame_sink_support().get() == this); |
| 362 current_surface_->RequestCopyOfOutput(std::move(copy_request)); |
| 363 surface_manager_->SurfaceModified(current_surface_->surface_id()); |
| 273 } | 364 } |
| 274 | 365 |
| 275 } // namespace cc | 366 } // namespace cc |
| OLD | NEW |