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 c89843a81c855cd20fc2b49e1a6545f4f245ffe5..1d581bd9a8f24c1bbc2c9cb3c3c7dbe03ffd59c6 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" |
@@ -26,16 +27,16 @@ CompositorFrameSinkSupport::CompositorFrameSinkSupport( |
bool needs_sync_points) |
: client_(client), |
surface_manager_(surface_manager), |
+ surface_resource_holder_(this), |
frame_sink_id_(frame_sink_id), |
- surface_factory_(frame_sink_id_, surface_manager_, this), |
reference_tracker_(frame_sink_id), |
is_root_(is_root), |
+ needs_sync_points_(needs_sync_points), |
handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation), |
weak_factory_(this) { |
- surface_factory_.set_needs_sync_points(needs_sync_points); |
if (handles_frame_sink_id_invalidation_) |
surface_manager_->RegisterFrameSinkId(frame_sink_id_); |
- surface_manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); |
+ surface_manager_->RegisterCompositorFrameSinkSupport(frame_sink_id_, this); |
} |
CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { |
@@ -49,17 +50,16 @@ 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(); |
- surface_manager_->UnregisterSurfaceFactoryClient(frame_sink_id_); |
+ EvictFrame(); |
+ surface_manager_->UnregisterCompositorFrameSinkSupport(frame_sink_id_); |
if (handles_frame_sink_id_invalidation_) |
surface_manager_->InvalidateFrameSinkId(frame_sink_id_); |
} |
void CompositorFrameSinkSupport::EvictFrame() { |
- surface_factory_.EvictSurface(); |
+ if (!current_surface_) |
+ return; |
+ DestroyCurrentSurface(); |
} |
void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { |
@@ -86,6 +86,8 @@ void CompositorFrameSinkSupport::BeginFrameDidNotSwap( |
void CompositorFrameSinkSupport::SubmitCompositorFrame( |
const LocalSurfaceId& local_surface_id, |
CompositorFrame frame) { |
+ DCHECK(local_surface_id.is_valid()); |
+ TRACE_EVENT0("cc", "CompositorFrameSinkSupport::SubmitCompositorFrame"); |
++ack_pending_count_; |
if (frame.metadata.begin_frame_ack.sequence_number < |
@@ -99,11 +101,33 @@ 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()); |
+ 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())); |
+ if (!surface_manager_->SurfaceModified( |
+ SurfaceId(frame_sink_id_, local_surface_id))) { |
+ TRACE_EVENT_INSTANT0("cc", "Damage not visible.", TRACE_EVENT_SCOPE_THREAD); |
+ surface->RunDrawCallbacks(); |
+ } |
+ 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 |
@@ -175,7 +199,10 @@ void CompositorFrameSinkSupport::DidReceiveCompositorFrameAck() { |
} |
void CompositorFrameSinkSupport::ForceReclaimResources() { |
- surface_factory_.ClearSurface(); |
+ if (!current_surface_) |
+ return; |
+ current_surface_->EvictFrame(); |
+ surface_manager_->SurfaceModified(current_surface_->surface_id()); |
} |
void CompositorFrameSinkSupport::ClaimTemporaryReference( |
@@ -183,29 +210,24 @@ void CompositorFrameSinkSupport::ClaimTemporaryReference( |
surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_); |
} |
-BeginFrameSource* CompositorFrameSinkSupport::BeginFrameSourceForTesting() |
- const { |
- return begin_frame_source_; |
+void CompositorFrameSinkSupport::ReceiveFromChild( |
+ const TransferableResourceArray& resources) { |
+ surface_resource_holder_.ReceiveFromChild(resources); |
} |
-void CompositorFrameSinkSupport::ReferencedSurfacesChanged( |
- const LocalSurfaceId& local_surface_id, |
- const std::vector<SurfaceId>* active_referenced_surfaces, |
- const std::vector<SurfaceId>* pending_referenced_surfaces) { |
- if (!surface_manager_->using_surface_references()) |
- return; |
- |
- SurfaceId last_surface_id = reference_tracker_.current_surface_id(); |
+void CompositorFrameSinkSupport::RefResources( |
+ const TransferableResourceArray& resources) { |
+ surface_resource_holder_.RefResources(resources); |
+} |
- // 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, |
- pending_referenced_surfaces); |
+void CompositorFrameSinkSupport::UnrefResources( |
+ const ReturnedResourceArray& resources) { |
+ surface_resource_holder_.UnrefResources(resources); |
+} |
- UpdateSurfaceReferences(last_surface_id, local_surface_id); |
+BeginFrameSource* CompositorFrameSinkSupport::BeginFrameSourceForTesting() |
+ const { |
+ return begin_frame_source_; |
} |
void CompositorFrameSinkSupport::ReturnResources( |
@@ -253,6 +275,55 @@ const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs() |
void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} |
+void CompositorFrameSinkSupport::OnReferencedSurfacesChanged( |
+ Surface* surface, |
+ const std::vector<SurfaceId>* active_referenced_surfaces, |
+ const std::vector<SurfaceId>* pending_referenced_surfaces) { |
+ if (!surface_manager_->using_surface_references()) |
+ return; |
+ |
+ SurfaceId last_surface_id = reference_tracker_.current_surface_id(); |
+ LocalSurfaceId local_surface_id = surface->surface_id().local_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, |
+ pending_referenced_surfaces); |
+ |
+ UpdateSurfaceReferences(last_surface_id, local_surface_id); |
+} |
+ |
+void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) { |
+ DCHECK(surface->HasActiveFrame()); |
+ // TODO(staraz): Notify BeginFrameSource about the last activated sequence |
+ // number. |
+ if (seen_first_frame_activation_) |
+ return; |
+ |
+ 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, |
+ // CompositorFrameSinkSupport stops observing new activations after the first |
+ // one. |
+ surface_manager_->SurfaceCreated(SurfaceInfo( |
+ surface->surface_id(), frame.metadata.device_scale_factor, frame_size)); |
+} |
+ |
+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; |
@@ -267,9 +338,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) { |
- 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 |