blob: 954176f0fcf52e268b5bd5e7d8670e6cd1bffbe9 [file] [log] [blame]
// 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