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