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

Commit e8436a0f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Clean up VSyncModulator"

parents ef4c7148 eddeda1e
Loading
Loading
Loading
Loading
+65 −78
Original line number Original line Diff line number Diff line
@@ -18,115 +18,102 @@


#include <cutils/properties.h>
#include <cutils/properties.h>


#include "SurfaceFlingerProperties.h"
#include <optional>

namespace android {
using namespace android::sysprop;

namespace scheduler {

using RefreshRateType = RefreshRateConfigs::RefreshRateType;
PhaseOffsets::~PhaseOffsets() = default;


namespace impl {
#include "SurfaceFlingerProperties.h"
PhaseOffsets::PhaseOffsets() {
    int64_t vsyncPhaseOffsetNs = vsync_event_phase_offset_ns(1000000);


    int64_t sfVsyncPhaseOffsetNs = vsync_sf_event_phase_offset_ns(1000000);
namespace {


std::optional<int> getProperty(const char* name) {
    char value[PROPERTY_VALUE_MAX];
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.sf.early_phase_offset_ns", value, "-1");
    property_get(name, value, "-1");
    const int earlySfOffsetNs = atoi(value);
    if (const int i = atoi(value); i != -1) return i;

    return std::nullopt;
    property_get("debug.sf.early_gl_phase_offset_ns", value, "-1");
}
    const int earlyGlSfOffsetNs = atoi(value);

    property_get("debug.sf.early_app_phase_offset_ns", value, "-1");
    const int earlyAppOffsetNs = atoi(value);

    property_get("debug.sf.early_gl_app_phase_offset_ns", value, "-1");
    const int earlyGlAppOffsetNs = atoi(value);

    property_get("debug.sf.high_fps_early_phase_offset_ns", value, "-1");
    const int highFpsEarlySfOffsetNs = atoi(value);

    property_get("debug.sf.high_fps_early_gl_phase_offset_ns", value, "-1");
    const int highFpsEarlyGlSfOffsetNs = atoi(value);


    property_get("debug.sf.high_fps_early_app_phase_offset_ns", value, "-1");
} // namespace
    const int highFpsEarlyAppOffsetNs = atoi(value);


    property_get("debug.sf.high_fps_early_gl_app_phase_offset_ns", value, "-1");
namespace android::scheduler {
    const int highFpsEarlyGlAppOffsetNs = atoi(value);


    // TODO(b/122905996): Define these in device.mk.
PhaseOffsets::~PhaseOffsets() = default;
    property_get("debug.sf.high_fps_late_app_phase_offset_ns", value, "2000000");
    const int highFpsLateAppOffsetNs = atoi(value);


    property_get("debug.sf.high_fps_late_sf_phase_offset_ns", value, "1000000");
namespace impl {
    const int highFpsLateSfOffsetNs = atoi(value);


PhaseOffsets::PhaseOffsets() {
    // Below defines the threshold when an offset is considered to be negative, i.e. targeting
    // Below defines the threshold when an offset is considered to be negative, i.e. targeting
    // for the N+2 vsync instead of N+1. This means that:
    // for the N+2 vsync instead of N+1. This means that:
    // For offset < threshold, SF wake up (vsync_duration - offset) before HW vsync.
    // For offset < threshold, SF wake up (vsync_duration - offset) before HW vsync.
    // For offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW vsync.
    // For offset >= threshold, SF wake up (2 * vsync_duration - offset) before HW vsync.
    property_get("debug.sf.phase_offset_threshold_for_next_vsync_ns", value, "-1");
    const nsecs_t thresholdForNextVsync =
    const int phaseOffsetThresholdForNextVsyncNs = atoi(value);
            getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns")

                    .value_or(std::numeric_limits<nsecs_t>::max());
    Offsets defaultOffsets;

    Offsets highFpsOffsets;
    const Offsets defaultOffsets = getDefaultOffsets(thresholdForNextVsync);
    defaultOffsets.early = {RefreshRateType::DEFAULT,
    const Offsets highFpsOffsets = getHighFpsOffsets(thresholdForNextVsync);
                            earlySfOffsetNs != -1 ? earlySfOffsetNs : sfVsyncPhaseOffsetNs,
                            earlyAppOffsetNs != -1 ? earlyAppOffsetNs : vsyncPhaseOffsetNs};
    defaultOffsets.earlyGl = {RefreshRateType::DEFAULT,
                              earlyGlSfOffsetNs != -1 ? earlyGlSfOffsetNs : sfVsyncPhaseOffsetNs,
                              earlyGlAppOffsetNs != -1 ? earlyGlAppOffsetNs : vsyncPhaseOffsetNs};
    defaultOffsets.late = {RefreshRateType::DEFAULT, sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs};

    highFpsOffsets.early = {RefreshRateType::PERFORMANCE,
                            highFpsEarlySfOffsetNs != -1 ? highFpsEarlySfOffsetNs
                                                         : highFpsLateSfOffsetNs,
                            highFpsEarlyAppOffsetNs != -1 ? highFpsEarlyAppOffsetNs
                                                          : highFpsLateAppOffsetNs};
    highFpsOffsets.earlyGl = {RefreshRateType::PERFORMANCE,
                              highFpsEarlyGlSfOffsetNs != -1 ? highFpsEarlyGlSfOffsetNs
                                                             : highFpsLateSfOffsetNs,
                              highFpsEarlyGlAppOffsetNs != -1 ? highFpsEarlyGlAppOffsetNs
                                                              : highFpsLateAppOffsetNs};
    highFpsOffsets.late = {RefreshRateType::PERFORMANCE, highFpsLateSfOffsetNs,
                           highFpsLateAppOffsetNs};


    mOffsets.insert({RefreshRateType::POWER_SAVING, defaultOffsets});
    mOffsets.insert({RefreshRateType::POWER_SAVING, defaultOffsets});
    mOffsets.insert({RefreshRateType::DEFAULT, defaultOffsets});
    mOffsets.insert({RefreshRateType::DEFAULT, defaultOffsets});
    mOffsets.insert({RefreshRateType::PERFORMANCE, highFpsOffsets});
    mOffsets.insert({RefreshRateType::PERFORMANCE, highFpsOffsets});

    mOffsetThresholdForNextVsync = phaseOffsetThresholdForNextVsyncNs != -1
            ? phaseOffsetThresholdForNextVsyncNs
            : std::numeric_limits<nsecs_t>::max();
}
}


PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(
PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(
        android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const {
        RefreshRateType refreshRateType) const {
    return mOffsets.at(refreshRateType);
    return mOffsets.at(refreshRateType);
}
}


void PhaseOffsets::dump(std::string& result) const {
void PhaseOffsets::dump(std::string& result) const {
    const auto [early, earlyGl, late] = getCurrentOffsets();
    const auto [early, earlyGl, late, threshold] = getCurrentOffsets();
    base::StringAppendF(&result,
    base::StringAppendF(&result,
                        "         app phase: %9" PRId64 " ns\t         SF phase: %9" PRId64 " ns\n"
                        "         app phase: %9" PRId64 " ns\t         SF phase: %9" PRId64 " ns\n"
                        "   early app phase: %9" PRId64 " ns\t   early SF phase: %9" PRId64 " ns\n"
                        "   early app phase: %9" PRId64 " ns\t   early SF phase: %9" PRId64 " ns\n"
                        "GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n",
                        "GL early app phase: %9" PRId64 " ns\tGL early SF phase: %9" PRId64 " ns\n"
                        late.app, late.sf, early.app, early.sf, earlyGl.app, earlyGl.sf);
                        "threshold for next VSYNC: %" PRId64 " ns\n",
                        late.app, late.sf, early.app, early.sf, earlyGl.app, earlyGl.sf, threshold);
}
}


nsecs_t PhaseOffsets::getCurrentAppOffset() {
PhaseOffsets::Offsets PhaseOffsets::getDefaultOffsets(nsecs_t thresholdForNextVsync) {
    return getCurrentOffsets().late.app;
    const int64_t vsyncPhaseOffsetNs = sysprop::vsync_event_phase_offset_ns(1000000);
    const int64_t sfVsyncPhaseOffsetNs = sysprop::vsync_sf_event_phase_offset_ns(1000000);

    const auto earlySfOffsetNs = getProperty("debug.sf.early_phase_offset_ns");
    const auto earlyGlSfOffsetNs = getProperty("debug.sf.early_gl_phase_offset_ns");
    const auto earlyAppOffsetNs = getProperty("debug.sf.early_app_phase_offset_ns");
    const auto earlyGlAppOffsetNs = getProperty("debug.sf.early_gl_app_phase_offset_ns");

    return {{RefreshRateType::DEFAULT, earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs),
             earlyAppOffsetNs.value_or(vsyncPhaseOffsetNs)},

            {RefreshRateType::DEFAULT, earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs),
             earlyGlAppOffsetNs.value_or(vsyncPhaseOffsetNs)},

            {RefreshRateType::DEFAULT, sfVsyncPhaseOffsetNs, vsyncPhaseOffsetNs},

            thresholdForNextVsync};
}
}


nsecs_t PhaseOffsets::getCurrentSfOffset() {
PhaseOffsets::Offsets PhaseOffsets::getHighFpsOffsets(nsecs_t thresholdForNextVsync) {
    return getCurrentOffsets().late.sf;
    // TODO(b/122905996): Define these in device.mk.
    const int highFpsLateAppOffsetNs =
            getProperty("debug.sf.high_fps_late_app_phase_offset_ns").value_or(2000000);
    const int highFpsLateSfOffsetNs =
            getProperty("debug.sf.high_fps_late_sf_phase_offset_ns").value_or(1000000);

    const auto highFpsEarlySfOffsetNs = getProperty("debug.sf.high_fps_early_phase_offset_ns");
    const auto highFpsEarlyGlSfOffsetNs = getProperty("debug.sf.high_fps_early_gl_phase_offset_ns");
    const auto highFpsEarlyAppOffsetNs = getProperty("debug.sf.high_fps_early_app_phase_offset_ns");
    const auto highFpsEarlyGlAppOffsetNs =
            getProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns");

    return {{RefreshRateType::PERFORMANCE, highFpsEarlySfOffsetNs.value_or(highFpsLateSfOffsetNs),
             highFpsEarlyAppOffsetNs.value_or(highFpsLateAppOffsetNs)},

            {RefreshRateType::PERFORMANCE, highFpsEarlyGlSfOffsetNs.value_or(highFpsLateSfOffsetNs),
             highFpsEarlyGlAppOffsetNs.value_or(highFpsLateAppOffsetNs)},

            {RefreshRateType::PERFORMANCE, highFpsLateSfOffsetNs, highFpsLateAppOffsetNs},

            thresholdForNextVsync};
}
}


} // namespace impl
} // namespace impl
} // namespace scheduler
} // namespace android::scheduler
} // namespace android
+23 −29
Original line number Original line Diff line number Diff line
@@ -16,14 +16,12 @@


#pragma once
#pragma once


#include <cinttypes>
#include <unordered_map>
#include <unordered_map>


#include "RefreshRateConfigs.h"
#include "RefreshRateConfigs.h"
#include "VSyncModulator.h"
#include "VSyncModulator.h"


namespace android {
namespace android::scheduler {
namespace scheduler {


/*
/*
 * This class encapsulates offsets for different refresh rates. Depending
 * This class encapsulates offsets for different refresh rates. Depending
@@ -33,35 +31,33 @@ namespace scheduler {
 */
 */
class PhaseOffsets {
class PhaseOffsets {
public:
public:
    struct Offsets {
    using Offsets = VSyncModulator::OffsetsConfig;
        VSyncModulator::Offsets early;
    using RefreshRateType = RefreshRateConfigs::RefreshRateType;
        VSyncModulator::Offsets earlyGl;
        VSyncModulator::Offsets late;
    };


    virtual ~PhaseOffsets();
    virtual ~PhaseOffsets();


    virtual nsecs_t getCurrentAppOffset() = 0;
    nsecs_t getCurrentAppOffset() const { return getCurrentOffsets().late.app; }
    virtual nsecs_t getCurrentSfOffset() = 0;
    nsecs_t getCurrentSfOffset() const { return getCurrentOffsets().late.sf; }
    virtual Offsets getOffsetsForRefreshRate(
    nsecs_t getOffsetThresholdForNextVsync() const {
            RefreshRateConfigs::RefreshRateType refreshRateType) const = 0;
        return getCurrentOffsets().thresholdForNextVsync;
    }

    virtual Offsets getCurrentOffsets() const = 0;
    virtual Offsets getCurrentOffsets() const = 0;
    virtual void setRefreshRateType(RefreshRateConfigs::RefreshRateType refreshRateType) = 0;
    virtual Offsets getOffsetsForRefreshRate(RefreshRateType) const = 0;
    virtual nsecs_t getOffsetThresholdForNextVsync() const = 0;

    virtual void setRefreshRateType(RefreshRateType) = 0;

    virtual void dump(std::string& result) const = 0;
    virtual void dump(std::string& result) const = 0;
};
};


namespace impl {
namespace impl {

class PhaseOffsets : public scheduler::PhaseOffsets {
class PhaseOffsets : public scheduler::PhaseOffsets {
public:
public:
    PhaseOffsets();
    PhaseOffsets();


    nsecs_t getCurrentAppOffset() override;
    nsecs_t getCurrentSfOffset() override;

    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
    Offsets getOffsetsForRefreshRate(
    Offsets getOffsetsForRefreshRate(RefreshRateType) const override;
            RefreshRateConfigs::RefreshRateType refreshRateType) const override;


    // Returns early, early GL, and late offsets for Apps and SF.
    // Returns early, early GL, and late offsets for Apps and SF.
    Offsets getCurrentOffsets() const override {
    Offsets getCurrentOffsets() const override {
@@ -70,23 +66,21 @@ public:


    // This function should be called when the device is switching between different
    // This function should be called when the device is switching between different
    // refresh rates, to properly update the offsets.
    // refresh rates, to properly update the offsets.
    void setRefreshRateType(RefreshRateConfigs::RefreshRateType refreshRateType) override {
    void setRefreshRateType(RefreshRateType refreshRateType) override {
        mRefreshRateType = refreshRateType;
        mRefreshRateType = refreshRateType;
    }
    }


    nsecs_t getOffsetThresholdForNextVsync() const override { return mOffsetThresholdForNextVsync; }

    // Returns current offsets in human friendly format.
    // Returns current offsets in human friendly format.
    void dump(std::string& result) const override;
    void dump(std::string& result) const override;


private:
private:
    std::atomic<RefreshRateConfigs::RefreshRateType> mRefreshRateType =
    static Offsets getDefaultOffsets(nsecs_t thresholdForNextVsync);
            RefreshRateConfigs::RefreshRateType::DEFAULT;
    static Offsets getHighFpsOffsets(nsecs_t thresholdForNextVsync);

    std::atomic<RefreshRateType> mRefreshRateType = RefreshRateType::DEFAULT;


    std::unordered_map<RefreshRateConfigs::RefreshRateType, Offsets> mOffsets;
    std::unordered_map<RefreshRateType, Offsets> mOffsets;
    nsecs_t mOffsetThresholdForNextVsync;
};
};
} // namespace impl


} // namespace scheduler
} // namespace impl
} // namespace android
} // namespace android::scheduler
+35 −48
Original line number Original line Diff line number Diff line
@@ -24,25 +24,24 @@
#include <cinttypes>
#include <cinttypes>
#include <mutex>
#include <mutex>


namespace android {
namespace android::scheduler {


using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType;
VSyncModulator::VSyncModulator(Scheduler& scheduler,
VSyncModulator::VSyncModulator() {
                               const sp<Scheduler::ConnectionHandle>& appConnectionHandle,
                               const sp<Scheduler::ConnectionHandle>& sfConnectionHandle,
                               const OffsetsConfig& config)
      : mScheduler(scheduler),
        mAppConnectionHandle(appConnectionHandle),
        mSfConnectionHandle(sfConnectionHandle),
        mOffsetsConfig(config) {
    char value[PROPERTY_VALUE_MAX];
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.sf.vsync_trace_detailed_info", value, "0");
    property_get("debug.sf.vsync_trace_detailed_info", value, "0");
    mTraceDetailedInfo = atoi(value);
    mTraceDetailedInfo = atoi(value);
    // Populate the offset map with some default offsets.
    const Offsets defaultOffsets = {RefreshRateType::DEFAULT, 0, 0};
    setPhaseOffsets(defaultOffsets, defaultOffsets, defaultOffsets, 0);
}
}


void VSyncModulator::setPhaseOffsets(Offsets early, Offsets earlyGl, Offsets late,
void VSyncModulator::setPhaseOffsets(const OffsetsConfig& config) {
                                     nsecs_t thresholdForNextVsync) {
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);
    mOffsetMap.insert_or_assign(OffsetType::Early, early);
    mOffsetsConfig = config;
    mOffsetMap.insert_or_assign(OffsetType::EarlyGl, earlyGl);
    mOffsetMap.insert_or_assign(OffsetType::Late, late);
    mThresholdForNextVsync = thresholdForNextVsync;
    updateOffsetsLocked();
    updateOffsetsLocked();
}
}


@@ -100,25 +99,21 @@ void VSyncModulator::onRefreshed(bool usedRenderEngine) {
    }
    }
}
}


VSyncModulator::Offsets VSyncModulator::getOffsets() {
VSyncModulator::Offsets VSyncModulator::getOffsets() const {
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);
    return mOffsets;
    return mOffsets;
}
}


VSyncModulator::Offsets VSyncModulator::getNextOffsets() {
const VSyncModulator::Offsets& VSyncModulator::getNextOffsets() const {
    return mOffsetMap.at(getNextOffsetType());
}

VSyncModulator::OffsetType VSyncModulator::getNextOffsetType() {
    // Early offsets are used if we're in the middle of a refresh rate
    // Early offsets are used if we're in the middle of a refresh rate
    // change, or if we recently begin a transaction.
    // change, or if we recently begin a transaction.
    if (mTransactionStart == Scheduler::TransactionStart::EARLY || mRemainingEarlyFrameCount > 0 ||
    if (mTransactionStart == Scheduler::TransactionStart::EARLY || mRemainingEarlyFrameCount > 0 ||
        mRefreshRateChangePending) {
        mRefreshRateChangePending) {
        return OffsetType::Early;
        return mOffsetsConfig.early;
    } else if (mRemainingRenderEngineUsageCount > 0) {
    } else if (mRemainingRenderEngineUsageCount > 0) {
        return OffsetType::EarlyGl;
        return mOffsetsConfig.earlyGl;
    } else {
    } else {
        return OffsetType::Late;
        return mOffsetsConfig.late;
    }
    }
}
}


@@ -128,37 +123,29 @@ void VSyncModulator::updateOffsets() {
}
}


void VSyncModulator::updateOffsetsLocked() {
void VSyncModulator::updateOffsetsLocked() {
    const Offsets desired = getNextOffsets();
    const Offsets& offsets = getNextOffsets();


    if (mSfConnectionHandle != nullptr) {
    mScheduler.setPhaseOffset(mSfConnectionHandle, offsets.sf);
        mScheduler->setPhaseOffset(mSfConnectionHandle, desired.sf);
    mScheduler.setPhaseOffset(mAppConnectionHandle, offsets.app);
    }


    if (mAppConnectionHandle != nullptr) {
    mOffsets = offsets;
        mScheduler->setPhaseOffset(mAppConnectionHandle, desired.app);
    }


    flushOffsets();
}

void VSyncModulator::flushOffsets() {
    OffsetType type = getNextOffsetType();
    mOffsets = mOffsetMap.at(type);
    if (!mTraceDetailedInfo) {
    if (!mTraceDetailedInfo) {
        return;
        return;
    }
    }
    ATRACE_INT("Vsync-EarlyOffsetsOn",

               mOffsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::Early);
    const bool isDefault = mOffsets.fpsMode == RefreshRateType::DEFAULT;
    ATRACE_INT("Vsync-EarlyGLOffsetsOn",
    const bool isPerformance = mOffsets.fpsMode == RefreshRateType::PERFORMANCE;
               mOffsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::EarlyGl);
    const bool isEarly = &offsets == &mOffsetsConfig.early;
    ATRACE_INT("Vsync-LateOffsetsOn",
    const bool isEarlyGl = &offsets == &mOffsetsConfig.earlyGl;
               mOffsets.fpsMode == RefreshRateType::DEFAULT && type == OffsetType::Late);
    const bool isLate = &offsets == &mOffsetsConfig.late;
    ATRACE_INT("Vsync-HighFpsEarlyOffsetsOn",

               mOffsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::Early);
    ATRACE_INT("Vsync-EarlyOffsetsOn", isDefault && isEarly);
    ATRACE_INT("Vsync-HighFpsEarlyGLOffsetsOn",
    ATRACE_INT("Vsync-EarlyGLOffsetsOn", isDefault && isEarlyGl);
               mOffsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::EarlyGl);
    ATRACE_INT("Vsync-LateOffsetsOn", isDefault && isLate);
    ATRACE_INT("Vsync-HighFpsLateOffsetsOn",
    ATRACE_INT("Vsync-HighFpsEarlyOffsetsOn", isPerformance && isEarly);
               mOffsets.fpsMode == RefreshRateType::PERFORMANCE && type == OffsetType::Late);
    ATRACE_INT("Vsync-HighFpsEarlyGLOffsetsOn", isPerformance && isEarlyGl);
}
    ATRACE_INT("Vsync-HighFpsLateOffsetsOn", isPerformance && isLate);

}
} // namespace android

} // namespace android::scheduler
+26 −47
Original line number Original line Diff line number Diff line
@@ -16,12 +16,11 @@


#pragma once
#pragma once


#include <cinttypes>
#include <mutex>
#include <mutex>


#include "Scheduler.h"
#include "Scheduler.h"


namespace android {
namespace android::scheduler {


/*
/*
 * Modulates the vsync-offsets depending on current SurfaceFlinger state.
 * Modulates the vsync-offsets depending on current SurfaceFlinger state.
@@ -31,51 +30,36 @@ private:
    // Number of frames we'll keep the early phase offsets once they are activated for a
    // Number of frames we'll keep the early phase offsets once they are activated for a
    // transaction. This acts as a low-pass filter in case the client isn't quick enough in
    // transaction. This acts as a low-pass filter in case the client isn't quick enough in
    // sending new transactions.
    // sending new transactions.
    const int MIN_EARLY_FRAME_COUNT_TRANSACTION = 2;
    static constexpr int MIN_EARLY_FRAME_COUNT_TRANSACTION = 2;


    // Number of frames we'll keep the early gl phase offsets once they are activated.
    // Number of frames we'll keep the early gl phase offsets once they are activated.
    // This acts as a low-pass filter to avoid scenarios where we rapidly
    // This acts as a low-pass filter to avoid scenarios where we rapidly
    // switch in and out of gl composition.
    // switch in and out of gl composition.
    const int MIN_EARLY_GL_FRAME_COUNT_TRANSACTION = 2;
    static constexpr int MIN_EARLY_GL_FRAME_COUNT_TRANSACTION = 2;


public:
    using RefreshRateType = RefreshRateConfigs::RefreshRateType;
    VSyncModulator();


public:
    // Wrapper for a collection of surfaceflinger/app offsets for a particular
    // Wrapper for a collection of surfaceflinger/app offsets for a particular
    // configuration.
    // configuration.
    struct Offsets {
    struct Offsets {
        scheduler::RefreshRateConfigs::RefreshRateType fpsMode;
        RefreshRateType fpsMode;
        nsecs_t sf;
        nsecs_t sf;
        nsecs_t app;
        nsecs_t app;
    };
    };


    enum class OffsetType {
    struct OffsetsConfig {
        Early,
        Offsets early;   // For transactions with the eEarlyWakeup flag.
        EarlyGl,
        Offsets earlyGl; // As above but while compositing with GL.
        Late,
        Offsets late;    // Default.

        nsecs_t thresholdForNextVsync;
    };
    };


    // Sets the phase offsets
    VSyncModulator(Scheduler&, const sp<Scheduler::ConnectionHandle>& appConnectionHandle,
    //
                   const sp<Scheduler::ConnectionHandle>& sfConnectionHandle, const OffsetsConfig&);
    // sfEarly: The phase offset when waking up SF early, which happens when marking a transaction

    //          as early. May be the same as late, in which case we don't shift offsets.
    void setPhaseOffsets(const OffsetsConfig&) EXCLUDES(mMutex);
    // sfEarlyGl: Like sfEarly, but only if we used GL composition. If we use both GL composition
    //            and the transaction was marked as early, we'll use sfEarly.
    // sfLate: The regular SF vsync phase offset.
    // appEarly: Like sfEarly, but for the app-vsync
    // appEarlyGl: Like sfEarlyGl, but for the app-vsync.
    // appLate: The regular app vsync phase offset.
    void setPhaseOffsets(Offsets early, Offsets earlyGl, Offsets late,
                         nsecs_t thresholdForNextVsync) EXCLUDES(mMutex);

    // Sets the scheduler and vsync connection handlers.
    void setSchedulerAndHandles(Scheduler* scheduler,
                                Scheduler::ConnectionHandle* appConnectionHandle,
                                Scheduler::ConnectionHandle* sfConnectionHandle) {
        mScheduler = scheduler;
        mAppConnectionHandle = appConnectionHandle;
        mSfConnectionHandle = sfConnectionHandle;
    }


    // Signals that a transaction has started, and changes offsets accordingly.
    // Signals that a transaction has started, and changes offsets accordingly.
    void setTransactionStart(Scheduler::TransactionStart transactionStart);
    void setTransactionStart(Scheduler::TransactionStart transactionStart);
@@ -98,28 +82,23 @@ public:
    void onRefreshed(bool usedRenderEngine);
    void onRefreshed(bool usedRenderEngine);


    // Returns the offsets that we are currently using
    // Returns the offsets that we are currently using
    Offsets getOffsets() EXCLUDES(mMutex);
    Offsets getOffsets() const EXCLUDES(mMutex);


private:
private:
    // Returns the next offsets that we should be using
    // Returns the next offsets that we should be using
    Offsets getNextOffsets() REQUIRES(mMutex);
    const Offsets& getNextOffsets() const REQUIRES(mMutex);
    // Returns the next offset type that we should use.
    OffsetType getNextOffsetType();
    // Updates offsets and persists them into the scheduler framework.
    // Updates offsets and persists them into the scheduler framework.
    void updateOffsets() EXCLUDES(mMutex);
    void updateOffsets() EXCLUDES(mMutex);
    void updateOffsetsLocked() REQUIRES(mMutex);
    void updateOffsetsLocked() REQUIRES(mMutex);
    // Updates the internal offsets and offset type.
    void flushOffsets() REQUIRES(mMutex);


    mutable std::mutex mMutex;
    Scheduler& mScheduler;
    std::unordered_map<OffsetType, Offsets> mOffsetMap GUARDED_BY(mMutex);
    const sp<Scheduler::ConnectionHandle> mAppConnectionHandle;
    nsecs_t mThresholdForNextVsync;
    const sp<Scheduler::ConnectionHandle> mSfConnectionHandle;


    Scheduler* mScheduler = nullptr;
    mutable std::mutex mMutex;
    Scheduler::ConnectionHandle* mAppConnectionHandle = nullptr;
    OffsetsConfig mOffsetsConfig GUARDED_BY(mMutex);
    Scheduler::ConnectionHandle* mSfConnectionHandle = nullptr;


    Offsets mOffsets GUARDED_BY(mMutex) = {Scheduler::RefreshRateType::DEFAULT, 0, 0};
    Offsets mOffsets GUARDED_BY(mMutex){mOffsetsConfig.late};


    std::atomic<Scheduler::TransactionStart> mTransactionStart =
    std::atomic<Scheduler::TransactionStart> mTransactionStart =
            Scheduler::TransactionStart::NORMAL;
            Scheduler::TransactionStart::NORMAL;
@@ -130,4 +109,4 @@ private:
    bool mTraceDetailedInfo = false;
    bool mTraceDetailedInfo = false;
};
};


} // namespace android
} // namespace android::scheduler
+18 −27

File changed.

Preview size limit exceeded, changes collapsed.

Loading