| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/aura/local/layer_tree_frame_sink_local.h" |
| |
| #include "cc/trees/layer_tree_frame_sink_client.h" |
| #include "components/viz/common/surfaces/surface_info.h" |
| #include "components/viz/host/host_frame_sink_manager.h" |
| #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" |
| #include "ui/aura/client/cursor_client.h" |
| #include "ui/aura/env.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura/window_delegate.h" |
| #include "ui/display/display.h" |
| #include "ui/display/screen.h" |
| |
| namespace aura { |
| |
| LayerTreeFrameSinkLocal::LayerTreeFrameSinkLocal( |
| const viz::FrameSinkId& frame_sink_id, |
| viz::HostFrameSinkManager* host_frame_sink_manager, |
| const std::string& debug_label) |
| : cc::LayerTreeFrameSink(nullptr, nullptr, nullptr, nullptr, nullptr), |
| frame_sink_id_(frame_sink_id), |
| host_frame_sink_manager_(host_frame_sink_manager), |
| weak_factory_(this) { |
| host_frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_, this); |
| #if DCHECK_IS_ON() |
| host_frame_sink_manager_->SetFrameSinkDebugLabel(frame_sink_id_, debug_label); |
| #endif |
| } |
| |
| LayerTreeFrameSinkLocal::~LayerTreeFrameSinkLocal() { |
| host_frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_); |
| } |
| |
| bool LayerTreeFrameSinkLocal::BindToClient( |
| cc::LayerTreeFrameSinkClient* client) { |
| if (!cc::LayerTreeFrameSink::BindToClient(client)) |
| return false; |
| DCHECK(!thread_checker_); |
| thread_checker_ = std::make_unique<base::ThreadChecker>(); |
| |
| support_ = host_frame_sink_manager_->CreateCompositorFrameSinkSupport( |
| this, frame_sink_id_, false /* is_root */, |
| true /* needs_sync_points */); |
| begin_frame_source_ = std::make_unique<viz::ExternalBeginFrameSource>(this); |
| client->SetBeginFrameSource(begin_frame_source_.get()); |
| return true; |
| } |
| |
| void LayerTreeFrameSinkLocal::SetSurfaceChangedCallback( |
| const SurfaceChangedCallback& callback) { |
| DCHECK(!surface_changed_callback_); |
| surface_changed_callback_ = callback; |
| } |
| |
| base::WeakPtr<LayerTreeFrameSinkLocal> LayerTreeFrameSinkLocal::GetWeakPtr() { |
| return weak_factory_.GetWeakPtr(); |
| } |
| |
| void LayerTreeFrameSinkLocal::DetachFromClient() { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| client_->SetBeginFrameSource(nullptr); |
| begin_frame_source_.reset(); |
| support_->EvictCurrentSurface(); |
| support_.reset(); |
| thread_checker_.reset(); |
| cc::LayerTreeFrameSink::DetachFromClient(); |
| } |
| |
| void LayerTreeFrameSinkLocal::SetLocalSurfaceId( |
| const viz::LocalSurfaceId& local_surface_id) { |
| DCHECK(local_surface_id.is_valid()); |
| local_surface_id_ = local_surface_id; |
| } |
| |
| void LayerTreeFrameSinkLocal::SubmitCompositorFrame( |
| viz::CompositorFrame frame) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| DCHECK(frame.metadata.begin_frame_ack.has_damage); |
| DCHECK_LE(viz::BeginFrameArgs::kStartingFrameNumber, |
| frame.metadata.begin_frame_ack.sequence_number); |
| |
| DCHECK(local_surface_id_.is_valid()); |
| |
| bool result = |
| support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)); |
| DCHECK(result); |
| } |
| |
| void LayerTreeFrameSinkLocal::DidNotProduceFrame( |
| const viz::BeginFrameAck& ack) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| DCHECK(!ack.has_damage); |
| DCHECK_LE(viz::BeginFrameArgs::kStartingFrameNumber, ack.sequence_number); |
| support_->DidNotProduceFrame(ack); |
| } |
| |
| void LayerTreeFrameSinkLocal::DidReceiveCompositorFrameAck( |
| const std::vector<viz::ReturnedResource>& resources) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| if (!client_) |
| return; |
| if (!resources.empty()) |
| client_->ReclaimResources(resources); |
| client_->DidReceiveCompositorFrameAck(); |
| } |
| |
| void LayerTreeFrameSinkLocal::DidPresentCompositorFrame( |
| uint32_t presentation_token, |
| base::TimeTicks time, |
| base::TimeDelta refresh, |
| uint32_t flags) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| client_->DidPresentCompositorFrame(presentation_token, time, refresh, flags); |
| } |
| |
| void LayerTreeFrameSinkLocal::DidDiscardCompositorFrame( |
| uint32_t presentation_token) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| client_->DidDiscardCompositorFrame(presentation_token); |
| } |
| |
| void LayerTreeFrameSinkLocal::OnBeginFrame(const viz::BeginFrameArgs& args) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| begin_frame_source_->OnBeginFrame(args); |
| } |
| |
| void LayerTreeFrameSinkLocal::OnBeginFramePausedChanged(bool paused) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| begin_frame_source_->OnSetBeginFrameSourcePaused(paused); |
| } |
| |
| void LayerTreeFrameSinkLocal::ReclaimResources( |
| const std::vector<viz::ReturnedResource>& resources) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| if (!client_) |
| return; |
| client_->ReclaimResources(resources); |
| } |
| |
| void LayerTreeFrameSinkLocal::OnNeedsBeginFrames(bool needs_begin_frames) { |
| DCHECK(thread_checker_); |
| DCHECK(thread_checker_->CalledOnValidThread()); |
| support_->SetNeedsBeginFrame(needs_begin_frames); |
| } |
| |
| void LayerTreeFrameSinkLocal::OnFirstSurfaceActivation( |
| const viz::SurfaceInfo& surface_info) { |
| surface_changed_callback_.Run(surface_info); |
| } |
| |
| void LayerTreeFrameSinkLocal::OnFrameTokenChanged(uint32_t frame_token) { |
| // TODO(yiyix, fsamuel): Implement frame token propagation for |
| // LayerTreeFrameSinkLocal. |
| NOTREACHED(); |
| } |
| |
| } // namespace aura |