blob: 1f83999c35af38fdf4ea7a95ac19e0bd497e9441 [file]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_LAYER_TREE_VIEW_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_LAYER_TREE_VIEW_H_
#include <stdint.h>
#include "base/containers/circular_deque.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "cc/input/browser_controls_state.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "cc/trees/paint_holding_reason.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/widget/compositing/layer_tree_view_delegate.h"
#include "ui/gfx/ca_layer_result.h"
#include "ui/gfx/geometry/rect.h"
namespace cc {
class AnimationHost;
class LayerTreeFrameSink;
class LayerTreeHost;
class LayerTreeSettings;
class RenderFrameMetadataObserver;
class TaskGraphRunner;
} // namespace cc
namespace blink {
namespace scheduler {
class WidgetScheduler;
} // namespace scheduler
class PLATFORM_EXPORT LayerTreeView
: public cc::LayerTreeHostClient,
public cc::LayerTreeHostSingleThreadClient,
public cc::LayerTreeHostSchedulingClient {
public:
LayerTreeView(LayerTreeViewDelegate* delegate,
scoped_refptr<scheduler::WidgetScheduler> scheduler);
LayerTreeView(const LayerTreeView&) = delete;
LayerTreeView& operator=(const LayerTreeView&) = delete;
~LayerTreeView() override;
// The |main_thread| is the task runner that the compositor will use for the
// main thread (where it is constructed). The |compositor_thread| is the task
// runner for the compositor thread, but is null if the compositor will run in
// single-threaded mode (in tests only).
// The |ukm_recorder_factory| may be null to disable recording (in tests
// only).
void Initialize(const cc::LayerTreeSettings& settings,
scoped_refptr<base::SingleThreadTaskRunner> main_thread,
scoped_refptr<base::SingleThreadTaskRunner> compositor_thread,
cc::TaskGraphRunner* task_graph_runner);
// Drops any references back to the delegate in preparation for being
// destroyed.
void Disconnect();
// Drops any references back to the current delegate and attaches to
// `delegate` if non-null.
void ClearPreviousDelegateAndReattachIfNeeded(
LayerTreeViewDelegate* delegate,
scoped_refptr<scheduler::WidgetScheduler> scheduler);
cc::AnimationHost* animation_host() { return animation_host_.get(); }
void SetVisible(bool visible);
void SetShouldWarmUp();
// cc::LayerTreeHostClient implementation.
// NOTE: LayerTreeView allows re-attaching itself to a different delegate.
// Since the compositor is threaded, we could receive callbacks from the host
// which are tied to content committed by the previous delegate.
//
// Ensure such callbacks have a `source_frame_number` to ensure callbacks
// associated with the previous delegate are safely discarded.
void WillBeginMainFrame() override;
void DidBeginMainFrame() override;
void WillUpdateLayers() override;
void DidUpdateLayers() override;
void BeginMainFrame(const viz::BeginFrameArgs& args) override;
void OnDeferMainFrameUpdatesChanged(bool) override;
void OnDeferCommitsChanged(
bool defer_status,
cc::PaintHoldingReason reason,
std::optional<cc::PaintHoldingCommitTrigger> trigger) override;
void OnCommitRequested() override;
void BeginMainFrameNotExpectedSoon() override;
void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override;
void UpdateLayerTreeHost() override;
void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override;
void UpdateCompositorScrollState(
const cc::CompositorCommitData& commit_data) override;
void RequestNewLayerTreeFrameSink() override;
void DidInitializeLayerTreeFrameSink() override;
void DidFailToInitializeLayerTreeFrameSink() override;
void WillCommit(const cc::CommitState&) override;
void DidCommit(int source_frame_number,
base::TimeTicks commit_start_time,
base::TimeTicks commit_finish_time) override;
void DidCommitAndDrawFrame(int source_frame_number) override;
void DidCompletePageScaleAnimation(int source_frame_number) override;
void DidPresentCompositorFrame(
uint32_t frame_token,
const viz::FrameTimingDetails& frame_timing_details) override;
void RecordStartOfFrameMetrics() override;
void RecordEndOfFrameMetrics(
base::TimeTicks frame_begin_time,
cc::ActiveFrameSequenceTrackers trackers) override;
std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics()
override;
void NotifyThroughputTrackerResults(
cc::CustomTrackerResults results) override;
void DidObserveFirstScrollDelay(
int source_frame_number,
base::TimeDelta first_scroll_delay,
base::TimeTicks first_scroll_timestamp) override;
void RunPaintBenchmark(int repeat_count,
cc::PaintBenchmarkResult& result) override;
std::string GetPausedDebuggerLocalizedMessage() override;
// cc::LayerTreeHostSingleThreadClient implementation.
void DidSubmitCompositorFrame() override;
void DidLoseLayerTreeFrameSink() override;
void ScheduleAnimationForWebTests() override;
// cc::LayerTreeHostSchedulingClient implementation.
void DidRunBeginMainFrame() override;
// Registers a callback that will be run on the first successful presentation
// for `frame_token` or a following frame.
void AddPresentationCallback(
uint32_t frame_token,
base::OnceCallback<void(const viz::FrameTimingDetails&)> callback);
#if BUILDFLAG(IS_APPLE)
void AddCoreAnimationErrorCodeCallback(
uint32_t frame_token,
base::OnceCallback<void(gfx::CALayerResult)> callback);
#endif
cc::LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); }
const cc::LayerTreeHost* layer_tree_host() const {
return layer_tree_host_.get();
}
protected:
friend class RenderViewImplScaleFactorTest;
private:
void SetLayerTreeFrameSink(
std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink,
std::unique_ptr<cc::RenderFrameMetadataObserver>
render_frame_metadata_observer);
template <typename Callback>
void AddCallback(
uint32_t frame_token,
Callback callback,
base::circular_deque<std::pair<uint32_t, std::vector<Callback>>>&
callbacks);
scoped_refptr<scheduler::WidgetScheduler> widget_scheduler_;
const std::unique_ptr<cc::AnimationHost> animation_host_;
// The delegate_ becomes null when Disconnect() is called. After that, the
// class should do nothing in calls from the LayerTreeHost, and just wait to
// be destroyed. It is not expected to be used at all after Disconnect()
// outside of handling/dropping LayerTreeHost client calls.
raw_ptr<LayerTreeViewDelegate> delegate_;
std::unique_ptr<cc::LayerTreeHost> layer_tree_host_;
enum class FrameSinkState {
kNoFrameSink,
kRequestBufferedInvisible,
kRequestPending,
kInitializing,
kInitialized
};
FrameSinkState frame_sink_state_ = FrameSinkState::kNoFrameSink;
base::circular_deque<std::pair<
uint32_t,
std::vector<base::OnceCallback<void(const viz::FrameTimingDetails&)>>>>
presentation_callbacks_;
#if BUILDFLAG(IS_APPLE)
base::circular_deque<std::pair<
uint32_t,
std::vector<base::OnceCallback<void(gfx::CALayerResult error_code)>>>>
core_animation_error_code_callbacks_;
#endif
// Tracks the source frame number for the first main frame when a new
// delegate is bound to this view. This is used to safely ignore redundant
// callbacks which are tied to content produced by the previous delegate.
int first_source_frame_for_current_delegate_ = 0;
base::WeakPtrFactory<LayerTreeView> weak_factory_{this};
base::WeakPtrFactory<LayerTreeView> weak_factory_for_delegate_{this};
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WIDGET_COMPOSITING_LAYER_TREE_VIEW_H_