1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <utils/Log.h> 20 #include <utils/Timers.h> 21 #include <functional> 22 #include <optional> 23 #include <string> 24 25 #include "StrongTyping.h" 26 27 namespace android::scheduler { 28 class TimeKeeper; 29 class VSyncTracker; 30 31 using ScheduleResult = std::optional<nsecs_t>; 32 33 enum class CancelResult { Cancelled, TooLate, Error }; 34 35 /* 36 * VSyncDispatch is a class that will dispatch callbacks relative to system vsync events. 37 */ 38 class VSyncDispatch { 39 public: 40 using CallbackToken = StrongTyping<size_t, class CallbackTokenTag, Compare, Hash>; 41 42 virtual ~VSyncDispatch(); 43 44 /* 45 * A callback that can be registered to be awoken at a given time relative to a vsync event. 46 * \param [in] vsyncTime: The timestamp of the vsync the callback is for. 47 * \param [in] targetWakeupTime: The timestamp of intended wakeup time of the cb. 48 * \param [in] readyTime: The timestamp of intended time where client needs to finish 49 * its work by. 50 */ 51 using Callback = 52 std::function<void(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime)>; 53 54 /* 55 * Registers a callback that will be called at designated points on the vsync timeline. 56 * The callback can be scheduled, rescheduled targeting vsync times, or cancelled. 57 * The token returned must be cleaned up via unregisterCallback. 58 * 59 * \param [in] callbackFn A function to schedule for callback. The resources needed to invoke 60 * callbackFn must have lifetimes encompassing the lifetime of the 61 * CallbackToken returned. 62 * \param [in] callbackName A human-readable, unique name to identify the callback. 63 * \return A token that can be used to schedule, reschedule, or cancel the 64 * invocation of callbackFn. 65 * 66 */ 67 virtual CallbackToken registerCallback(Callback const& callbackFn, 68 std::string callbackName) = 0; 69 70 /* 71 * Unregisters a callback. 72 * 73 * \param [in] token The callback to unregister. 74 * 75 */ 76 virtual void unregisterCallback(CallbackToken token) = 0; 77 78 /* 79 * Timing information about a scheduled callback 80 * 81 * @workDuration: The time needed for the client to perform its work 82 * @readyDuration: The time needed for the client to be ready before a vsync event. 83 * For external (non-SF) clients, not only do we need to account for their 84 * workDuration, but we also need to account for the time SF will take to 85 * process their buffer/transaction. In this case, readyDuration will be set 86 * to the SF duration in order to provide enough end-to-end time, and to be 87 * able to provide the ready-by time (deadline) on the callback. 88 * For internal clients, we don't need to add additional padding, so 89 * readyDuration will typically be 0. 90 * @earliestVsync: The targeted display time. This will be snapped to the closest 91 * predicted vsync time after earliestVsync. 92 * 93 * callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync 94 * event. 95 */ 96 struct ScheduleTiming { 97 nsecs_t workDuration = 0; 98 nsecs_t readyDuration = 0; 99 nsecs_t earliestVsync = 0; 100 101 bool operator==(const ScheduleTiming& other) const { 102 return workDuration == other.workDuration && readyDuration == other.readyDuration && 103 earliestVsync == other.earliestVsync; 104 } 105 106 bool operator!=(const ScheduleTiming& other) const { return !(*this == other); } 107 }; 108 109 /* 110 * Schedules the registered callback to be dispatched. 111 * 112 * The callback will be dispatched at 'workDuration + readyDuration' nanoseconds before a vsync 113 * event. 114 * 115 * The caller designates the earliest vsync event that should be targeted by the earliestVsync 116 * parameter. 117 * The callback will be scheduled at (workDuration + readyDuration - predictedVsync), where 118 * predictedVsync is the first vsync event time where ( predictedVsync >= earliestVsync ). 119 * 120 * If (workDuration + readyDuration - earliestVsync) is in the past, or if a callback has 121 * already been dispatched for the predictedVsync, an error will be returned. 122 * 123 * It is valid to reschedule a callback to a different time. 124 * 125 * \param [in] token The callback to schedule. 126 * \param [in] scheduleTiming The timing information for this schedule call 127 * \return The expected callback time if a callback was scheduled. 128 * std::nullopt if the callback is not registered. 129 */ 130 virtual ScheduleResult schedule(CallbackToken token, ScheduleTiming scheduleTiming) = 0; 131 132 /* Cancels a scheduled callback, if possible. 133 * 134 * \param [in] token The callback to cancel. 135 * \return A CancelResult::TooLate if the callback was already dispatched. 136 * A CancelResult::Cancelled if the callback was successfully cancelled. 137 * A CancelResult::Error if there was an pre-condition violation. 138 */ 139 virtual CancelResult cancel(CallbackToken token) = 0; 140 141 virtual void dump(std::string& result) const = 0; 142 143 protected: 144 VSyncDispatch() = default; 145 VSyncDispatch(VSyncDispatch const&) = delete; 146 VSyncDispatch& operator=(VSyncDispatch const&) = delete; 147 }; 148 149 /* 150 * Helper class to operate on registered callbacks. It is up to user of the class to ensure 151 * that VsyncDispatch lifetime exceeds the lifetime of VSyncCallbackRegistation. 152 */ 153 class VSyncCallbackRegistration { 154 public: 155 VSyncCallbackRegistration(VSyncDispatch&, VSyncDispatch::Callback const& callbackFn, 156 std::string const& callbackName); 157 VSyncCallbackRegistration(VSyncCallbackRegistration&&); 158 VSyncCallbackRegistration& operator=(VSyncCallbackRegistration&&); 159 ~VSyncCallbackRegistration(); 160 161 // See documentation for VSyncDispatch::schedule. 162 ScheduleResult schedule(VSyncDispatch::ScheduleTiming scheduleTiming); 163 164 // See documentation for VSyncDispatch::cancel. 165 CancelResult cancel(); 166 167 private: 168 VSyncCallbackRegistration(VSyncCallbackRegistration const&) = delete; 169 VSyncCallbackRegistration& operator=(VSyncCallbackRegistration const&) = delete; 170 171 std::reference_wrapper<VSyncDispatch> mDispatch; 172 VSyncDispatch::CallbackToken mToken; 173 bool mValidToken; 174 }; 175 176 } // namespace android::scheduler 177