Chromium Code Reviews| Index: blimp/client/core/compositor/blimp_compositor.cc |
| diff --git a/blimp/client/core/compositor/blimp_compositor.cc b/blimp/client/core/compositor/blimp_compositor.cc |
| index 2866c44682eebb89be95e2cab08c6f1c05543d3c..5aa7537df2ec228aae7207f0b732947f450267d4 100644 |
| --- a/blimp/client/core/compositor/blimp_compositor.cc |
| +++ b/blimp/client/core/compositor/blimp_compositor.cc |
| @@ -60,6 +60,62 @@ void RequireCallback(cc::SurfaceManager* manager, |
| } // namespace |
| +class BlimpCompositor::FrameTrackingSwapPromise : public cc::SwapPromise { |
| + public: |
| + FrameTrackingSwapPromise( |
| + std::unique_ptr<cc::CopyOutputRequest> copy_request, |
| + base::WeakPtr<BlimpCompositor> compositor, |
| + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) |
| + : copy_request_(std::move(copy_request)), |
| + compositor_weak_ptr_(compositor), |
| + main_task_runner_(std::move(main_task_runner)) {} |
| + ~FrameTrackingSwapPromise() override = default; |
| + |
| + // cc::SwapPromise implementation. |
| + void DidActivate() override {} |
| + void DidSwap(cc::CompositorFrameMetadata* metadata) override { |
| + // DidSwap is called right before the CompositorFrame is submitted to the |
| + // CompositorFrameSink, so we make sure to delay the copy request till that |
| + // frame is submitted. |
| + main_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&BlimpCompositor::MakeCopyRequestOnNextSwap, |
| + compositor_weak_ptr_, base::Passed(©_request_))); |
| + } |
| + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override { |
| + switch (reason) { |
| + case DidNotSwapReason::SWAP_FAILS: |
| + // The swap will fail if there is no frame damage, we can queue the |
| + // request right away. |
| + main_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&BlimpCompositor::RequestCopyOfOutput, |
| + compositor_weak_ptr_, |
| + base::Passed(©_request_), false)); |
| + break; |
| + case DidNotSwapReason::COMMIT_FAILS: |
| + // The commit fails when the host is going away. |
| + break; |
| + case DidNotSwapReason::COMMIT_NO_UPDATE: |
| + main_task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&BlimpCompositor::RequestCopyOfOutput, |
| + compositor_weak_ptr_, |
| + base::Passed(©_request_), false)); |
| + break; |
| + case DidNotSwapReason::ACTIVATION_FAILS: |
| + // Failure to activate the pending tree implies either the host in going |
| + // away or the FrameSink was lost. |
| + break; |
| + } |
| + return DidNotSwapAction::BREAK_PROMISE; |
| + } |
| + int64_t TraceId() const override { return 0; } |
| + |
| + private: |
| + std::unique_ptr<cc::CopyOutputRequest> copy_request_; |
| + base::WeakPtr<BlimpCompositor> compositor_weak_ptr_; |
| + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
| +}; |
| + |
| BlimpCompositor::BlimpCompositor( |
| BlimpCompositorDependencies* compositor_dependencies, |
| BlimpCompositorClient* client, |
| @@ -99,25 +155,50 @@ BlimpCompositor::~BlimpCompositor() { |
| DestroyLayerTreeHost(); |
| GetEmbedderDeps()->GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_); |
| - |
| - CheckPendingCommitCounts(true /* flush */); |
| } |
| void BlimpCompositor::SetVisible(bool visible) { |
| host_->SetVisible(visible); |
| +} |
| + |
| +void BlimpCompositor::RequestCopyOfOutput( |
| + std::unique_ptr<cc::CopyOutputRequest> copy_request, |
| + bool flush_pending_update) { |
| + // If we don't have a FrameSink, fail right away. |
| + if (!surface_factory_) |
| + return; |
| + |
| + if (!use_threaded_layer_tree_host_) { |
| + RequestCopyOfOutputDeprecated(std::move(copy_request)); |
| + return; |
| + } |
| - if (!visible) |
| - CheckPendingCommitCounts(true /* flush */); |
| + if (flush_pending_update) { |
| + // Always request a commit when queuing the promise to make sure that any |
| + // frames pending draws are cleared from the pipeline. |
| + host_->QueueSwapPromise(base::MakeUnique<FrameTrackingSwapPromise>( |
| + std::move(copy_request), weak_ptr_factory_.GetWeakPtr(), |
| + base::ThreadTaskRunnerHandle::Get())); |
| + host_->SetNeedsCommit(); |
| + } else if (!local_frame_id_.is_null()) { |
| + // Make a copy request for the surface directly. |
| + surface_factory_->RequestCopyOfSurface(local_frame_id_, |
| + std::move(copy_request)); |
| + } |
| } |
| -void BlimpCompositor::NotifyWhenDonePendingCommits(base::Closure callback) { |
| +void BlimpCompositor::RequestCopyOfOutputDeprecated( |
| + std::unique_ptr<cc::CopyOutputRequest> copy_request) { |
| + DCHECK(!use_threaded_layer_tree_host_); |
| + |
| if (outstanding_commits_ == 0) { |
| - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); |
| + surface_factory_->RequestCopyOfSurface(local_frame_id_, |
| + std::move(copy_request)); |
| return; |
| } |
| pending_commit_trackers_.push_back( |
| - std::make_pair(outstanding_commits_, callback)); |
| + std::make_pair(outstanding_commits_, std::move(copy_request))); |
| } |
| void BlimpCompositor::UpdateLayerTreeHost() { |
| @@ -147,12 +228,23 @@ void BlimpCompositor::DidInitializeCompositorFrameSink() { |
| } |
| void BlimpCompositor::DidCommitAndDrawFrame() { |
| - BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); |
| + if (use_threaded_layer_tree_host_) |
|
aelias_OOO_until_Jul13
2016/11/02 07:02:10
For my edification, what is !use_threaded_layer_tr
Khushal
2016/11/02 07:24:21
Right now our split point in the pipeline is right
|
| + return; |
| DCHECK_GT(outstanding_commits_, 0U); |
| outstanding_commits_--; |
| - CheckPendingCommitCounts(false /* flush */); |
| + for (auto it = pending_commit_trackers_.begin(); |
| + it != pending_commit_trackers_.end();) { |
| + if (--it->first == 0) { |
| + if (surface_factory_) |
| + surface_factory_->RequestCopyOfSurface(local_frame_id_, |
| + std::move(it->second)); |
| + it = pending_commit_trackers_.erase(it); |
| + } else { |
| + ++it; |
| + } |
| + } |
| } |
| void BlimpCompositor::SetProtoReceiver(ProtoReceiver* receiver) { |
| @@ -181,8 +273,8 @@ void BlimpCompositor::OnCompositorMessageReceived( |
| UMA_HISTOGRAM_MEMORY_KB("Blimp.Compositor.CommitSizeKb", |
| (float)message->ByteSize() / 1024); |
| + BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); |
| pending_frame_update_ = std::move(message); |
| - outstanding_commits_++; |
| host_->SetNeedsAnimate(); |
| } |
| @@ -196,6 +288,7 @@ void BlimpCompositor::HandleCompositorMessageToImpl( |
| if (to_impl_proto.message_type() == |
| cc::proto::CompositorMessageToImpl::START_COMMIT) { |
| + BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); |
| outstanding_commits_++; |
| } |
| @@ -293,6 +386,12 @@ void BlimpCompositor::SubmitCompositorFrame(cc::CompositorFrame frame) { |
| local_frame_id_, std::move(frame), |
| base::Bind(&BlimpCompositor::SubmitCompositorFrameAck, |
| weak_ptr_factory_.GetWeakPtr())); |
| + |
| + for (auto& copy_request : copy_requests_for_next_swap_) { |
| + surface_factory_->RequestCopyOfSurface(local_frame_id_, |
| + std::move(copy_request)); |
| + } |
| + copy_requests_for_next_swap_.clear(); |
| } |
| void BlimpCompositor::SubmitCompositorFrameAck() { |
| @@ -303,6 +402,11 @@ void BlimpCompositor::SubmitCompositorFrameAck() { |
| proxy_client_)); |
| } |
| +void BlimpCompositor::MakeCopyRequestOnNextSwap( |
| + std::unique_ptr<cc::CopyOutputRequest> copy_request) { |
| + copy_requests_for_next_swap_.push_back(std::move(copy_request)); |
| +} |
| + |
| void BlimpCompositor::UnbindProxyClient() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| DCHECK(surface_factory_); |
| @@ -357,7 +461,6 @@ void BlimpCompositor::DestroyDelegatedContent() { |
| void BlimpCompositor::CreateLayerTreeHost() { |
| DCHECK(!host_); |
| - VLOG(1) << "Creating LayerTreeHost."; |
| // Create the LayerTreeHost |
| cc::LayerTreeHostInProcess::InitParams params; |
| @@ -391,7 +494,6 @@ void BlimpCompositor::CreateLayerTreeHost() { |
| void BlimpCompositor::DestroyLayerTreeHost() { |
| DCHECK(host_); |
| - VLOG(1) << "Destroying LayerTreeHost."; |
| // Tear down the output surface connection with the old LayerTreeHost |
| // instance. |
| @@ -409,17 +511,5 @@ void BlimpCompositor::DestroyLayerTreeHost() { |
| DCHECK(!remote_proto_channel_receiver_); |
| } |
| -void BlimpCompositor::CheckPendingCommitCounts(bool flush) { |
| - for (auto it = pending_commit_trackers_.begin(); |
| - it != pending_commit_trackers_.end();) { |
| - if (flush || --it->first == 0) { |
| - it->second.Run(); |
| - it = pending_commit_trackers_.erase(it); |
| - } else { |
| - ++it; |
| - } |
| - } |
| -} |
| - |
| } // namespace client |
| } // namespace blimp |