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

Commit 4ad8b30f authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

SF: Use default minimal refresh rate between frames

When calculating duplicate frames make sure the minimal period
is at least Fps(120).toPeriodNsecs(). It's not okay to use
min period equal to the max refresh rate at layer creation,
because the supported refresh rates can change. E.g. initially
it can be 24hz and later (bacause another display is plugged)
it can be 60hz, which will cause a lot of frames to be considered
as duplicates.

Bug: 159590486
Test: presubmit
Change-Id: I4424c05012925273ed6ea8254fb975bf8fe7d058
parent ea25ddfe
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -86,9 +86,8 @@ LayerHistory::LayerHistory(const RefreshRateConfigs& refreshRateConfigs)

LayerHistory::~LayerHistory() = default;

void LayerHistory::registerLayer(Layer* layer, Fps highRefreshRate, LayerVoteType type) {
    const nsecs_t highRefreshRatePeriod = highRefreshRate.getPeriodNsecs();
    auto info = std::make_unique<LayerInfo>(layer->getName(), highRefreshRatePeriod, type);
void LayerHistory::registerLayer(Layer* layer, LayerVoteType type) {
    auto info = std::make_unique<LayerInfo>(layer->getName(), type);
    std::lock_guard lock(mLock);
    mLayerInfos.emplace_back(layer, std::move(info));
}
+1 −1
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ public:
    ~LayerHistory();

    // Layers are unregistered when the weak reference expires.
    void registerLayer(Layer*, Fps highRefreshRate, LayerVoteType type);
    void registerLayer(Layer*, LayerVoteType type);

    // Sets the display size. Client is responsible for synchronization.
    void setDisplayArea(uint32_t displayArea) { mDisplayArea = displayArea; }
+3 −5
Original line number Diff line number Diff line
@@ -33,10 +33,8 @@ namespace android::scheduler {
const RefreshRateConfigs* LayerInfo::sRefreshRateConfigs = nullptr;
bool LayerInfo::sTraceEnabled = false;

LayerInfo::LayerInfo(const std::string& name, nsecs_t highRefreshRatePeriod,
                     LayerHistory::LayerVoteType defaultVote)
LayerInfo::LayerInfo(const std::string& name, LayerHistory::LayerVoteType defaultVote)
      : mName(name),
        mHighRefreshRatePeriod(highRefreshRatePeriod),
        mDefaultVote(defaultVote),
        mLayerVote({defaultVote, Fps(0.0f)}),
        mRefreshRateHistory(name) {}
@@ -133,7 +131,7 @@ std::optional<nsecs_t> LayerInfo::calculateAverageFrameTime() const {
        }

        totalQueueTimeDeltas +=
                std::max(((it + 1)->queueTime - it->queueTime), mHighRefreshRatePeriod);
                std::max(((it + 1)->queueTime - it->queueTime), kMinPeriodBetweenFrames);
        numFrames++;

        if (!missingPresentTime && (it->presetTime == 0 || (it + 1)->presetTime == 0)) {
@@ -147,7 +145,7 @@ std::optional<nsecs_t> LayerInfo::calculateAverageFrameTime() const {
        }

        totalPresentTimeDeltas +=
                std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
                std::max(((it + 1)->presetTime - it->presetTime), kMinPeriodBetweenFrames);
    }

    // Calculate the average frame time based on presentation timestamps. If those
+4 −4
Original line number Diff line number Diff line
@@ -70,8 +70,7 @@ public:
        sRefreshRateConfigs = &refreshRateConfigs;
    }

    LayerInfo(const std::string& name, nsecs_t highRefreshRatePeriod,
              LayerHistory::LayerVoteType defaultVote);
    LayerInfo(const std::string& name, LayerHistory::LayerVoteType defaultVote);

    LayerInfo(const LayerInfo&) = delete;
    LayerInfo& operator=(const LayerInfo&) = delete;
@@ -194,8 +193,9 @@ private:

    const std::string mName;

    // Used for sanitizing the heuristic data
    const nsecs_t mHighRefreshRatePeriod;
    // Used for sanitizing the heuristic data. If two frames are less than
    // this period apart from each other they'll be considered as duplicates.
    static constexpr nsecs_t kMinPeriodBetweenFrames = Fps(120.f).getPeriodNsecs();
    LayerHistory::LayerVoteType mDefaultVote;

    LayerVote mLayerVote;
+4 −8
Original line number Diff line number Diff line
@@ -551,23 +551,19 @@ void Scheduler::setIgnorePresentFences(bool ignore) {
void Scheduler::registerLayer(Layer* layer) {
    if (!mLayerHistory) return;

    const auto maxFps = mRefreshRateConfigs.getMaxRefreshRate().getFps();

    if (layer->getWindowType() == InputWindowInfo::Type::STATUS_BAR) {
        mLayerHistory->registerLayer(layer, maxFps, scheduler::LayerHistory::LayerVoteType::NoVote);
        mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::NoVote);
    } else if (!mOptions.useContentDetection) {
        // If the content detection feature is off, all layers are registered at Max. We still keep
        // the layer history, since we use it for other features (like Frame Rate API), so layers
        // still need to be registered.
        mLayerHistory->registerLayer(layer, maxFps, scheduler::LayerHistory::LayerVoteType::Max);
        mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::Max);
    } else {
        if (layer->getWindowType() == InputWindowInfo::Type::WALLPAPER) {
            // Running Wallpaper at Min is considered as part of content detection.
            mLayerHistory->registerLayer(layer, maxFps,
                                         scheduler::LayerHistory::LayerVoteType::Min);
            mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::Min);
        } else {
            mLayerHistory->registerLayer(layer, maxFps,
                                         scheduler::LayerHistory::LayerVoteType::Heuristic);
            mLayerHistory->registerLayer(layer, scheduler::LayerHistory::LayerVoteType::Heuristic);
        }
    }
}