forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelegated_frame_host_android.h
231 lines (186 loc) · 9.03 KB
/
delegated_frame_host_android.h
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_ANDROID_DELEGATED_FRAME_HOST_ANDROID_H_
#define UI_ANDROID_DELEGATED_FRAME_HOST_ANDROID_H_
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "cc/layers/deadline_policy.h"
#include "components/viz/client/frame_evictor.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_timing_details_map.h"
#include "components/viz/common/resources/returned_resource.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "components/viz/host/host_frame_sink_client.h"
#include "third_party/blink/public/common/page/content_to_visible_time_reporter.h"
#include "third_party/blink/public/mojom/widget/record_content_to_visible_time_request.mojom.h"
#include "ui/android/ui_android_export.h"
namespace cc::slim {
class SurfaceLayer;
}
namespace viz {
class HostFrameSinkManager;
} // namespace viz
namespace ui {
class ViewAndroid;
class WindowAndroidCompositor;
class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
: public viz::HostFrameSinkClient,
public viz::FrameEvictorClient {
public:
class Client {
public:
virtual ~Client() {}
virtual void OnFrameTokenChanged(uint32_t frame_token,
base::TimeTicks activation_time) = 0;
virtual void WasEvicted() = 0;
virtual void OnSurfaceIdChanged() = 0;
virtual std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction()
const = 0;
};
DelegatedFrameHostAndroid(ViewAndroid* view,
viz::HostFrameSinkManager* host_frame_sink_manager,
Client* client,
const viz::FrameSinkId& frame_sink_id);
DelegatedFrameHostAndroid(const DelegatedFrameHostAndroid&) = delete;
DelegatedFrameHostAndroid& operator=(const DelegatedFrameHostAndroid&) =
delete;
~DelegatedFrameHostAndroid() override;
static int64_t TimeDeltaToFrames(base::TimeDelta delta) {
return base::ClampRound<int64_t>(delta /
viz::BeginFrameArgs::DefaultInterval());
}
// Wait up to 5 seconds for the first frame to be produced. Having Android
// display a placeholder for a longer period of time is preferable to drawing
// nothing, and the first frame can take a while on low-end systems.
static constexpr base::TimeDelta FirstFrameTimeout() {
return base::Seconds(5);
}
static int64_t FirstFrameTimeoutFrames() {
return TimeDeltaToFrames(FirstFrameTimeout());
}
// Wait up to 175 milliseconds for a frame of the correct size to be produced.
// Android OS will only wait 200 milliseconds, so we limit this to make sure
// that Viz is able to produce the latest frame from the Browser before the OS
// stops waiting. Otherwise a rotated version of the previous frame will be
// displayed with a large black region where there is no content yet.
static constexpr base::TimeDelta ResizeTimeout() {
return base::Milliseconds(175);
}
static int64_t ResizeTimeoutFrames() {
return TimeDeltaToFrames(ResizeTimeout());
}
void ClearFallbackSurfaceForCommitPending();
// Advances the fallback surface to the first surface after navigation. This
// ensures that stale surfaces are not presented to the user for an indefinite
// period of time.
void ResetFallbackToFirstNavigationSurface();
bool HasDelegatedContent() const;
const cc::slim::SurfaceLayer* content_layer() const {
return content_layer_.get();
}
const viz::FrameSinkId& GetFrameSinkId() const;
// Should only be called when the host has a content layer. Use this for one-
// off screen capture, not for video. Always provides ResultFormat::RGBA,
// ResultDestination::kSystemMemory CopyOutputResults.
void CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& output_size,
base::OnceCallback<void(const SkBitmap&)> callback);
bool CanCopyFromCompositingSurface() const;
void CompositorFrameSinkChanged();
// Called when this DFH is attached/detached from a parent browser compositor
// and needs to be attached to the surface hierarchy.
void AttachToCompositor(WindowAndroidCompositor* compositor);
void DetachFromCompositor();
bool IsPrimarySurfaceEvicted() const;
bool HasSavedFrame() const;
void WasHidden();
void WasShown(const viz::LocalSurfaceId& local_surface_id,
const gfx::Size& size_in_pixels,
bool is_fullscreen,
blink::mojom::RecordContentToVisibleTimeRequestPtr
content_to_visible_time_request);
void EmbedSurface(const viz::LocalSurfaceId& new_local_surface_id,
const gfx::Size& new_size_in_pixels,
cc::DeadlinePolicy deadline_policy,
bool is_fullscreen);
// Called to request the presentation time for the next frame or cancel any
// requests when the RenderWidget's visibility state is not changing. If the
// visibility state is changing call WasHidden or WasShown instead.
void RequestSuccessfulPresentationTimeForNextFrame(
blink::mojom::RecordContentToVisibleTimeRequestPtr
content_to_visible_time_request);
void CancelSuccessfulPresentationTimeRequest();
// Returns the ID for the current Surface. Returns an invalid ID if no
// surface exists (!HasDelegatedContent()).
viz::SurfaceId SurfaceId() const;
bool HasPrimarySurface() const;
bool HasFallbackSurface() const;
void TakeFallbackContentFrom(DelegatedFrameHostAndroid* other);
// Called when navigation has completed, and this DelegatedFrameHost is
// visible. A new Surface will have been embedded at this point. If navigation
// is done while hidden, this will be called upon becoming visible.
void DidNavigate();
// Navigation to a different page than the current one has begun. This is
// called regardless of the visibility of the page. Caches the current
// LocalSurfaceId information so that old content can be evicted if
// navigation fails to complete.
void OnNavigateToNewPage();
void SetTopControlsVisibleHeight(float height);
viz::SurfaceId GetFallbackSurfaceIdForTesting() const;
private:
// FrameEvictorClient implementation.
void EvictDelegatedFrame(
const std::vector<viz::SurfaceId>& surface_ids) override;
std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() const override;
viz::SurfaceId GetCurrentSurfaceId() const override;
viz::SurfaceId GetPreNavigationSurfaceId() const override;
// viz::HostFrameSinkClient implementation.
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnFrameTokenChanged(uint32_t frame_token,
base::TimeTicks activation_time) override;
void ProcessCopyOutputRequest(
std::unique_ptr<viz::CopyOutputRequest> request);
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id);
// We cannot guarantee to be attached to `registered_parent_compositor_` when
// either WasShown or RequestSuccessfulPresentationTimeForNextFrame is called.
// In such cases we enqueue the request and attempt again to send it once the
// compositor has been attached.
void PostRequestSuccessfulPresentationTimeForNextFrame(
blink::mojom::RecordContentToVisibleTimeRequestPtr
content_to_visible_time_request);
const viz::FrameSinkId frame_sink_id_;
raw_ptr<ViewAndroid> view_;
const raw_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
raw_ptr<WindowAndroidCompositor> registered_parent_compositor_ = nullptr;
raw_ptr<Client> client_;
float top_controls_visible_height_ = 0.f;
scoped_refptr<cc::slim::SurfaceLayer> content_layer_;
// Whether we've received a frame from the renderer since navigating.
// Only used when surface synchronization is on.
viz::LocalSurfaceId first_local_surface_id_after_navigation_;
// While navigating we have no active |local_surface_id_|. Track the one from
// before a navigation, because if the navigation fails to complete, we will
// need to evict its surface.
viz::LocalSurfaceId pre_navigation_local_surface_id_;
// The LocalSurfaceId of the currently embedded surface. If surface sync is
// on, this surface is not necessarily active.
viz::LocalSurfaceId local_surface_id_;
// The size of the above surface (updated at the same time).
gfx::Size surface_size_in_pixels_;
// If `registered_parent_compositor_` is not attached when we receive a
// request, we save it and attempt again to send it once the compositor has
// been attached.
blink::mojom::RecordContentToVisibleTimeRequestPtr
content_to_visible_time_request_;
blink::ContentToVisibleTimeReporter content_to_visible_time_recorder_;
std::unique_ptr<viz::FrameEvictor> frame_evictor_;
};
} // namespace ui
#endif // UI_ANDROID_DELEGATED_FRAME_HOST_ANDROID_H_