157 lines
5.3 KiB
C++
157 lines
5.3 KiB
C++
/*
|
|
* 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 <memory>
|
|
#include <string>
|
|
|
|
#include <ThreadContext.h>
|
|
#include <android-base/thread_annotations.h>
|
|
#include <ftl/enum.h>
|
|
#include <ftl/optional.h>
|
|
#include <scheduler/Features.h>
|
|
#include <scheduler/Time.h>
|
|
#include <ui/DisplayId.h>
|
|
|
|
namespace android {
|
|
class EventThreadTest;
|
|
class VsyncScheduleTest;
|
|
}
|
|
|
|
namespace android::fuzz {
|
|
class SchedulerFuzzer;
|
|
}
|
|
|
|
namespace android::scheduler {
|
|
|
|
struct ISchedulerCallback;
|
|
|
|
// 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 {
|
|
public:
|
|
VsyncSchedule(PhysicalDisplayId, FeatureFlags);
|
|
~VsyncSchedule();
|
|
|
|
Period period() const;
|
|
TimePoint vsyncDeadlineAfter(TimePoint) const;
|
|
|
|
// Inform the schedule that the period is changing and the schedule needs to recalibrate
|
|
// itself. The schedule will end the period transition internally. This will
|
|
// enable hardware VSYNCs in order to calibrate.
|
|
//
|
|
// \param [in] period The period that the system is changing into.
|
|
// \param [in] force True to force a transition even if it is not a
|
|
// change.
|
|
void startPeriodTransition(ISchedulerCallback&, Period period, 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(ISchedulerCallback&, TimePoint timestamp,
|
|
ftl::Optional<Period> hwcVsyncPeriod);
|
|
|
|
// TODO(b/185535769): Hide behind API.
|
|
const 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(ISchedulerCallback&) 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(ISchedulerCallback&, 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>;
|
|
|
|
// For tests.
|
|
VsyncSchedule(PhysicalDisplayId, TrackerPtr, DispatchPtr, ControllerPtr);
|
|
|
|
private:
|
|
friend class TestableScheduler;
|
|
friend class android::EventThreadTest;
|
|
friend class android::VsyncScheduleTest;
|
|
friend class android::fuzz::SchedulerFuzzer;
|
|
|
|
static TrackerPtr createTracker(PhysicalDisplayId);
|
|
static DispatchPtr createDispatch(TrackerPtr);
|
|
static ControllerPtr createController(PhysicalDisplayId, VsyncTracker&, FeatureFlags);
|
|
|
|
void enableHardwareVsyncLocked(ISchedulerCallback&) 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 TrackerPtr mTracker;
|
|
const DispatchPtr mDispatch;
|
|
const ControllerPtr mController;
|
|
const TracerPtr mTracer;
|
|
};
|
|
|
|
} // namespace android::scheduler
|