1 // Copyright 2015 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_SCHEDULER_H_
6 #define COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_SCHEDULER_H_
7 
8 #include <memory>
9 
10 #include "base/cancelable_callback.h"
11 #include "base/containers/flat_map.h"
12 #include "base/macros.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/single_thread_task_runner.h"
15 #include "components/viz/common/display/renderer_settings.h"
16 #include "components/viz/common/frame_sinks/begin_frame_source.h"
17 #include "components/viz/common/surfaces/surface_id.h"
18 #include "components/viz/service/display/display_scheduler_base.h"
19 #include "components/viz/service/viz_service_export.h"
20 
21 namespace viz {
22 
23 class BeginFrameSource;
24 
25 class VIZ_SERVICE_EXPORT DisplayScheduler : public DisplaySchedulerBase {
26  public:
27   DisplayScheduler(BeginFrameSource* begin_frame_source,
28                    base::SingleThreadTaskRunner* task_runner,
29                    int max_pending_swaps,
30                    bool wait_for_all_surfaces_before_draw = false);
31   ~DisplayScheduler() override;
32 
33   // DisplaySchedulerBase implementation.
34   void SetVisible(bool visible) override;
35   void ForceImmediateSwapIfPossible() override;
36   void SetNeedsOneBeginFrame(bool needs_draw) override;
37   void DidSwapBuffers() override;
38   void DidReceiveSwapBuffersAck() override;
39   void OutputSurfaceLost() override;
40 
41   // DisplayDamageTrackerObserver implementation.
42   void OnDisplayDamaged(SurfaceId surface_id) override;
43   void OnRootFrameMissing(bool missing) override;
44   void OnPendingSurfacesChanged() override;
45 
46  protected:
47   class BeginFrameObserver;
48 
49   bool OnBeginFrame(const BeginFrameArgs& args);
50 
current_frame_display_time()51   base::TimeTicks current_frame_display_time() const {
52     return current_begin_frame_args_.frame_time +
53            current_begin_frame_args_.interval;
54   }
55 
56   // These values inidicate how a response to the BeginFrame should be
57   // scheduled.
58   enum class BeginFrameDeadlineMode {
59     // Respond immediately. This means either all clients have responded with a
60     // BeginFrameAck so there is nothing to wait for, or DrawAndSwap cannot
61     // happen anymore (for example, OutputSurface is lost) and we might as well
62     // respond right now.
63     kImmediate,
64     // Schedule a task at the the end of BeginFrame interval minus the estimated
65     // time to run DrawAndSwap. This indicates that all requirements for calling
66     // DrawAndSwap are met, but we just want to give clients as much time as
67     // possible to send CompositorFrames.
68     kRegular,
69     // Schedule a response at the end of the BeginFrame interval. This usually
70     // indicates that some requirements for calling DrawAndSwap are not
71     // currently met (for example, the previous swap is not acked yet) and
72     // we would like to wait as long as possible to see if DrawAndSwap becomes
73     // possible.
74     kLate,
75     // A response to the BeginFrame cannot be scheduled right now. This means we
76     // have an unlimited deadline and some clients haven't responded to the
77     // BeginFrame yet so we need to wait longer.
78     kNone
79   };
80   base::TimeTicks DesiredBeginFrameDeadlineTime() const;
81   BeginFrameDeadlineMode AdjustedBeginFrameDeadlineMode() const;
82   BeginFrameDeadlineMode DesiredBeginFrameDeadlineMode() const;
83   virtual void ScheduleBeginFrameDeadline();
84   bool AttemptDrawAndSwap();
85   void OnBeginFrameDeadline();
86   bool DrawAndSwap();
87   void MaybeStartObservingBeginFrames();
88   void StartObservingBeginFrames();
89   void StopObservingBeginFrames();
90   bool ShouldDraw() const;
91   void DidFinishFrame(bool did_draw);
92   // Updates |has_pending_surfaces_| and returns whether its value changed.
93   bool UpdateHasPendingSurfaces();
94 
95   std::unique_ptr<BeginFrameObserver> begin_frame_observer_;
96   BeginFrameSource* begin_frame_source_;
97   base::SingleThreadTaskRunner* task_runner_;
98 
99   BeginFrameArgs current_begin_frame_args_;
100   base::RepeatingClosure begin_frame_deadline_closure_;
101   base::CancelableOnceClosure begin_frame_deadline_task_;
102   base::TimeTicks begin_frame_deadline_task_time_;
103 
104   base::CancelableOnceClosure missed_begin_frame_task_;
105   bool inside_surface_damaged_;
106 
107   bool visible_;
108   bool output_surface_lost_;
109 
110   bool inside_begin_frame_deadline_interval_;
111   bool needs_draw_;
112   bool has_pending_surfaces_;
113 
114   int next_swap_id_;
115   int pending_swaps_;
116   int max_pending_swaps_;
117   bool wait_for_all_surfaces_before_draw_;
118 
119   bool observing_begin_frame_source_;
120 
121   base::WeakPtrFactory<DisplayScheduler> weak_ptr_factory_{this};
122 
123  private:
124   DISALLOW_COPY_AND_ASSIGN(DisplayScheduler);
125 };
126 
127 }  // namespace viz
128 
129 #endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_SCHEDULER_H_
130