// 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 #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/output/swap_promise.h" #include "cc/surfaces/surface_sequence_generator.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/swap_promise_manager.h" #include "cc/trees/task_runner_provider.h" namespace cc { class SatisfySwapPromise : public SwapPromise { public: SatisfySwapPromise( base::Closure reference_returner, scoped_refptr main_task_runner) : reference_returner_(reference_returner), main_task_runner_(std::move(main_task_runner)) {} ~SatisfySwapPromise() override {} private: void DidActivate() override {} void WillSwap(CompositorFrameMetadata* 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 main_task_runner_; DISALLOW_COPY_AND_ASSIGN(SatisfySwapPromise); }; scoped_refptr SurfaceLayer::Create( scoped_refptr ref_factory) { return make_scoped_refptr(new SurfaceLayer(std::move(ref_factory))); } SurfaceLayer::SurfaceLayer(scoped_refptr ref_factory) : ref_factory_(std::move(ref_factory)) {} SurfaceLayer::~SurfaceLayer() { DCHECK(!layer_tree_host()); } void SurfaceLayer::SetPrimarySurfaceInfo(const SurfaceInfo& surface_info) { RemoveReference(std::move(primary_reference_returner_)); primary_surface_info_ = surface_info; if (layer_tree_host()) { primary_reference_returner_ = ref_factory_->CreateReference( layer_tree_host(), primary_surface_info_.id()); } UpdateDrawsContent(HasDrawableContent()); SetNeedsCommit(); } void SurfaceLayer::SetFallbackSurfaceInfo(const SurfaceInfo& surface_info) { RemoveReference(std::move(fallback_reference_returner_)); fallback_surface_info_ = surface_info; if (layer_tree_host()) { fallback_reference_returner_ = ref_factory_->CreateReference( layer_tree_host(), fallback_surface_info_.id()); } SetNeedsCommit(); } void SurfaceLayer::SetStretchContentToFillBounds( bool stretch_content_to_fill_bounds) { stretch_content_to_fill_bounds_ = stretch_content_to_fill_bounds; SetNeedsPushProperties(); } std::unique_ptr SurfaceLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return SurfaceLayerImpl::Create(tree_impl, id()); } bool SurfaceLayer::HasDrawableContent() const { return primary_surface_info_.is_valid() && Layer::HasDrawableContent(); } void SurfaceLayer::SetLayerTreeHost(LayerTreeHost* host) { if (layer_tree_host() == host) { Layer::SetLayerTreeHost(host); return; } RemoveReference(std::move(primary_reference_returner_)); RemoveReference(std::move(fallback_reference_returner_)); Layer::SetLayerTreeHost(host); if (layer_tree_host()) { if (primary_surface_info_.is_valid()) { primary_reference_returner_ = ref_factory_->CreateReference( layer_tree_host(), primary_surface_info_.id()); } if (fallback_surface_info_.is_valid()) { fallback_reference_returner_ = ref_factory_->CreateReference( layer_tree_host(), fallback_surface_info_.id()); } } } void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) { Layer::PushPropertiesTo(layer); TRACE_EVENT0("cc", "SurfaceLayer::PushPropertiesTo"); SurfaceLayerImpl* layer_impl = static_cast(layer); layer_impl->SetPrimarySurfaceInfo(primary_surface_info_); layer_impl->SetFallbackSurfaceInfo(fallback_surface_info_); layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_); } void SurfaceLayer::RemoveReference(base::Closure reference_returner) { if (!reference_returner) return; auto swap_promise = base::MakeUnique( std::move(reference_returner), layer_tree_host()->GetTaskRunnerProvider()->MainThreadTaskRunner()); layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise( std::move(swap_promise)); } } // namespace cc