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