Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d164f2b authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Move some Scheduler APIs to VsyncSchedule

Scheduler::getDisplayStatInfo forces callers to query both the deadline
and period, so split it into two VsyncSchedule APIs. Inline Scheduler::
getPreviousVsyncFrom.

Introduce <scheduler/Time.h> for type-safe, self-documenting wrappers
around std::chrono, which will gradually supersede nsecs_t (including
<scheduler/Fps.h> integration).

Clean up SF helpers for previous present fences. Remove the unnecessary
and inaccurate CompositorTiming initialization.

Bug: 185535769
Test: Perfetto timeline is green.
Change-Id: I22d8ad44ae37612e66f9d98fd4e7e1831951eb99
parent fb3beed5
Loading
Loading
Loading
Loading
+1 −16
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@
#include <ftl/fake_guard.h>
#include <gui/WindowInfo.h>
#include <system/window.h>
#include <ui/DisplayStatInfo.h>
#include <utils/Timers.h>
#include <utils/Trace.h>

@@ -172,8 +171,7 @@ impl::EventThread::ThrottleVsyncCallback Scheduler::makeThrottleVsyncCallback()
impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction() const {
    return [this](uid_t uid) {
        const Fps refreshRate = holdRefreshRateConfigs()->getActiveMode()->getFps();
        const auto currentPeriod =
                mVsyncSchedule->getTracker().currentPeriod() ?: refreshRate.getPeriodNsecs();
        const nsecs_t currentPeriod = mVsyncSchedule->period().ns() ?: refreshRate.getPeriodNsecs();

        const auto frameRate = getFrameRateOverride(uid);
        if (!frameRate.has_value()) {
@@ -361,12 +359,6 @@ void Scheduler::setDuration(ConnectionHandle handle, std::chrono::nanoseconds wo
    thread->setDuration(workDuration, readyDuration);
}

DisplayStatInfo Scheduler::getDisplayStatInfo(nsecs_t now) {
    const auto vsyncTime = mVsyncSchedule->getTracker().nextAnticipatedVSyncTimeFrom(now);
    const auto vsyncPeriod = mVsyncSchedule->getTracker().currentPeriod();
    return DisplayStatInfo{.vsyncTime = vsyncTime, .vsyncPeriod = vsyncPeriod};
}

ConnectionHandle Scheduler::enableVSyncInjection(bool enable) {
    if (mInjectVSyncs == enable) {
        return {};
@@ -776,11 +768,4 @@ void Scheduler::setPreferredRefreshRateForUid(FrameRateOverride frameRateOverrid
    mFrameRateOverrideMappings.setPreferredRefreshRateForUid(frameRateOverride);
}

std::chrono::steady_clock::time_point Scheduler::getPreviousVsyncFrom(
        nsecs_t expectedPresentTime) const {
    const auto presentTime = std::chrono::nanoseconds(expectedPresentTime);
    const auto vsyncPeriod = std::chrono::nanoseconds(mVsyncSchedule->getTracker().currentPeriod());
    return std::chrono::steady_clock::time_point(presentTime - vsyncPeriod);
}

} // namespace android::scheduler
+2 −7
Original line number Diff line number Diff line
@@ -32,9 +32,8 @@
#include <ui/GraphicTypes.h>
#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"

#include <ui/DisplayStatInfo.h>

#include <scheduler/Features.h>
#include <scheduler/Time.h>

#include "EventThread.h"
#include "FrameRateOverrideMappings.h"
@@ -150,8 +149,6 @@ public:
    void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
                     std::chrono::nanoseconds readyDuration);

    DisplayStatInfo getDisplayStatInfo(nsecs_t now);

    // Returns injector handle if injection has toggled, or an invalid handle otherwise.
    ConnectionHandle enableVSyncInjection(bool enable);
    // Returns false if injection is disabled.
@@ -190,14 +187,12 @@ public:

    void setDisplayPowerMode(hal::PowerMode powerMode);

    VSyncDispatch& getVsyncDispatch() { return mVsyncSchedule->getDispatch(); }
    VsyncSchedule& getVsyncSchedule() { return *mVsyncSchedule; }

    // Returns true if a given vsync timestamp is considered valid vsync
    // for a given uid
    bool isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const;

    std::chrono::steady_clock::time_point getPreviousVsyncFrom(nsecs_t expectedPresentTime) const;

    void dump(std::string&) const;
    void dump(ConnectionHandle, std::string&) const;
    void dumpVsync(std::string&) const;
+8 −0
Original line number Diff line number Diff line
@@ -68,6 +68,14 @@ VsyncSchedule::VsyncSchedule(TrackerPtr tracker, DispatchPtr dispatch, Controlle
VsyncSchedule::VsyncSchedule(VsyncSchedule&&) = default;
VsyncSchedule::~VsyncSchedule() = default;

Period VsyncSchedule::period() const {
    return Period::fromNs(mTracker->currentPeriod());
}

TimePoint VsyncSchedule::vsyncDeadlineAfter(TimePoint timePoint) const {
    return TimePoint::fromNs(mTracker->nextAnticipatedVSyncTimeFrom(timePoint.ns()));
}

void VsyncSchedule::dump(std::string& out) const {
    out.append("VsyncController:\n");
    mController->dump(out);
+4 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <string>

#include <scheduler/Features.h>
#include <scheduler/Time.h>

namespace android::scheduler {

@@ -38,6 +39,9 @@ public:
    VsyncSchedule(VsyncSchedule&&);
    ~VsyncSchedule();

    Period period() const;
    TimePoint vsyncDeadlineAfter(TimePoint) const;

    // TODO(b/185535769): Hide behind API.
    const VsyncTracker& getTracker() const { return *mTracker; }
    VsyncTracker& getTracker() { return *mTracker; }
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 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 <chrono>

#include <utils/Timers.h>

namespace android {
namespace scheduler {

// TODO(b/185535769): Pull Clock.h to libscheduler to reuse this.
using SchedulerClock = std::chrono::high_resolution_clock;
static_assert(SchedulerClock::is_steady);

} // namespace scheduler

struct Duration;

struct TimePoint : scheduler::SchedulerClock::time_point {
    explicit TimePoint(const Duration&);

    // Implicit conversion from std::chrono counterpart.
    constexpr TimePoint(scheduler::SchedulerClock::time_point p)
          : scheduler::SchedulerClock::time_point(p) {}

    static TimePoint fromNs(nsecs_t);

    nsecs_t ns() const;
};

struct Duration : TimePoint::duration {
    // Implicit conversion from std::chrono counterpart.
    constexpr Duration(TimePoint::duration d) : TimePoint::duration(d) {}

    static Duration fromNs(nsecs_t ns) { return {std::chrono::nanoseconds(ns)}; }

    nsecs_t ns() const { return std::chrono::nanoseconds(*this).count(); }
};

using Period = Duration;

inline TimePoint::TimePoint(const Duration& d) : scheduler::SchedulerClock::time_point(d) {}

inline TimePoint TimePoint::fromNs(nsecs_t ns) {
    return TimePoint(Duration::fromNs(ns));
}

inline nsecs_t TimePoint::ns() const {
    return Duration(time_since_epoch()).ns();
}

} // namespace android
Loading