blob: da08647964e5ecb662949ccc554df805dfb72d66 [file] [log] [blame]
Avi Drissman3e1a26c2022-09-15 20:26:031// Copyright 2016 The Chromium Authors
khushalsagara693aa72016-08-16 22:18:062// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UI_ANDROID_DELEGATED_FRAME_HOST_ANDROID_H_
6#define UI_ANDROID_DELEGATED_FRAME_HOST_ANDROID_H_
7
Jonathan Ross4ee10062022-12-20 14:39:578#include <vector>
9
Keishi Hattori0e45c022021-11-27 09:25:5210#include "base/memory/raw_ptr.h"
Lei Zhang8f2f80a2022-11-03 18:36:0911#include "base/memory/scoped_refptr.h"
Peter Kasting809cfe72020-08-04 00:56:1312#include "base/numerics/safe_conversions.h"
Jonathan Rossbe6a0702021-02-23 01:01:5613#include "base/time/time.h"
Fady Samueldba483c2018-05-30 04:42:3514#include "cc/layers/deadline_policy.h"
Fady Samuelac325ce2018-06-01 15:23:2715#include "components/viz/client/frame_evictor.h"
Eric Karlb6d3d74d2019-07-17 21:43:4716#include "components/viz/common/frame_sinks/begin_frame_args.h"
danakjf20f4502017-09-26 17:13:3117#include "components/viz/common/frame_sinks/copy_output_request.h"
Daniel Libby58389b72019-06-11 20:03:4318#include "components/viz/common/frame_timing_details_map.h"
Fady Samuel4f7f0fb32017-07-28 15:33:3719#include "components/viz/common/resources/returned_resource.h"
Jonathan Ross4ee10062022-12-20 14:39:5720#include "components/viz/common/surfaces/surface_id.h"
Fady Samuel1a21156e2017-07-13 04:57:2921#include "components/viz/common/surfaces/surface_info.h"
Fady Samuelbac0f1a2017-08-02 15:54:0222#include "components/viz/host/host_frame_sink_client.h"
Jonathan Ross95bab102022-10-14 14:10:2423#include "third_party/blink/public/common/page/content_to_visible_time_reporter.h"
24#include "third_party/blink/public/mojom/widget/record_content_to_visible_time_request.mojom.h"
Peilin Wang1187e4e82025-02-10 08:53:2925#include "ui/android/browser_controls_offset_tag_definitions.h"
khushalsagara693aa72016-08-16 22:18:0626#include "ui/android/ui_android_export.h"
Peilin Wanga1e9e2ea2024-05-14 14:44:5927#include "ui/android/window_android_compositor.h"
khushalsagara693aa72016-08-16 22:18:0628
Bo Liu6ee5d0392023-01-30 20:30:2729namespace cc::slim {
khushalsagara693aa72016-08-16 22:18:0630class SurfaceLayer;
Bo Liu6ee5d0392023-01-30 20:30:2731}
khushalsagara693aa72016-08-16 22:18:0632
kylechara0900162017-07-14 17:35:2533namespace viz {
kylechara0900162017-07-14 17:35:2534class HostFrameSinkManager;
35} // namespace viz
36
khushalsagara693aa72016-08-16 22:18:0637namespace ui {
38class ViewAndroid;
39class WindowAndroidCompositor;
40
41class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
Eric Karlb6d3d74d2019-07-17 21:43:4742 : public viz::HostFrameSinkClient,
Fady Samuelac325ce2018-06-01 15:23:2743 public viz::FrameEvictorClient {
khushalsagara693aa72016-08-16 22:18:0644 public:
Peilin Wanga1e9e2ea2024-05-14 14:44:5945 class Client : public WindowAndroidCompositor::FrameSubmissionObserver {
eseckler8c15fc32016-12-20 20:22:2046 public:
Peilin Wanga1e9e2ea2024-05-14 14:44:5947 ~Client() override {}
Jonathan Rossbe6a0702021-02-23 01:01:5648 virtual void OnFrameTokenChanged(uint32_t frame_token,
49 base::TimeTicks activation_time) = 0;
Saman Sami4580e6322018-10-21 03:46:5950 virtual void WasEvicted() = 0;
Alexander Cooperf11d8fb2021-04-07 01:54:3651 virtual void OnSurfaceIdChanged() = 0;
Jonathan Ross4ee10062022-12-20 14:39:5752 virtual std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction()
53 const = 0;
eseckler8c15fc32016-12-20 20:22:2054 };
khushalsagara693aa72016-08-16 22:18:0655
56 DelegatedFrameHostAndroid(ViewAndroid* view,
kylechara0900162017-07-14 17:35:2557 viz::HostFrameSinkManager* host_frame_sink_manager,
xlai9351829f2017-01-27 18:39:1358 Client* client,
Eric Karlb6d3d74d2019-07-17 21:43:4759 const viz::FrameSinkId& frame_sink_id);
khushalsagara693aa72016-08-16 22:18:0660
Peter Boströmc8c12352021-09-21 23:37:1561 DelegatedFrameHostAndroid(const DelegatedFrameHostAndroid&) = delete;
62 DelegatedFrameHostAndroid& operator=(const DelegatedFrameHostAndroid&) =
63 delete;
64
khushalsagara693aa72016-08-16 22:18:0665 ~DelegatedFrameHostAndroid() override;
66
Bo Liu140aa0c2020-09-14 14:09:5667 static int64_t TimeDeltaToFrames(base::TimeDelta delta) {
68 return base::ClampRound<int64_t>(delta /
69 viz::BeginFrameArgs::DefaultInterval());
70 }
71
Fady Samuel99ec37a2018-07-16 21:43:4772 // Wait up to 5 seconds for the first frame to be produced. Having Android
73 // display a placeholder for a longer period of time is preferable to drawing
74 // nothing, and the first frame can take a while on low-end systems.
75 static constexpr base::TimeDelta FirstFrameTimeout() {
Peter Kastinge5a38ed2021-10-02 03:06:3576 return base::Seconds(5);
Fady Samuel99ec37a2018-07-16 21:43:4777 }
Peter Kasting809cfe72020-08-04 00:56:1378 static int64_t FirstFrameTimeoutFrames() {
Bo Liu140aa0c2020-09-14 14:09:5679 return TimeDeltaToFrames(FirstFrameTimeout());
Fady Samuel99ec37a2018-07-16 21:43:4780 }
81
Jonathan Rossd8f29e2e2021-05-21 15:30:1982 // Wait up to 175 milliseconds for a frame of the correct size to be produced.
83 // Android OS will only wait 200 milliseconds, so we limit this to make sure
84 // that Viz is able to produce the latest frame from the Browser before the OS
85 // stops waiting. Otherwise a rotated version of the previous frame will be
86 // displayed with a large black region where there is no content yet.
Fady Samuel99ec37a2018-07-16 21:43:4787 static constexpr base::TimeDelta ResizeTimeout() {
Peter Kastinge5a38ed2021-10-02 03:06:3588 return base::Milliseconds(175);
Fady Samuel99ec37a2018-07-16 21:43:4789 }
Peter Kasting809cfe72020-08-04 00:56:1390 static int64_t ResizeTimeoutFrames() {
Bo Liu140aa0c2020-09-14 14:09:5691 return TimeDeltaToFrames(ResizeTimeout());
Fady Samuel99ec37a2018-07-16 21:43:4792 }
93
Jonathan Ross61ec65342021-12-14 23:01:4094 void ClearFallbackSurfaceForCommitPending();
akabaf2624f22018-08-21 17:11:0195 // Advances the fallback surface to the first surface after navigation. This
96 // ensures that stale surfaces are not presented to the user for an indefinite
97 // period of time.
98 void ResetFallbackToFirstNavigationSurface();
99
khushalsagara693aa72016-08-16 22:18:06100 bool HasDelegatedContent() const;
101
Bo Liufe8fa982023-05-10 00:51:43102 const cc::slim::SurfaceLayer* content_layer() const {
Bo Liu6ee5d0392023-01-30 20:30:27103 return content_layer_.get();
104 }
Fady Samuelbcac6f02018-07-11 02:02:42105
Fady Samuel0c2f5b82018-07-19 00:33:46106 const viz::FrameSinkId& GetFrameSinkId() const;
khushalsagara693aa72016-08-16 22:18:06107
Yuri Wiitalab9ad27a2017-09-06 19:13:50108 // Should only be called when the host has a content layer. Use this for one-
Piotr Bialecki95d8f622021-07-29 18:58:44109 // off screen capture, not for video. Always provides ResultFormat::RGBA,
110 // ResultDestination::kSystemMemory CopyOutputResults.
William Liu6dcb0eb2023-08-08 17:38:23111 // `capture_exact_surface_id` indicates if the `CopyOutputRequest` will be
112 // issued against a specific surface or not.
Yuri Wiitala419ed0f2018-02-22 23:21:38113 void CopyFromCompositingSurface(
114 const gfx::Rect& src_subrect,
115 const gfx::Size& output_size,
William Liu6dcb0eb2023-08-08 17:38:23116 base::OnceCallback<void(const SkBitmap&)> callback,
Aldo Culquicondoredee2d292025-02-12 18:27:38117 bool capture_exact_surface_id,
Aldo Culquicondoraee41bb2025-05-05 20:03:11118 base::TimeDelta ipc_delay);
Yuri Wiitala419ed0f2018-02-22 23:21:38119 bool CanCopyFromCompositingSurface() const;
khushalsagara693aa72016-08-16 22:18:06120
danakj1120f4c2016-09-15 02:05:32121 void CompositorFrameSinkChanged();
khushalsagara693aa72016-08-16 22:18:06122
ennea487a272016-09-30 19:56:18123 // Called when this DFH is attached/detached from a parent browser compositor
124 // and needs to be attached to the surface hierarchy.
starazaa231112017-02-07 17:53:24125 void AttachToCompositor(WindowAndroidCompositor* compositor);
126 void DetachFromCompositor();
ennea487a272016-09-30 19:56:18127
Fady Samuelac325ce2018-06-01 15:23:27128 bool IsPrimarySurfaceEvicted() const;
129 bool HasSavedFrame() const;
130 void WasHidden();
131 void WasShown(const viz::LocalSurfaceId& local_surface_id,
Vasiliy Telezhnikov03d42b522020-06-29 14:40:59132 const gfx::Size& size_in_pixels,
Jonathan Ross95bab102022-10-14 14:10:24133 bool is_fullscreen,
134 blink::mojom::RecordContentToVisibleTimeRequestPtr
135 content_to_visible_time_request);
Saman Sami1bbd14692018-10-19 22:27:30136 void EmbedSurface(const viz::LocalSurfaceId& new_local_surface_id,
137 const gfx::Size& new_size_in_pixels,
Vasiliy Telezhnikov03d42b522020-06-29 14:40:59138 cc::DeadlinePolicy deadline_policy,
Vasiliy Telezhnikov2bef50f2020-07-10 19:19:31139 bool is_fullscreen);
Eric Karlbaa55ff32018-01-18 00:46:11140
Jonathan Ross95bab102022-10-14 14:10:24141 // Called to request the presentation time for the next frame or cancel any
142 // requests when the RenderWidget's visibility state is not changing. If the
143 // visibility state is changing call WasHidden or WasShown instead.
Mohsen Izadicc482292023-02-01 16:18:57144 void RequestSuccessfulPresentationTimeForNextFrame(
Jonathan Ross95bab102022-10-14 14:10:24145 blink::mojom::RecordContentToVisibleTimeRequestPtr
146 content_to_visible_time_request);
Mohsen Izadicc482292023-02-01 16:18:57147 void CancelSuccessfulPresentationTimeRequest();
Jonathan Ross95bab102022-10-14 14:10:24148
Eric Karlbaa55ff32018-01-18 00:46:11149 // Returns the ID for the current Surface. Returns an invalid ID if no
150 // surface exists (!HasDelegatedContent()).
Fady Samuel120c7e22018-07-20 05:19:28151 viz::SurfaceId SurfaceId() const;
Saman Sami1bbd14692018-10-19 22:27:30152
Saman Samif03a9dba2018-09-24 18:05:07153 bool HasPrimarySurface() const;
Xu Xing9ef5a882018-08-21 00:11:20154 bool HasFallbackSurface() const;
Eric Karlbaa55ff32018-01-18 00:46:11155
Saman Sami26a1fcd2018-04-10 17:12:21156 void TakeFallbackContentFrom(DelegatedFrameHostAndroid* other);
157
Jonathan Ross865a12d2020-12-16 22:33:00158 // Called when navigation has completed, and this DelegatedFrameHost is
159 // visible. A new Surface will have been embedded at this point. If navigation
160 // is done while hidden, this will be called upon becoming visible.
Eric Karldb7eb242018-05-16 17:16:59161 void DidNavigate();
William Liuf88840b2023-07-20 18:27:13162
Jonathan Ross865a12d2020-12-16 22:33:00163 // Navigation to a different page than the current one has begun. This is
164 // called regardless of the visibility of the page. Caches the current
165 // LocalSurfaceId information so that old content can be evicted if
166 // navigation fails to complete.
William Liuf88840b2023-07-20 18:27:13167 void DidNavigateMainFramePreCommit();
168
169 // Called when the page has just entered BFCache.
170 void DidEnterBackForwardCache();
Eric Karldb7eb242018-05-16 17:16:59171
William Liud130bd42025-02-11 15:42:20172 // Called when the page was activated from BFCache.
173 void ActivatedOrEvictedFromBackForwardCache();
174
Vladimir Levin16c09ed2023-04-21 14:23:41175 viz::SurfaceId GetFallbackSurfaceIdForTesting() const;
176
William Liuf88840b2023-07-20 18:27:13177 viz::SurfaceId GetCurrentSurfaceIdForTesting() const;
178
179 viz::SurfaceId GetPreNavigationSurfaceIdForTesting() const {
180 return GetPreNavigationSurfaceId();
181 }
182
William Liu2ad01732023-11-20 21:31:11183 viz::SurfaceId GetFirstSurfaceIdAfterNavigationForTesting() const;
184
William Liud130bd42025-02-11 15:42:20185 viz::SurfaceId GetBFCacheFallbackSurfaceIdForTesting() const;
186
Khushal Sagar402d1c9f2023-11-15 22:21:48187 void SetIsFrameSinkIdOwner(bool is_owner);
188
Peilin Wang1187e4e82025-02-10 08:53:29189 void RegisterOffsetTags(
190 const BrowserControlsOffsetTagDefinitions& tag_definitions);
191 void UnregisterOffsetTags(const cc::BrowserControlsOffsetTags& tags);
Peilin Wang95929bc02024-06-06 17:13:46192
khushalsagara693aa72016-08-16 22:18:06193 private:
kylechar055c2102020-07-13 19:58:15194 // FrameEvictorClient implementation.
Jonathan Ross579e74c12023-02-23 15:45:59195 void EvictDelegatedFrame(
196 const std::vector<viz::SurfaceId>& surface_ids) override;
Eliot Courtneyf760a8212024-04-26 01:35:21197 viz::FrameEvictorClient::EvictIds CollectSurfaceIdsForEviction()
198 const override;
Jonathan Ross579e74c12023-02-23 15:45:59199 viz::SurfaceId GetCurrentSurfaceId() const override;
200 viz::SurfaceId GetPreNavigationSurfaceId() const override;
kylechar055c2102020-07-13 19:58:15201
Fady Samuelbac0f1a2017-08-02 15:54:02202 // viz::HostFrameSinkClient implementation.
Fady Samuel5b7fb8e2017-08-08 16:58:22203 void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
Jonathan Rossbe6a0702021-02-23 01:01:56204 void OnFrameTokenChanged(uint32_t frame_token,
205 base::TimeTicks activation_time) override;
Fady Samuelbac0f1a2017-08-02 15:54:02206
Eric Karl5479bee2018-08-24 23:10:28207 void ProcessCopyOutputRequest(
208 std::unique_ptr<viz::CopyOutputRequest> request);
209
Alexander Cooperf11d8fb2021-04-07 01:54:36210 void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id);
211
Jonathan Ross95bab102022-10-14 14:10:24212 // We cannot guarantee to be attached to `registered_parent_compositor_` when
Mohsen Izadicc482292023-02-01 16:18:57213 // either WasShown or RequestSuccessfulPresentationTimeForNextFrame is called.
214 // In such cases we enqueue the request and attempt again to send it once the
Jonathan Ross95bab102022-10-14 14:10:24215 // compositor has been attached.
Mohsen Izadicc482292023-02-01 16:18:57216 void PostRequestSuccessfulPresentationTimeForNextFrame(
Jonathan Ross95bab102022-10-14 14:10:24217 blink::mojom::RecordContentToVisibleTimeRequestPtr
218 content_to_visible_time_request);
219
Eliot Courtney57bed97e2024-11-15 15:51:38220 void UpdateCaptureKeepAlive();
221 void ReleaseCaptureKeepAlive();
222
Fady Samueld5c26182017-07-12 02:43:33223 const viz::FrameSinkId frame_sink_id_;
fsamuelb6acafa2016-10-04 03:21:52224
Keishi Hattori0e45c022021-11-27 09:25:52225 raw_ptr<ViewAndroid> view_;
khushalsagara693aa72016-08-16 22:18:06226
Keishi Hattori0e45c022021-11-27 09:25:52227 const raw_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
228 raw_ptr<WindowAndroidCompositor> registered_parent_compositor_ = nullptr;
229 raw_ptr<Client> client_;
khushalsagara693aa72016-08-16 22:18:06230
Bo Liu6ee5d0392023-01-30 20:30:27231 scoped_refptr<cc::slim::SurfaceLayer> content_layer_;
khushalsagara693aa72016-08-16 22:18:06232
Eric Karldb7eb242018-05-16 17:16:59233 // Whether we've received a frame from the renderer since navigating.
Fady Samueldba483c2018-05-30 04:42:35234 // Only used when surface synchronization is on.
akabaf2624f22018-08-21 17:11:01235 viz::LocalSurfaceId first_local_surface_id_after_navigation_;
William Liuf88840b2023-07-20 18:27:13236
Jonathan Ross865a12d2020-12-16 22:33:00237 // While navigating we have no active |local_surface_id_|. Track the one from
238 // before a navigation, because if the navigation fails to complete, we will
William Liuf88840b2023-07-20 18:27:13239 // need to evict its surface. If the old page enters BFCache, this id is used
240 // to restore `local_surface_id_`.
Jonathan Ross865a12d2020-12-16 22:33:00241 viz::LocalSurfaceId pre_navigation_local_surface_id_;
Fady Samueldba483c2018-05-30 04:42:35242
William Liuf88840b2023-07-20 18:27:13243 // The fallback ID for BFCache restore. It is set when `this` enters the
244 // BFCache and is cleared when resize-while-hidden (which supplies with a
245 // latest fallback ID) or after it is used in `EmbedSurface`.
246 viz::LocalSurfaceId bfcache_fallback_;
247
Saman Sami1bbd14692018-10-19 22:27:30248 // The LocalSurfaceId of the currently embedded surface. If surface sync is
249 // on, this surface is not necessarily active.
William Liuf88840b2023-07-20 18:27:13250 //
Alison Galec5ea18592024-04-16 16:08:51251 // TODO(crbug.com/40274223): this value is a copy of what the browser
William Liuf88840b2023-07-20 18:27:13252 // wants to embed. The source of truth is stored else where. We should
253 // consider de-dup this ID.
Saman Sami1bbd14692018-10-19 22:27:30254 viz::LocalSurfaceId local_surface_id_;
Eric Karldb7eb242018-05-16 17:16:59255
Fady Samuelac325ce2018-06-01 15:23:27256 // The size of the above surface (updated at the same time).
Saman Sami1bbd14692018-10-19 22:27:30257 gfx::Size surface_size_in_pixels_;
Fady Samuelac325ce2018-06-01 15:23:27258
Jonathan Ross95bab102022-10-14 14:10:24259 // If `registered_parent_compositor_` is not attached when we receive a
260 // request, we save it and attempt again to send it once the compositor has
261 // been attached.
262 blink::mojom::RecordContentToVisibleTimeRequestPtr
263 content_to_visible_time_request_;
264 blink::ContentToVisibleTimeReporter content_to_visible_time_recorder_;
265
Fady Samuelac325ce2018-06-01 15:23:27266 std::unique_ptr<viz::FrameEvictor> frame_evictor_;
Khushal Sagar402d1c9f2023-11-15 22:21:48267
Eliot Courtney57bed97e2024-11-15 15:51:38268 // If the tab is backgrounded (not visible in the UI), then make sure that the
269 // surface is kept alive. This is required for e.g. capture of surfaces during
270 // tab sharing to work. We do this for tabs visible in the UI as well, which
271 // is redundant, but shouldn't hurt anything.
272 ui::WindowAndroidCompositor::ScopedKeepSurfaceAliveCallback
273 capture_keep_alive_callback_;
274
Khushal Sagar402d1c9f2023-11-15 22:21:48275 // Speculative RenderWidgetHostViews can start with a FrameSinkId owned by the
276 // currently committed RenderWidgetHostView. Ownership is transferred when the
277 // navigation is committed. This bit tracks whether this
278 // DelegatedFrameHostAndroid owns its FrameSinkId.
279 bool owns_frame_sink_id_ = false;
khushalsagara693aa72016-08-16 22:18:06280};
281
282} // namespace ui
283
284#endif // UI_ANDROID_DELEGATED_FRAME_HOST_ANDROID_H_