Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 SERVICES_GFX_COMPOSITOR_BACKEND_VSYNC_SCHEDULER_H_ | |
| 6 #define SERVICES_GFX_COMPOSITOR_BACKEND_VSYNC_SCHEDULER_H_ | |
| 7 | |
| 8 #include <limits> | |
| 9 #include <memory> | |
| 10 #include <mutex> | |
| 11 | |
| 12 #include "base/callback.h" | |
| 13 #include "base/macros.h" | |
| 14 #include "base/memory/ref_counted.h" | |
| 15 #include "base/task_runner.h" | |
| 16 #include "services/gfx/compositor/backend/scheduler.h" | |
| 17 | |
| 18 namespace compositor { | |
| 19 | |
| 20 // Schedules work to coincide with vsync intervals. | |
| 21 // | |
| 22 // This object is thread-safe and it intended to be used to allow one thread | |
| 23 // to be scheduling work for itself while another thread concurrently updates | |
| 24 // timing parameters. | |
| 25 class VsyncScheduler : public Scheduler { | |
| 26 public: | |
| 27 // Limits on allowable parameters. (Exposed for testing.) | |
| 28 static constexpr int64_t kMinVsyncInterval = 1000; // 1000 Hz | |
|
viettrungluu
2016/01/04 21:08:24
You need to declare storage for these (in the .cc)
jeffbrown
2016/01/16 03:28:31
Hah! You're right. I'd interpreted constexpr as
| |
| 29 static constexpr int64_t kMaxVsyncInterval = 1000000; // 1 Hz | |
| 30 | |
| 31 // Time reference. Should be MojoTimeTicksNow() except during testing. | |
| 32 using Clock = base::Callback<MojoTimeTicks()>; | |
| 33 | |
| 34 VsyncScheduler(const scoped_refptr<base::TaskRunner>& task_runner, | |
| 35 const SchedulerCallbacks& callbacks); | |
| 36 VsyncScheduler(const scoped_refptr<base::TaskRunner>& task_runner, | |
| 37 const SchedulerCallbacks& callbacks, | |
| 38 const Clock& clock); | |
| 39 ~VsyncScheduler() override; | |
| 40 | |
| 41 // Starts scheduling work and sets the scheduling parameters. | |
| 42 // | |
| 43 // |vsync_timebase| is a value in the |MojoTimeTicks| timebase which | |
| 44 // specifies when a recent vsync occurred and is used to determine the phase. | |
| 45 // | |
| 46 // |vsync_interval| is the number of microseconds between vsyncs which | |
| 47 // also determines the |FrameInfo.frame_interval| value to deliver to | |
| 48 // applications. | |
| 49 // | |
| 50 // |update_phase| specifies an offset relative to vsync for determining | |
| 51 // when updates are scheduled and the |FrameInfo.frame_time| to deliver | |
| 52 // to applications. | |
| 53 // | |
| 54 // |snapshot_phase| specifies an offset relative to vsync for | |
| 55 // determining when snapshots are scheduled and the |FrameInfo.frame_deadline| | |
| 56 // to deliver to applications. Must be greater than or equal to | |
| 57 // |update_phase|. | |
| 58 // | |
| 59 // |presentation_phase| specifies an offset relative to vsync for | |
| 60 // determining when frames are shown on the display output and the | |
| 61 // |FrameInfo.presentation_time| to deliver to applications. Must be | |
| 62 // greater than or equal to |snapshot_phase|. | |
| 63 // | |
| 64 // The notion of 'vsync' is somewhat abstract here. It's just a reference | |
| 65 // pulse but we usually interpret it as a deadline for preparing the next | |
| 66 // frame and submitting it to the display hardware. | |
| 67 // | |
| 68 // The phases can be positive or negative but negative offsets from vsync | |
| 69 // may be easier to interpret when computing deadlines. To avoid | |
| 70 // overflows, the values chosen for the phases should be close to 0. | |
| 71 // | |
| 72 // This function schedules an update and snapshot if not already scheduled. | |
| 73 // | |
| 74 // Returns true if the schedule was started successfully, false if the | |
| 75 // parameters are invalid. | |
| 76 bool Start(int64_t vsync_timebase, | |
| 77 int64_t vsync_interval, | |
| 78 int64_t update_phase, | |
| 79 int64_t snapshot_phase, | |
| 80 int64_t presentation_phase) { | |
| 81 return state_->Start(vsync_timebase, vsync_interval, update_phase, | |
| 82 snapshot_phase, presentation_phase); | |
| 83 } | |
| 84 | |
| 85 // Stops scheduling work. | |
| 86 // | |
| 87 // Previously scheduled callbacks may still be delivered. | |
| 88 void Stop() { state_->Stop(); } | |
| 89 | |
| 90 // |Scheduler|: | |
| 91 void ScheduleFrame(SchedulingMode scheduling_mode) override; | |
| 92 | |
| 93 private: | |
| 94 // Internal state. Held by a shared_ptr so that callbacks running on | |
| 95 // other threads can reference it using a weak_ptr. | |
| 96 class State : public std::enable_shared_from_this<State> { | |
| 97 public: | |
| 98 State(const scoped_refptr<base::TaskRunner>& task_runner, | |
| 99 const SchedulerCallbacks& callbacks, | |
| 100 const Clock& clock); | |
| 101 ~State(); | |
| 102 | |
| 103 MojoTimeTicks GetTimeTicksNow() { return clock_.Run(); } | |
| 104 | |
| 105 bool Start(int64_t vsync_timebase, | |
| 106 int64_t vsync_interval, | |
| 107 int64_t update_phase, | |
| 108 int64_t snapshot_phase, | |
| 109 int64_t presentation_phase); | |
| 110 void Stop(); | |
| 111 void ScheduleFrame(SchedulingMode scheduling_mode); | |
| 112 | |
| 113 private: | |
| 114 enum class Action { | |
| 115 kUpdate, | |
| 116 kEarlySnapshot, | |
| 117 kLateSnapshot, | |
| 118 }; | |
| 119 | |
| 120 static void DispatchThunk(const std::weak_ptr<State>& state_weak, | |
| 121 int32_t generation, | |
| 122 Action action, | |
| 123 int64_t update_time); | |
| 124 | |
| 125 void ScheduleLocked(MojoTimeTicks now); | |
| 126 void PostDispatchLocked(int64_t now, | |
| 127 int64_t delivery_time, | |
| 128 Action action, | |
| 129 int64_t update_time); | |
| 130 | |
| 131 void Dispatch(int32_t generation, Action action, int64_t update_time); | |
| 132 void SetFrameInfoLocked(mojo::gfx::composition::FrameInfo* frame_info, | |
| 133 int64_t update_time); | |
| 134 | |
| 135 const scoped_refptr<base::TaskRunner> task_runner_; | |
| 136 const SchedulerCallbacks callbacks_; | |
| 137 const Clock clock_; | |
| 138 | |
| 139 // Parameters and state guarded by |mutex_|. | |
| 140 std::mutex mutex_; | |
| 141 bool running_ = false; | |
| 142 int32_t generation_ = 0; | |
| 143 int64_t vsync_timebase_ = 0; | |
| 144 int64_t vsync_interval_ = 0; | |
| 145 int64_t update_phase_ = 0; | |
| 146 int64_t snapshot_phase_ = 0; | |
| 147 int64_t presentation_phase_ = 0; | |
| 148 bool need_update_ = false; | |
| 149 bool pending_dispatch_ = false; | |
| 150 int64_t last_delivered_update_time_ = std::numeric_limits<int64_t>::min(); | |
| 151 | |
| 152 DISALLOW_COPY_AND_ASSIGN(State); | |
| 153 }; | |
| 154 | |
| 155 const std::shared_ptr<State> state_; | |
| 156 | |
| 157 DISALLOW_COPY_AND_ASSIGN(VsyncScheduler); | |
| 158 }; | |
| 159 | |
| 160 } // namespace compositor | |
| 161 | |
| 162 #endif // SERVICES_GFX_COMPOSITOR_BACKEND_VSYNC_SCHEDULER_H_ | |
| OLD | NEW |