blob: 018af16012a9339b6867c0bd1ab05ae2914a1da2 [file] [log] [blame]
// Copyright 2014 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 "cc/layers/surface_layer.h"
#include <stdint.h>
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "cc/layers/surface_layer_impl.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/swap_promise.h"
#include "cc/trees/swap_promise_manager.h"
#include "cc/trees/task_runner_provider.h"
#include "components/viz/common/surfaces/surface_sequence_generator.h"
namespace cc {
class SatisfySwapPromise : public SwapPromise {
public:
SatisfySwapPromise(
base::Closure reference_returner,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
: reference_returner_(reference_returner),
main_task_runner_(std::move(main_task_runner)) {}
~SatisfySwapPromise() override = default;
private:
void DidActivate() override {}
void WillSwap(viz::CompositorFrameMetadata* compositor_frame_metadata,
RenderFrameMetadata* render_frame_metadata) override {}
void DidSwap() override {
main_task_runner_->PostTask(FROM_HERE, reference_returner_);
}
DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
main_task_runner_->PostTask(FROM_HERE, reference_returner_);
return DidNotSwapAction::BREAK_PROMISE;
}
int64_t TraceId() const override { return 0; }
base::Closure reference_returner_;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
DISALLOW_COPY_AND_ASSIGN(SatisfySwapPromise);
};
scoped_refptr<SurfaceLayer> SurfaceLayer::Create(
scoped_refptr<viz::SurfaceReferenceFactory> ref_factory) {
return base::WrapRefCounted(new SurfaceLayer(std::move(ref_factory)));
}
SurfaceLayer::SurfaceLayer(
scoped_refptr<viz::SurfaceReferenceFactory> ref_factory)
: ref_factory_(std::move(ref_factory)) {}
SurfaceLayer::~SurfaceLayer() {
DCHECK(!layer_tree_host());
}
void SurfaceLayer::SetPrimarySurfaceId(
const viz::SurfaceId& surface_id,
base::Optional<uint32_t> deadline_in_frames) {
if (primary_surface_id_ == surface_id &&
deadline_in_frames_ == deadline_in_frames) {
return;
}
primary_surface_id_ = surface_id;
deadline_in_frames_ = deadline_in_frames;
UpdateDrawsContent(HasDrawableContent());
SetNeedsCommit();
}
void SurfaceLayer::SetFallbackSurfaceId(const viz::SurfaceId& surface_id) {
if (fallback_surface_id_ == surface_id)
return;
RemoveReference(std::move(fallback_reference_returner_));
if (layer_tree_host())
layer_tree_host()->RemoveSurfaceLayerId(fallback_surface_id_);
fallback_surface_id_ = surface_id;
if (layer_tree_host() && fallback_surface_id_.is_valid()) {
fallback_reference_returner_ =
ref_factory_->CreateReference(layer_tree_host(), fallback_surface_id_);
layer_tree_host()->AddSurfaceLayerId(fallback_surface_id_);
}
SetNeedsCommit();
}
void SurfaceLayer::SetStretchContentToFillBounds(
bool stretch_content_to_fill_bounds) {
if (stretch_content_to_fill_bounds_ == stretch_content_to_fill_bounds)
return;
stretch_content_to_fill_bounds_ = stretch_content_to_fill_bounds;
SetNeedsPushProperties();
}
std::unique_ptr<LayerImpl> SurfaceLayer::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
return SurfaceLayerImpl::Create(tree_impl, id());
}
bool SurfaceLayer::HasDrawableContent() const {
return primary_surface_id_.is_valid() && Layer::HasDrawableContent();
}
void SurfaceLayer::SetLayerTreeHost(LayerTreeHost* host) {
if (layer_tree_host() == host) {
return;
}
if (layer_tree_host() && fallback_surface_id_.is_valid())
layer_tree_host()->RemoveSurfaceLayerId(fallback_surface_id_);
RemoveReference(std::move(fallback_reference_returner_));
Layer::SetLayerTreeHost(host);
if (layer_tree_host() && fallback_surface_id_.is_valid()) {
fallback_reference_returner_ =
ref_factory_->CreateReference(layer_tree_host(), fallback_surface_id_);
layer_tree_host()->AddSurfaceLayerId(fallback_surface_id_);
}
}
void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) {
Layer::PushPropertiesTo(layer);
TRACE_EVENT0("cc", "SurfaceLayer::PushPropertiesTo");
SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
layer_impl->SetPrimarySurfaceId(primary_surface_id_,
std::move(deadline_in_frames_));
deadline_in_frames_.reset();
layer_impl->SetFallbackSurfaceId(fallback_surface_id_);
layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_);
}
void SurfaceLayer::RemoveReference(base::Closure reference_returner) {
if (!reference_returner)
return;
auto swap_promise = std::make_unique<SatisfySwapPromise>(
std::move(reference_returner),
layer_tree_host()->GetTaskRunnerProvider()->MainThreadTaskRunner());
layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
std::move(swap_promise));
}
} // namespace cc