1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_RENDERER_HOST_DELEGATED_FRAME_HOST_H_ 6 #define CONTENT_BROWSER_RENDERER_HOST_DELEGATED_FRAME_HOST_H_ 7 8 #include <stdint.h> 9 10 #include <vector> 11 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/time/time.h" 15 #include "components/viz/client/frame_evictor.h" 16 #include "components/viz/common/frame_sinks/begin_frame_args.h" 17 #include "components/viz/common/frame_sinks/begin_frame_source.h" 18 #include "components/viz/common/frame_timing_details_map.h" 19 #include "components/viz/host/hit_test/hit_test_query.h" 20 #include "components/viz/host/host_frame_sink_client.h" 21 #include "components/viz/host/host_frame_sink_manager.h" 22 #include "content/browser/renderer_host/dip_util.h" 23 #include "content/common/content_export.h" 24 #include "content/common/content_to_visible_time_reporter.h" 25 #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" 26 #include "services/viz/public/mojom/hit_test/hit_test_region_list.mojom.h" 27 #include "ui/compositor/compositor.h" 28 #include "ui/compositor/compositor_observer.h" 29 #include "ui/compositor/layer.h" 30 #include "ui/events/event.h" 31 #include "ui/gfx/geometry/rect_conversions.h" 32 33 namespace content { 34 35 class DelegatedFrameHost; 36 37 // The DelegatedFrameHostClient is the interface from the DelegatedFrameHost, 38 // which manages delegated frames, and the ui::Compositor being used to 39 // display them. 40 class CONTENT_EXPORT DelegatedFrameHostClient { 41 public: ~DelegatedFrameHostClient()42 virtual ~DelegatedFrameHostClient() {} 43 44 virtual ui::Layer* DelegatedFrameHostGetLayer() const = 0; 45 virtual bool DelegatedFrameHostIsVisible() const = 0; 46 // Returns the color that the resize gutters should be drawn with. 47 virtual SkColor DelegatedFrameHostGetGutterColor() const = 0; 48 virtual void OnFrameTokenChanged(uint32_t frame_token) = 0; 49 virtual float GetDeviceScaleFactor() const = 0; 50 virtual void InvalidateLocalSurfaceIdOnEviction() = 0; 51 virtual std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() = 0; 52 virtual bool ShouldShowStaleContentOnEviction() = 0; 53 }; 54 55 // The DelegatedFrameHost is used to host all of the RenderWidgetHostView state 56 // and functionality that is associated with delegated frames being sent from 57 // the RenderWidget. The DelegatedFrameHost will push these changes through to 58 // the ui::Compositor associated with its DelegatedFrameHostClient. 59 class CONTENT_EXPORT DelegatedFrameHost 60 : public ui::CompositorObserver, 61 public viz::FrameEvictorClient, 62 public viz::HostFrameSinkClient { 63 public: 64 enum class FrameEvictionState { 65 kNotStarted = 0, // Frame eviction is ready. 66 kPendingEvictionRequests // Frame eviction is paused with pending requests. 67 }; 68 69 class Observer { 70 public: 71 virtual void OnFrameEvictionStateChanged(FrameEvictionState new_state) = 0; 72 73 protected: 74 virtual ~Observer() = default; 75 }; 76 77 // |should_register_frame_sink_id| flag indicates whether DelegatedFrameHost 78 // is responsible for registering the associated FrameSinkId with the 79 // compositor or not. This is set only on non-aura platforms, since aura is 80 // responsible for doing the appropriate [un]registration. 81 DelegatedFrameHost(const viz::FrameSinkId& frame_sink_id, 82 DelegatedFrameHostClient* client, 83 bool should_register_frame_sink_id); 84 ~DelegatedFrameHost() override; 85 86 void AddObserverForTesting(Observer* observer); 87 void RemoveObserverForTesting(Observer* observer); 88 89 // ui::CompositorObserver implementation. 90 void OnCompositingShuttingDown(ui::Compositor* compositor) override; 91 92 void ResetFallbackToFirstNavigationSurface(); 93 94 // viz::HostFrameSinkClient implementation. 95 void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; 96 void OnFrameTokenChanged(uint32_t frame_token) override; 97 98 // Public interface exposed to RenderWidgetHostView. 99 100 // kOccluded means the native window for the host was 101 // occluded/hidden, kOther is for other causes, e.g., a tab became a 102 // background tab. 103 enum class HiddenCause { kOccluded, kOther }; 104 105 void WasHidden(HiddenCause cause); 106 107 // TODO(ccameron): Include device scale factor here. 108 void WasShown(const viz::LocalSurfaceId& local_surface_id, 109 const gfx::Size& dip_size, 110 const base::Optional<RecordContentToVisibleTimeRequest>& 111 record_tab_switch_time_request); 112 void EmbedSurface(const viz::LocalSurfaceId& local_surface_id, 113 const gfx::Size& dip_size, 114 cc::DeadlinePolicy deadline_policy); 115 bool HasSavedFrame() const; 116 void AttachToCompositor(ui::Compositor* compositor); 117 void DetachFromCompositor(); 118 119 // Copies |src_subrect| from the compositing surface into a bitmap (first 120 // overload) or texture (second overload). |output_size| specifies the size of 121 // the output bitmap or texture. 122 // Note: |src_subrect| is specified in DIP dimensions while |output_size| 123 // expects pixels. If |src_subrect| is empty, the entire surface area is 124 // copied. 125 void CopyFromCompositingSurface( 126 const gfx::Rect& src_subrect, 127 const gfx::Size& output_size, 128 base::OnceCallback<void(const SkBitmap&)> callback); 129 void CopyFromCompositingSurfaceAsTexture( 130 const gfx::Rect& src_subrect, 131 const gfx::Size& output_size, 132 viz::CopyOutputRequest::CopyOutputRequestCallback callback); 133 134 bool CanCopyFromCompositingSurface() const; frame_sink_id()135 const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; } 136 137 // Returns the surface id for the most recently embedded surface. GetCurrentSurfaceId()138 viz::SurfaceId GetCurrentSurfaceId() const { 139 return viz::SurfaceId(frame_sink_id_, local_surface_id_); 140 } 141 142 bool HasPrimarySurface() const; 143 bool HasFallbackSurface() const; 144 OnCompositingDidCommitForTesting(ui::Compositor * compositor)145 void OnCompositingDidCommitForTesting(ui::Compositor* compositor) { 146 OnCompositingDidCommit(compositor); 147 } 148 CurrentFrameSizeInDipForTesting()149 gfx::Size CurrentFrameSizeInDipForTesting() const { 150 return current_frame_size_in_dip_; 151 } 152 153 void DidNavigate(); 154 155 void WindowTitleChanged(const std::string& title); 156 157 // If our SurfaceLayer doesn't have a fallback, use the fallback info of 158 // |other|. 159 void TakeFallbackContentFrom(DelegatedFrameHost* other); 160 GetWeakPtr()161 base::WeakPtr<DelegatedFrameHost> GetWeakPtr() { 162 return weak_factory_.GetWeakPtr(); 163 } 164 stale_content_layer()165 const ui::Layer* stale_content_layer() const { 166 return stale_content_layer_.get(); 167 } 168 frame_eviction_state()169 FrameEvictionState frame_eviction_state() const { 170 return frame_eviction_state_; 171 } 172 173 private: 174 friend class DelegatedFrameHostClient; 175 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraBrowserTest, 176 StaleFrameContentOnEvictionNormal); 177 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraBrowserTest, 178 StaleFrameContentOnEvictionRejected); 179 FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraBrowserTest, 180 StaleFrameContentOnEvictionNone); 181 182 // FrameEvictorClient implementation. 183 void EvictDelegatedFrame() override; 184 185 void DidCopyStaleContent(std::unique_ptr<viz::CopyOutputResult> result); 186 187 void ContinueDelegatedFrameEviction(); 188 189 SkColor GetGutterColor() const; 190 191 void CopyFromCompositingSurfaceInternal( 192 const gfx::Rect& src_subrect, 193 const gfx::Size& output_size, 194 viz::CopyOutputRequest::ResultFormat format, 195 viz::CopyOutputRequest::CopyOutputRequestCallback callback); 196 197 void SetFrameEvictionStateAndNotifyObservers( 198 FrameEvictionState frame_eviction_state); 199 200 const viz::FrameSinkId frame_sink_id_; 201 DelegatedFrameHostClient* const client_; 202 const bool should_register_frame_sink_id_; 203 ui::Compositor* compositor_ = nullptr; 204 205 // The LocalSurfaceId of the currently embedded surface. 206 viz::LocalSurfaceId local_surface_id_; 207 // The size of the above surface (updated at the same time). 208 gfx::Size surface_dip_size_; 209 210 // In non-surface sync, this is the size of the most recently activated 211 // surface (which is suitable for calculating gutter size). In surface sync, 212 // this is most recent size set in EmbedSurface. 213 // TODO(ccameron): The meaning of "current" should be made more clear here. 214 gfx::Size current_frame_size_in_dip_; 215 216 viz::HostFrameSinkManager* const host_frame_sink_manager_; 217 218 std::unique_ptr<viz::FrameEvictor> frame_evictor_; 219 220 viz::LocalSurfaceId first_local_surface_id_after_navigation_; 221 222 FrameEvictionState frame_eviction_state_ = FrameEvictionState::kNotStarted; 223 224 // Layer responsible for displaying the stale content for the DFHC when the 225 // actual web content frame has been evicted. This will be reset when a new 226 // compositor frame is submitted. 227 std::unique_ptr<ui::Layer> stale_content_layer_; 228 229 ContentToVisibleTimeReporter tab_switch_time_recorder_; 230 231 base::ObserverList<Observer>::Unchecked observers_; 232 233 base::WeakPtrFactory<DelegatedFrameHost> weak_factory_{this}; 234 235 DISALLOW_COPY_AND_ASSIGN(DelegatedFrameHost); 236 }; 237 238 } // namespace content 239 240 #endif // CONTENT_BROWSER_RENDERER_HOST_DELEGATED_FRAME_HOST_H_ 241