1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
ash / frame_sink / frame_sink_host.h [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_FRAME_SINK_FRAME_SINK_HOST_H_
#define ASH_FRAME_SINK_FRAME_SINK_HOST_H_
#include <memory>
#include "ash/ash_export.h"
#include "ash/frame_sink/ui_resource_manager.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/presentation_feedback.h"
namespace cc {
class LayerTreeFrameSink;
} // namespace cc
namespace ash {
class FrameSinkHolder;
// Base class for surfaces that render content by creating independent
// compositor frames and submitting them directly to display compositor.
//
// FrameSinkHost encapsulates interactions with the display compositor and
// manages relevant resources. Child classes override CreateCompositorFrame() to
// control compositor frame creation behavior.
//
// Note: The host_window must outlive the FrameSinkHost.
class ASH_EXPORT FrameSinkHost : public aura::WindowObserver {
public:
using PresentationCallback =
base::RepeatingCallback<void(const gfx::PresentationFeedback&)>;
using FrameSinkFactory =
base::RepeatingCallback<std::unique_ptr<cc::LayerTreeFrameSink>()>;
FrameSinkHost();
FrameSinkHost(const FrameSinkHost&) = delete;
FrameSinkHost& operator=(const FrameSinkHost&) = delete;
~FrameSinkHost() override;
aura::Window* host_window() { return host_window_; }
const aura::Window* host_window() const { return host_window_; }
void SetPresentationCallback(PresentationCallback callback);
// Initializes the FrameSinkHost on the host_window.
virtual void Init(aura::Window* host_window);
virtual void InitForTesting(aura::Window* host_window,
FrameSinkFactory frame_sink_factory);
// Updates the surface by submitting a compositor frame. With
// synchronous_draw as true, we send a compositor frame as soon as we call the
// UpdateSurface method otherwise we draw asynchronously where we wait till
// display_compositor requests for a new frame.
// Note: Calling this method turns off the auto updating of the surface if
// enabled.
void UpdateSurface(const gfx::Rect& content_rect,
const gfx::Rect& damage_rect,
bool synchronous_draw);
// Updates the surface by submitting frames asynchronously. Compared to
// `UpdateSurface()`, where we submit a single frame, after calling
// this method, we keep submitting frames asynchronously. It should be used if
// we expect that there are continuous updates within the content_rect.
void AutoUpdateSurface(const gfx::Rect& content_rect,
const gfx::Rect& damage_rect);
// Overridden from aura::WindowObserver
void OnWindowDestroying(aura::Window* window) override;
FrameSinkHolder* frame_sink_holder_for_testing() {
return frame_sink_holder_.get();
}
protected:
// Creates a compositor frame that can be sent to the display compositor.
// `begin_frame_ack` is a token that needs to be attached to the compositor
// frame being created.
// `resource_manager` helps manage resources that can be attached to the
// compositor frame and also give us a pool of reusable resources.
// `auto_update` if true means that we are continuously submitting frames
// asynchronously and should redraw full surface regardless of damage.
// `last_submitted_frame_size` and `last_submitted_frame_dsf`
// can be used to determine if a new surface needs to be identified on the
// `host_window_`.
// Returns nullptr if a compositor frame cannot be created.
virtual std::unique_ptr<viz::CompositorFrame> CreateCompositorFrame(
const viz::BeginFrameAck& begin_frame_ack,
UiResourceManager& resource_manager,
bool auto_update,
const gfx::Size& last_submitted_frame_size,
float last_submitted_frame_dsf) = 0;
// Callback invoked when underlying frame sink holder gets the first begin
// frame from viz. This signifies that the gpu process has been fully
// initialized.
virtual void OnFirstFrameRequested();
const gfx::Rect& GetTotalDamage() const { return total_damage_rect_; }
void UnionDamage(const gfx::Rect& rect) { total_damage_rect_.Union(rect); }
void IntersectDamage(const gfx::Rect& rect) {
total_damage_rect_.Intersect(rect);
}
void ResetDamage() { total_damage_rect_ = gfx::Rect(); }
const gfx::Rect& GetContentRect() const { return content_rect_; }
private:
void InitFrameSinkHolder(
aura::Window* host_window,
std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink);
void SetHostWindow(aura::Window* host_window);
std::unique_ptr<cc::LayerTreeFrameSink> CreateLayerTreeFrameSink();
// Callback invoked when the connection to `LayerTreeFrameSink` is lost. (i.e
// gpu crashed, host_window closes etc)
void OnFrameSinkLost();
// Observation to track the lifetime of `host_window_`.
base::ScopedObservation<aura::Window, aura::WindowObserver>
host_window_observation_{this};
// The window on which LayerTreeFrameSink is created on.
raw_ptr<aura::Window> host_window_ = nullptr;
// The bounds of the content to be displayed in host window coordinates.
gfx::Rect content_rect_;
// The damage rect in host window coordinates.
gfx::Rect total_damage_rect_;
FrameSinkFactory frame_sink_factory_;
// Holds the LayerTreeFrameSink. For proper deletion of in flight
// resources, lifetime of the FrameSinkHolder is extended to either the root
// window of the`host_window` or till we reclaim all the exported resources
// to the display compositor. See `FrameSinkHolder` implementation for
// details. https://crbug.com/765763
std::unique_ptr<FrameSinkHolder> frame_sink_holder_;
base::WeakPtrFactory<FrameSinkHost> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_FRAME_SINK_FRAME_SINK_HOST_H_