1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <functional>
#include <memory>
#include <string>
#include <android-base/thread_annotations.h>
#include <ThreadContext.h>
#include <ftl/enum.h>
#include <ftl/optional.h>
#include <ui/DisplayId.h>
#include <scheduler/Features.h>
#include <scheduler/IVsyncSource.h>
#include <scheduler/Time.h>
#include "ThreadContext.h"
#include "VSyncTracker.h"
namespace android {
class EventThreadTest;
class VsyncScheduleTest;
}
namespace android::fuzz {
class SchedulerFuzzer;
}
namespace android::scheduler {
// TODO(b/185535769): Rename classes, and remove aliases.
class VSyncDispatch;
class VSyncTracker;
class VsyncController;
using VsyncDispatch = VSyncDispatch;
using VsyncTracker = VSyncTracker;
// Schedule that synchronizes to hardware VSYNC of a physical display.
class VsyncSchedule final : public IVsyncSource {
public:
using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>;
VsyncSchedule(ftl::NonNull<DisplayModePtr> modePtr, FeatureFlags, RequestHardwareVsync);
~VsyncSchedule();
// IVsyncSource overrides:
Period period() const override;
TimePoint vsyncDeadlineAfter(TimePoint,
ftl::Optional<TimePoint> lastVsyncOpt = {}) const override;
Period minFramePeriod() const override;
// Inform the schedule that the display mode changed the schedule needs to recalibrate
// itself to the new vsync period. The schedule will end the period transition internally.
// This will enable hardware VSYNCs in order to calibrate.
//
// \param [in] DisplayModePtr The mode that the display is changing to.
// \param [in] force True to force a transition even if it is not a
// change.
void onDisplayModeChanged(ftl::NonNull<DisplayModePtr>, bool force);
// Pass a VSYNC sample to VsyncController. Return true if
// VsyncController detected that the VSYNC period changed. Enable or disable
// hardware VSYNCs depending on whether more samples are needed.
bool addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod);
// TODO(b/185535769): Hide behind API.
VsyncTracker& getTracker() const { return *mTracker; }
VsyncTracker& getTracker() { return *mTracker; }
VsyncController& getController() { return *mController; }
// TODO(b/185535769): Once these are hidden behind the API, they may no
// longer need to be shared_ptrs.
using DispatchPtr = std::shared_ptr<VsyncDispatch>;
using TrackerPtr = std::shared_ptr<VsyncTracker>;
// TODO(b/185535769): Remove once VsyncSchedule owns all registrations.
DispatchPtr getDispatch() { return mDispatch; }
void dump(std::string&) const;
// Turn on hardware VSYNCs, unless mHwVsyncState is Disallowed, in which
// case this call is ignored.
void enableHardwareVsync() EXCLUDES(mHwVsyncLock);
// Disable hardware VSYNCs. If `disallow` is true, future calls to
// enableHardwareVsync are ineffective until isHardwareVsyncAllowed is
// called with `makeAllowed` set to true.
void disableHardwareVsync(bool disallow) EXCLUDES(mHwVsyncLock);
// If true, enableHardwareVsync can enable hardware VSYNC (if not already
// enabled). If false, enableHardwareVsync does nothing.
bool isHardwareVsyncAllowed(bool makeAllowed) EXCLUDES(mHwVsyncLock);
void setPendingHardwareVsyncState(bool enabled) REQUIRES(kMainThreadContext);
bool getPendingHardwareVsyncState() const REQUIRES(kMainThreadContext);
protected:
using ControllerPtr = std::unique_ptr<VsyncController>;
static void NoOpRequestHardwareVsync(PhysicalDisplayId, bool) {}
// For tests.
VsyncSchedule(PhysicalDisplayId, TrackerPtr, DispatchPtr, ControllerPtr,
RequestHardwareVsync = NoOpRequestHardwareVsync);
private:
friend class TestableScheduler;
friend class android::EventThreadTest;
friend class android::VsyncScheduleTest;
friend class android::fuzz::SchedulerFuzzer;
static TrackerPtr createTracker(ftl::NonNull<DisplayModePtr> modePtr);
static DispatchPtr createDispatch(TrackerPtr);
static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags);
void enableHardwareVsyncLocked() REQUIRES(mHwVsyncLock);
mutable std::mutex mHwVsyncLock;
enum class HwVsyncState {
// Hardware VSYNCs are currently enabled.
Enabled,
// Hardware VSYNCs are currently disabled. They can be enabled by a call
// to `enableHardwareVsync`.
Disabled,
// Hardware VSYNCs are not currently allowed (e.g. because the display
// is off).
Disallowed,
ftl_last = Disallowed,
};
HwVsyncState mHwVsyncState GUARDED_BY(mHwVsyncLock) = HwVsyncState::Disallowed;
// Pending state, in case an attempt is made to set the state while the
// device is off.
HwVsyncState mPendingHwVsyncState GUARDED_BY(kMainThreadContext) = HwVsyncState::Disabled;
class PredictedVsyncTracer;
using TracerPtr = std::unique_ptr<PredictedVsyncTracer>;
const PhysicalDisplayId mId;
const RequestHardwareVsync mRequestHardwareVsync;
const TrackerPtr mTracker;
const DispatchPtr mDispatch;
const ControllerPtr mController;
const TracerPtr mTracer;
};
} // namespace android::scheduler
|