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 COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_
6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_
7 
8 #include <memory>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/containers/circular_deque.h"
13 #include "base/macros.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/time/time.h"
18 #include "components/viz/common/frame_sinks/begin_frame_source.h"
19 #include "components/viz/common/gpu/context_lost_observer.h"
20 #include "components/viz/common/resources/returned_resource.h"
21 #include "components/viz/common/surfaces/frame_sink_id.h"
22 #include "components/viz/common/surfaces/surface_id.h"
23 #include "components/viz/service/display/display_compositor_memory_and_task_controller.h"
24 #include "components/viz/service/display/display_resource_provider.h"
25 #include "components/viz/service/display/display_scheduler.h"
26 #include "components/viz/service/display/frame_rate_decider.h"
27 #include "components/viz/service/display/output_surface_client.h"
28 #include "components/viz/service/display/overlay_processor_interface.h"
29 #include "components/viz/service/display/software_output_device_client.h"
30 #include "components/viz/service/display/surface_aggregator.h"
31 #include "components/viz/service/surfaces/latest_local_surface_id_lookup_delegate.h"
32 #include "components/viz/service/surfaces/surface.h"
33 #include "components/viz/service/surfaces/surface_manager.h"
34 #include "components/viz/service/viz_service_export.h"
35 #include "gpu/command_buffer/common/texture_in_use_response.h"
36 #include "ui/gfx/display_color_spaces.h"
37 #include "ui/gfx/overlay_transform.h"
38 #include "ui/gfx/swap_result.h"
39 #include "ui/latency/latency_info.h"
40 
41 namespace gfx {
42 class Size;
43 }
44 
45 namespace gpu {
46 class ScopedAllowScheduleGpuTask;
47 }
48 
49 namespace viz {
50 class AggregatedFrame;
51 class DelegatedInkPointRendererBase;
52 class DirectRenderer;
53 class DisplayClient;
54 class DisplayResourceProvider;
55 class OutputSurface;
56 class RendererSettings;
57 class SharedBitmapManager;
58 class SkiaOutputSurface;
59 class SoftwareRenderer;
60 
61 class VIZ_SERVICE_EXPORT DisplayObserver {
62  public:
~DisplayObserver()63   virtual ~DisplayObserver() {}
64 
65   virtual void OnDisplayDidFinishFrame(const BeginFrameAck& ack) = 0;
66   virtual void OnDisplayDestroyed() = 0;
67 };
68 
69 // A Display produces a surface that can be used to draw to a physical display
70 // (OutputSurface). The client is responsible for creating and sizing the
71 // surface IDs used to draw into the display and deciding when to draw.
72 class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient,
73                                    public OutputSurfaceClient,
74                                    public ContextLostObserver,
75                                    public LatestLocalSurfaceIdLookupDelegate,
76                                    public SoftwareOutputDeviceClient,
77                                    public FrameRateDecider::Client {
78  public:
79   // The |begin_frame_source| and |scheduler| may be null (together). In that
80   // case, DrawAndSwap must be called externally when needed.
81   // The |current_task_runner| may be null if the Display is on a thread without
82   // a MessageLoop.
83   // TODO(penghuang): Remove skia_output_surface when all DirectRenderer
84   // subclasses are replaced by SkiaRenderer.
85   Display(
86       SharedBitmapManager* bitmap_manager,
87       const RendererSettings& settings,
88       const DebugRendererSettings* debug_settings,
89       const FrameSinkId& frame_sink_id,
90       std::unique_ptr<DisplayCompositorMemoryAndTaskController> gpu_dependency,
91       std::unique_ptr<OutputSurface> output_surface,
92       std::unique_ptr<OverlayProcessorInterface> overlay_processor,
93       std::unique_ptr<DisplaySchedulerBase> scheduler,
94       scoped_refptr<base::SingleThreadTaskRunner> current_task_runner);
95 
96   ~Display() override;
97 
98   static constexpr base::TimeDelta kDrawToSwapMin =
99       base::TimeDelta::FromMicroseconds(5);
100   static constexpr base::TimeDelta kDrawToSwapMax =
101       base::TimeDelta::FromMilliseconds(50);
102   static constexpr uint32_t kDrawToSwapUsBuckets = 50;
103 
104   // TODO(cblume, crbug.com/900973): |enable_shared_images| is a temporary
105   // solution that unblocks us until SharedImages are threadsafe in WebView.
106 #if defined(ANDROID)
107   static constexpr bool kEnableSharedImages = false;
108 #else
109   static constexpr bool kEnableSharedImages = true;
110 #endif
111   void Initialize(DisplayClient* client,
112                   SurfaceManager* surface_manager,
113                   bool enable_shared_images = kEnableSharedImages,
114                   bool hw_support_for_multiple_refresh_rates = false,
115                   size_t num_of_frames_to_toggle_interval = 60);
116 
117   void AddObserver(DisplayObserver* observer);
118   void RemoveObserver(DisplayObserver* observer);
119 
120   // device_scale_factor is used to communicate to the external window system
121   // what scale this was rendered at.
122   void SetLocalSurfaceId(const LocalSurfaceId& id, float device_scale_factor);
123   void SetVisible(bool visible);
124   void Resize(const gfx::Size& new_size);
125 
126   // This disallows resource provider to access GPU thread to unlock resources
127   // outside of Initialize, DrawAndSwap and dtor.
128   void DisableGPUAccessByDefault();
129 
130   // Stop drawing until Resize() is called with a new size. If the display
131   // hasn't drawn a frame at the current size *and* it's possible to immediately
132   // draw then this will run DrawAndSwap() first.
133   //
134   // |no_pending_swaps_callback| will be run there are no more swaps pending and
135   // may be run immediately.
136   void DisableSwapUntilResize(base::OnceClosure no_pending_swaps_callback);
137 
138   // Sets the color matrix that will be used to transform the output of this
139   // display. This is only supported for GPU compositing.
140   void SetColorMatrix(const SkMatrix44& matrix);
141 
142   void SetDisplayColorSpaces(
143       const gfx::DisplayColorSpaces& display_color_spaces);
144   void SetOutputIsSecure(bool secure);
145 
146   const SurfaceId& CurrentSurfaceId();
147 
148   // DisplaySchedulerClient implementation.
149   bool DrawAndSwap(base::TimeTicks expected_display_time) override;
150   void DidFinishFrame(const BeginFrameAck& ack) override;
151 
152   // OutputSurfaceClient implementation.
153   void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override;
154   void DidReceiveSwapBuffersAck(const gfx::SwapTimings& timings) override;
155   void DidReceiveTextureInUseResponses(
156       const gpu::TextureInUseResponses& responses) override;
157   void DidReceiveCALayerParams(
158       const gfx::CALayerParams& ca_layer_params) override;
159   void DidSwapWithSize(const gfx::Size& pixel_size) override;
160   void DidReceivePresentationFeedback(
161       const gfx::PresentationFeedback& feedback) override;
162   void DidReceiveReleasedOverlays(
163       const std::vector<gpu::Mailbox>& released_overlays) override;
164 
165   // LatestLocalSurfaceIdLookupDelegate implementation.
166   LocalSurfaceId GetSurfaceAtAggregation(
167       const FrameSinkId& frame_sink_id) const override;
168 
169   // SoftwareOutputDeviceClient implementation
170   void SoftwareDeviceUpdatedCALayerParams(
171       const gfx::CALayerParams& ca_layer_params) override;
172 
173   // FrameRateDecider::Client implementation
174   void SetPreferredFrameInterval(base::TimeDelta interval) override;
175   base::TimeDelta GetPreferredFrameIntervalForFrameSinkId(
176       const FrameSinkId& id,
177       mojom::CompositorFrameSinkType* type) override;
178 
has_scheduler()179   bool has_scheduler() const { return !!scheduler_; }
renderer_for_testing()180   DirectRenderer* renderer_for_testing() const { return renderer_.get(); }
181 
182   void ForceImmediateDrawAndSwapIfPossible();
183   void SetNeedsOneBeginFrame();
184   void RemoveOverdrawQuads(AggregatedFrame* frame);
185 
186   void SetSupportedFrameIntervals(std::vector<base::TimeDelta> intervals);
187 
188   base::ScopedClosureRunner GetCacheBackBufferCb();
189 
190   bool IsRootFrameMissing() const;
191   bool HasPendingSurfaces(const BeginFrameArgs& args) const;
192 
193   // Return the delegated ink point renderer from |renderer_|, creating it if
194   // one doesn't exist. Should only be used when the delegated ink trails web
195   // API has been used.
196   DelegatedInkPointRendererBase* GetDelegatedInkPointRenderer();
197 
198  private:
199   friend class DisplayTest;
200   // PresentationGroupTiming stores rendering pipeline stage timings associated
201   // with a call to Display::DrawAndSwap along with a list of
202   // Surface::PresentationHelper's for each aggregated Surface that will be
203   // presented.
204   class PresentationGroupTiming {
205    public:
206     PresentationGroupTiming();
207     PresentationGroupTiming(PresentationGroupTiming&& other);
208     ~PresentationGroupTiming();
209 
210     void AddPresentationHelper(
211         std::unique_ptr<Surface::PresentationHelper> helper);
212     void OnDraw(base::TimeTicks draw_start_timestamp);
213     void OnSwap(gfx::SwapTimings timings);
HasSwapped()214     bool HasSwapped() const { return !swap_timings_.is_null(); }
215     void OnPresent(const gfx::PresentationFeedback& feedback);
216 
draw_start_timestamp()217     base::TimeTicks draw_start_timestamp() const {
218       return draw_start_timestamp_;
219     }
220 
221    private:
222     base::TimeTicks draw_start_timestamp_;
223     gfx::SwapTimings swap_timings_;
224     std::vector<std::unique_ptr<Surface::PresentationHelper>>
225         presentation_helpers_;
226 
227     DISALLOW_COPY_AND_ASSIGN(PresentationGroupTiming);
228   };
229 
230   // TODO(cblume, crbug.com/900973): |enable_shared_images| is a temporary
231   // solution that unblocks us until SharedImages are threadsafe in WebView.
232   void InitializeRenderer(bool enable_shared_images = true);
233 
234   // ContextLostObserver implementation.
235   void OnContextLost() override;
236 
237   SharedBitmapManager* const bitmap_manager_;
238   const RendererSettings settings_;
239 
240   // Points to the viz-global singleton.
241   const DebugRendererSettings* const debug_settings_;
242 
243   DisplayClient* client_ = nullptr;
244   base::ObserverList<DisplayObserver>::Unchecked observers_;
245   SurfaceManager* surface_manager_ = nullptr;
246   const FrameSinkId frame_sink_id_;
247   SurfaceId current_surface_id_;
248   gfx::Size current_surface_size_;
249   float device_scale_factor_ = 1.f;
250   gfx::DisplayColorSpaces display_color_spaces_;
251   bool visible_ = false;
252   bool swapped_since_resize_ = false;
253   bool output_is_secure_ = false;
254 
255 #if DCHECK_IS_ON()
256   std::unique_ptr<gpu::ScopedAllowScheduleGpuTask>
257       allow_schedule_gpu_task_during_destruction_;
258 #endif
259   std::unique_ptr<DisplayCompositorMemoryAndTaskController> gpu_dependency_;
260   std::unique_ptr<OutputSurface> output_surface_;
261   SkiaOutputSurface* const skia_output_surface_;
262   std::unique_ptr<DisplayDamageTracker> damage_tracker_;
263   std::unique_ptr<DisplaySchedulerBase> scheduler_;
264   std::unique_ptr<DisplayResourceProvider> resource_provider_;
265   std::unique_ptr<SurfaceAggregator> aggregator_;
266   bool last_wide_color_enabled_ = false;
267   std::unique_ptr<FrameRateDecider> frame_rate_decider_;
268   // This may be null if the Display is on a thread without a MessageLoop.
269   scoped_refptr<base::SingleThreadTaskRunner> current_task_runner_;
270   std::unique_ptr<DirectRenderer> renderer_;
271   SoftwareRenderer* software_renderer_ = nullptr;
272   // Currently, this OverlayProcessor takes raw pointer to memory tracker, which
273   // is owned by the OutputSurface. This OverlayProcessor also takes resource
274   // locks which contains raw pointers to DisplayResourceProvider. Make sure
275   // both the OutputSurface and the DisplayResourceProvider outlive the
276   // Overlay Processor.
277   std::unique_ptr<OverlayProcessorInterface> overlay_processor_;
278   std::vector<ui::LatencyInfo> stored_latency_info_;
279   std::vector<gfx::Rect> cached_visible_region_;
280 
281   // |pending_presentation_group_timings_| stores a
282   // Display::PresentationGroupTiming for each group currently waiting for
283   // Display::DidReceivePresentationFeedack()
284   base::circular_deque<Display::PresentationGroupTiming>
285       pending_presentation_group_timings_;
286 
287   bool disable_swap_until_resize_ = true;
288 
289   // Callback that will be run after all pending swaps have acked.
290   base::OnceClosure no_pending_swaps_callback_;
291 
292   int64_t swapped_trace_id_ = 0;
293   int64_t last_swap_ack_trace_id_ = 0;
294   int64_t last_presented_trace_id_ = 0;
295   int pending_swaps_ = 0;
296 
297   // The height of the top-controls in the previously drawn frame.
298   float last_top_controls_visible_height_ = 0.f;
299 
300   DISALLOW_COPY_AND_ASSIGN(Display);
301 };
302 
303 }  // namespace viz
304 
305 #endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_
306