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