Chromium Code Reviews| Index: cc/surfaces/compositor_frame_sink_support.cc |
| diff --git a/cc/surfaces/compositor_frame_sink_support.cc b/cc/surfaces/compositor_frame_sink_support.cc |
| index 7fc9e6556d46ce13067d902aa23a44019747c27e..46508a03d71390b348a2f43699f98262af98bcc9 100644 |
| --- a/cc/surfaces/compositor_frame_sink_support.cc |
| +++ b/cc/surfaces/compositor_frame_sink_support.cc |
| @@ -12,6 +12,7 @@ |
| #include "cc/surfaces/compositor_frame_sink_support_client.h" |
| #include "cc/surfaces/display.h" |
| #include "cc/surfaces/surface.h" |
| +#include "cc/surfaces/surface_info.h" |
| #include "cc/surfaces/surface_manager.h" |
| #include "cc/surfaces/surface_reference.h" |
| @@ -43,37 +44,17 @@ CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { |
| reference_tracker_.current_surface_id().is_valid()) |
| RemoveTopLevelRootReference(reference_tracker_.current_surface_id()); |
| - // SurfaceFactory's destructor will attempt to return resources which will |
| - // call back into here and access |client_| so we should destroy |
| - // |surface_factory_|'s resources early on. |
| - surface_factory_->EvictSurface(); |
| + EvictFrame(); |
| surface_manager_->UnregisterFrameSinkManagerClient(frame_sink_id_); |
| if (handles_frame_sink_id_invalidation_) |
| surface_manager_->InvalidateFrameSinkId(frame_sink_id_); |
| } |
| -void CompositorFrameSinkSupport::ReferencedSurfacesChanged( |
| - const LocalSurfaceId& local_surface_id, |
| - const std::vector<SurfaceId>* active_referenced_surfaces) { |
| - if (!surface_manager_->using_surface_references()) |
| - return; |
| - |
| - SurfaceId last_surface_id = reference_tracker_.current_surface_id(); |
| - |
| - // Populate list of surface references to add and remove based on reference |
| - // surfaces in current frame compared with the last frame. The list of |
| - // surface references includes references from both the pending and active |
| - // frame if any. |
| - reference_tracker_.UpdateReferences(local_surface_id, |
| - active_referenced_surfaces); |
| - |
| - UpdateSurfaceReferences(last_surface_id, local_surface_id); |
| -} |
| - |
| void CompositorFrameSinkSupport::ReturnResources( |
| const ReturnedResourceArray& resources) { |
| if (resources.empty()) |
| return; |
| + |
|
Fady Samuel
2017/04/26 00:44:13
unnecessary change. Please delete.
Alex Z.
2017/04/27 22:10:01
Done.
|
| if (!ack_pending_count_ && client_) { |
| client_->ReclaimResources(resources); |
| return; |
| @@ -94,8 +75,9 @@ void CompositorFrameSinkSupport::SetBeginFrameSource( |
| } |
| void CompositorFrameSinkSupport::EvictFrame() { |
| - DCHECK(surface_factory_); |
| - surface_factory_->EvictSurface(); |
| + if (!current_surface_) |
| + return; |
| + DestroyCurrentSurface(); |
| } |
| void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { |
| @@ -122,7 +104,9 @@ void CompositorFrameSinkSupport::BeginFrameDidNotSwap( |
| void CompositorFrameSinkSupport::SubmitCompositorFrame( |
| const LocalSurfaceId& local_surface_id, |
| CompositorFrame frame) { |
| - DCHECK(surface_factory_); |
| + TRACE_EVENT0("cc", "CompositorFrameSinkSupport::SubmitCompositorFrame"); |
| + DCHECK(local_surface_id.is_valid()); |
| + TRACE_EVENT0("cc", "CompositorFrameSinkSupport::SubmitCompositorFrame"); |
|
Fady Samuel
2017/04/26 00:44:13
Why is this trace event listed twice?
Alex Z.
2017/04/27 22:10:01
It must've got during rebase. It's removed now.
|
| ++ack_pending_count_; |
| if (frame.metadata.begin_frame_ack.sequence_number < |
| @@ -136,13 +120,38 @@ void CompositorFrameSinkSupport::SubmitCompositorFrame( |
| frame.metadata.begin_frame_ack.has_damage = true; |
| BeginFrameAck ack = frame.metadata.begin_frame_ack; |
| - surface_factory_->SubmitCompositorFrame( |
| - local_surface_id, std::move(frame), |
| + |
| + DCHECK(local_surface_id.is_valid()); |
| + |
| + for (ui::LatencyInfo& latency : frame.metadata.latency_info) { |
| + if (latency.latency_components().size() > 0) { |
| + latency.AddLatencyNumber(ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, |
| + 0, 0); |
| + } |
| + } |
| + |
| + std::unique_ptr<Surface> surface; |
| + bool create_new_surface = |
| + (!current_surface_ || |
| + local_surface_id != current_surface_->surface_id().local_surface_id()); |
| + if (!create_new_surface) { |
| + surface = std::move(current_surface_); |
| + } else { |
| + surface = CreateSurface(local_surface_id); |
| + } |
| + surface->QueueFrame( |
| + std::move(frame), |
| base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck, |
| weak_factory_.GetWeakPtr()), |
| base::BindRepeating(&CompositorFrameSinkSupport::WillDrawSurface, |
| weak_factory_.GetWeakPtr())); |
| + if (current_surface_ && create_new_surface) { |
| + surface->SetPreviousFrameSurface(current_surface_.get()); |
| + DestroyCurrentSurface(); |
| + } |
| + current_surface_ = std::move(surface); |
| + |
| // TODO(eseckler): The CompositorFrame submitted below might not be activated |
| // right away b/c of surface synchronization. We should only send the |
| // BeginFrameAck to DisplayScheduler when it is activated. This also means |
| @@ -197,11 +206,30 @@ void CompositorFrameSinkSupport::RemoveTopLevelRootReference( |
| surface_manager_->RemoveSurfaceReferences({reference}); |
| } |
| +void CompositorFrameSinkSupport::ReferencedSurfacesChanged( |
| + const LocalSurfaceId& local_surface_id, |
| + const std::vector<SurfaceId>* active_referenced_surfaces) { |
| + if (!surface_manager_->using_surface_references()) |
| + return; |
| + |
| + SurfaceId last_surface_id = reference_tracker_.current_surface_id(); |
| + |
| + // Populate list of surface references to add and remove based on reference |
| + // surfaces in current frame compared with the last frame. The list of |
| + // surface references includes references from both the pending and active |
| + // frame if any. |
| + reference_tracker_.UpdateReferences(local_surface_id, |
| + active_referenced_surfaces); |
| + |
| + UpdateSurfaceReferences(last_surface_id, local_surface_id); |
| +} |
| + |
| void CompositorFrameSinkSupport::DidReceiveCompositorFrameAck() { |
| DCHECK_GT(ack_pending_count_, 0); |
| ack_pending_count_--; |
| if (!client_) |
| return; |
| + |
| client_->DidReceiveCompositorFrameAck(surface_returned_resources_); |
| surface_returned_resources_.clear(); |
| } |
| @@ -214,8 +242,10 @@ void CompositorFrameSinkSupport::WillDrawSurface( |
| } |
| void CompositorFrameSinkSupport::ForceReclaimResources() { |
|
Fady Samuel
2017/04/26 00:44:13
This should be going away now.
Alex Z.
2017/04/27 22:10:01
Done.
|
| - DCHECK(surface_factory_); |
| - surface_factory_->ClearSurface(); |
| + if (!current_surface_) |
| + return; |
| + current_surface_->EvictFrame(); |
| + surface_manager_->SurfaceModified(current_surface_->surface_id()); |
| } |
| void CompositorFrameSinkSupport::ClaimTemporaryReference( |
| @@ -223,6 +253,26 @@ void CompositorFrameSinkSupport::ClaimTemporaryReference( |
| surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_); |
| } |
| +void CompositorFrameSinkSupport::ReceiveFromChild( |
|
Fady Samuel
2017/04/26 00:44:13
It would be nice not having these public..
Alex Z.
2017/04/27 22:10:01
Done.
|
| + const TransferableResourceArray& resources) { |
| + surface_resource_holder_.ReceiveFromChild(resources); |
| +} |
| + |
| +void CompositorFrameSinkSupport::RefResources( |
| + const TransferableResourceArray& resources) { |
| + surface_resource_holder_.RefResources(resources); |
| +} |
| + |
| +void CompositorFrameSinkSupport::UnrefResources( |
| + const ReturnedResourceArray& resources) { |
| + surface_resource_holder_.UnrefResources(resources); |
| +} |
| + |
| +void CompositorFrameSinkSupport::ForceAck() { |
|
Fady Samuel
2017/04/26 00:44:13
What uses this? Delete it perhaps?
Alex Z.
2017/04/27 22:10:01
Done.
|
| + ++ack_pending_count_; |
| + DidReceiveCompositorFrameAck(); |
| +} |
| + |
| CompositorFrameSinkSupport::CompositorFrameSinkSupport( |
| CompositorFrameSinkSupportClient* client, |
| const FrameSinkId& frame_sink_id, |
| @@ -230,6 +280,7 @@ CompositorFrameSinkSupport::CompositorFrameSinkSupport( |
| bool handles_frame_sink_id_invalidation) |
| : client_(client), |
| frame_sink_id_(frame_sink_id), |
| + surface_resource_holder_(this), |
| reference_tracker_(frame_sink_id), |
| is_root_(is_root), |
| handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation), |
| @@ -238,12 +289,10 @@ CompositorFrameSinkSupport::CompositorFrameSinkSupport( |
| void CompositorFrameSinkSupport::Init(SurfaceManager* surface_manager, |
| bool needs_sync_points) { |
| surface_manager_ = surface_manager; |
| - surface_factory_ = base::MakeUnique<SurfaceFactory>( |
| - frame_sink_id_, surface_manager_, this, this); |
| if (handles_frame_sink_id_invalidation_) |
| surface_manager_->RegisterFrameSinkId(frame_sink_id_); |
| surface_manager_->RegisterFrameSinkManagerClient(frame_sink_id_, this); |
| - surface_factory_->set_needs_sync_points(needs_sync_points); |
| + needs_sync_points_ = needs_sync_points; |
| } |
| void CompositorFrameSinkSupport::OnBeginFrame(const BeginFrameArgs& args) { |
| @@ -260,6 +309,41 @@ const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs() |
| void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} |
| +void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) { |
| + DCHECK(surface->HasActiveFrame()); |
| + // TODO(staraz): Notify BeginFrameSource about the last activated sequence |
| + // number. |
| + if (!seen_first_frame_activation_) { |
| + seen_first_frame_activation_ = true; |
| + |
| + const CompositorFrame& frame = surface->GetActiveFrame(); |
| + // CompositorFrames might not be populated with a RenderPass in unit tests. |
| + gfx::Size frame_size; |
| + if (!frame.render_pass_list.empty()) |
| + frame_size = frame.render_pass_list.back()->output_rect.size(); |
| + |
| + // SurfaceCreated only applies for the first Surface activation. Thus, |
| + // SurfaceFactory stops observing new activations after the first one. |
| + surface_manager_->SurfaceCreated(SurfaceInfo( |
| + surface->surface_id(), frame.metadata.device_scale_factor, frame_size)); |
| + } |
| + // Fire SurfaceCreated first so that a temporary reference is added before it |
| + // is potentially transformed into a real reference by the client. |
| + ReferencedSurfacesChanged(surface->surface_id().local_surface_id(), |
| + surface->active_referenced_surfaces()); |
| + if (!surface_manager_->SurfaceModified(surface->surface_id())) { |
| + TRACE_EVENT_INSTANT0("cc", "Damage not visible.", TRACE_EVENT_SCOPE_THREAD); |
| + surface->RunDrawCallback(); |
| + } |
| +} |
| + |
| +void CompositorFrameSinkSupport::OnSurfaceDependenciesChanged( |
| + Surface* surface, |
| + const SurfaceDependencies& added_dependencies, |
| + const SurfaceDependencies& removed_dependencies) {} |
| + |
| +void CompositorFrameSinkSupport::OnSurfaceDiscarded(Surface* surface) {} |
| + |
| void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { |
| if (!begin_frame_source_) |
| return; |
| @@ -274,10 +358,29 @@ void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { |
| begin_frame_source_->RemoveObserver(this); |
| } |
| +std::unique_ptr<Surface> CompositorFrameSinkSupport::CreateSurface( |
| + const LocalSurfaceId& local_surface_id) { |
| + seen_first_frame_activation_ = false; |
| + std::unique_ptr<Surface> surface = surface_manager_->CreateSurface( |
| + weak_factory_.GetWeakPtr(), local_surface_id); |
| + surface->AddObserver(this); |
| + return surface; |
| +} |
| + |
| +void CompositorFrameSinkSupport::DestroyCurrentSurface() { |
| + current_surface_->RemoveObserver(this); |
| + surface_manager_->DestroySurface(std::move(current_surface_)); |
| +} |
| + |
| void CompositorFrameSinkSupport::RequestCopyOfSurface( |
| - std::unique_ptr<CopyOutputRequest> request) { |
| - DCHECK(surface_factory_); |
| - surface_factory_->RequestCopyOfSurface(std::move(request)); |
| + std::unique_ptr<CopyOutputRequest> copy_request) { |
| + if (!current_surface_) { |
| + copy_request->SendEmptyResult(); |
| + return; |
| + } |
| + DCHECK(current_surface_->compositor_frame_sink_support().get() == this); |
| + current_surface_->RequestCopyOfOutput(std::move(copy_request)); |
| + surface_manager_->SurfaceModified(current_surface_->surface_id()); |
| } |
| } // namespace cc |