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

Commit 0525b4d6 authored by Steven Thomas's avatar Steven Thomas Committed by Android (Google) Code Review
Browse files

Merge "Adding support for the setFrameRate() API to SurfaceFlinger path"

parents 7c3eee06 540730af
Loading
Loading
Loading
Loading
+41 −1
Original line number Diff line number Diff line
@@ -43,6 +43,9 @@ namespace android::scheduler::impl {
namespace {

bool isLayerActive(const Layer& layer, const LayerInfo& info, nsecs_t threshold) {
    if (layer.getFrameRate() > .0f) {
        return layer.isVisible();
    }
    return layer.isVisible() && info.getLastUpdatedTime() >= threshold;
}

@@ -117,11 +120,32 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) {
                    // Layers should be organized by priority
                    ALOGD("Layer has priority: %d", priority);
                }
            }
        }
    }

    for (const auto& [weakLayer, info] : activeLayers()) {
        const bool recent = info->isRecentlyActive(now);
        auto layer = weakLayer.promote();
        // Only use the layer if the reference still exists.
        if (layer || CC_UNLIKELY(mTraceEnabled)) {
            float refreshRate = 0.f;
            // Default content refresh rate is only used when dealing with recent layers.
            if (recent) {
                refreshRate = info->getRefreshRate(now);
            }
            // Check if frame rate was set on layer.
            float frameRate = layer->getFrameRate();
            if (frameRate > 0.f) {
                // Override content detection refresh rate, if it was set.
                refreshRate = frameRate;
            }
            if (refreshRate > maxRefreshRate) {
                maxRefreshRate = refreshRate;
            }

            if (CC_UNLIKELY(mTraceEnabled)) {
                trace(activeLayer, std::round(refreshRate));
                trace(weakLayer, std::round(refreshRate));
            }
        }
    }
@@ -175,6 +199,22 @@ void LayerHistory::clear() {
    mActiveLayersEnd = 0;
}

bool LayerHistory::hasClientSpecifiedFrameRate() {
    std::lock_guard lock(mLock);
    for (const auto& [weakLayer, info] : activeLayers()) {
        auto layer = weakLayer.promote();
        if (layer) {
            float frameRate = layer->getFrameRate();
            // Found a layer that has a frame rate set on it.
            if (fabs(frameRate) > 0.f) {
                return true;
            }
        }
    }
    // Did not find any layers that have frame rate.
    return false;
}

} // namespace android::scheduler::impl

// TODO(b/129481165): remove the #pragma below and fix conversion issues
+7 −0
Original line number Diff line number Diff line
@@ -53,6 +53,9 @@ public:
    virtual Summary summarize(nsecs_t now) = 0;

    virtual void clear() = 0;

    // Checks whether any of the active layers have a desired frame rate bit set on them.
    virtual bool hasClientSpecifiedFrameRate() = 0;
};

namespace impl {
@@ -75,6 +78,10 @@ public:

    void clear() override;

    // Traverses all active layers and checks whether any of them have a desired frame
    // rate bit set on them.
    bool hasClientSpecifiedFrameRate() override;

private:
    friend class android::scheduler::LayerHistoryTest;
    friend TestableScheduler;
+34 −26
Original line number Diff line number Diff line
@@ -422,6 +422,13 @@ void Scheduler::resetIdleTimer() {
}

void Scheduler::notifyTouchEvent() {
    // Touch event will boost the refresh rate to performance.
    // Clear Layer History to get fresh FPS detection.
    // NOTE: Instead of checking all the layers, we should be checking the layer
    // that is currently on top. b/142507166 will give us this capability.
    if (mLayerHistory && !mLayerHistory->hasClientSpecifiedFrameRate()) {
        mLayerHistory->clear();

        if (mTouchTimer) {
            mTouchTimer->reset();
        }
@@ -429,11 +436,6 @@ void Scheduler::notifyTouchEvent() {
        if (mSupportKernelTimer && mIdleTimer) {
            mIdleTimer->reset();
        }

    // Touch event will boost the refresh rate to performance.
    // Clear Layer History to get fresh FPS detection
    if (mLayerHistory) {
        mLayerHistory->clear();
    }
}

@@ -533,9 +535,14 @@ HwcConfigIndexType Scheduler::calculateRefreshRateType() {
        return mRefreshRateConfigs.getCurrentRefreshRate().configId;
    }

    // If the layer history doesn't have the frame rate specified, use the old path. NOTE:
    // if we remove the kernel idle timer, and use our internal idle timer, this code will have to
    // be refactored.
    if (!mLayerHistory->hasClientSpecifiedFrameRate()) {
        // If Display Power is not in normal operation we want to be in performance mode.
        // When coming back to normal mode, a grace period is given with DisplayPowerTimer
    if (!mFeatures.isDisplayPowerStateNormal || mFeatures.displayPowerTimer == TimerState::Reset) {
        if (!mFeatures.isDisplayPowerStateNormal ||
            mFeatures.displayPowerTimer == TimerState::Reset) {
            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
        }

@@ -553,6 +560,7 @@ HwcConfigIndexType Scheduler::calculateRefreshRateType() {
        if (mFeatures.contentDetection == ContentDetectionState::Off) {
            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
        }
    }

    // Content detection is on, find the appropriate refresh rate with minimal error
    return mRefreshRateConfigs