forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelegated_frame_host_android.h
265 lines (211 loc) · 10.4 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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
// 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.
// `capture_exact_surface_id` indicates if the `CopyOutputRequest` will be
// issued against a specific surface or not.
void CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& output_size,
base::OnceCallback<void(const SkBitmap&)> callback,
bool capture_exact_surface_id);
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 DidNavigateMainFramePreCommit();
// Called when the page has just entered BFCache.
void DidEnterBackForwardCache();
void SetTopControlsVisibleHeight(float height);
viz::SurfaceId GetFallbackSurfaceIdForTesting() const;
viz::SurfaceId GetCurrentSurfaceIdForTesting() const;
viz::SurfaceId GetPreNavigationSurfaceIdForTesting() const {
return GetPreNavigationSurfaceId();
}
viz::SurfaceId GetFirstSurfaceIdAfterNavigationForTesting() const;
void SetIsFrameSinkIdOwner(bool is_owner);
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. If the old page enters BFCache, this id is used
// to restore `local_surface_id_`.
viz::LocalSurfaceId pre_navigation_local_surface_id_;
// The fallback ID for BFCache restore. It is set when `this` enters the
// BFCache and is cleared when resize-while-hidden (which supplies with a
// latest fallback ID) or after it is used in `EmbedSurface`.
viz::LocalSurfaceId bfcache_fallback_;
// The LocalSurfaceId of the currently embedded surface. If surface sync is
// on, this surface is not necessarily active.
//
// TODO(https://crbug.com/1459238): this value is a copy of what the browser
// wants to embed. The source of truth is stored else where. We should
// consider de-dup this ID.
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_;
// Speculative RenderWidgetHostViews can start with a FrameSinkId owned by the
// currently committed RenderWidgetHostView. Ownership is transferred when the
// navigation is committed. This bit tracks whether this
// DelegatedFrameHostAndroid owns its FrameSinkId.
bool owns_frame_sink_id_ = false;
};
} // namespace ui
#endif // UI_ANDROID_DELEGATED_FRAME_HOST_ANDROID_H_