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

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

Merge "SurfaceFlinger: fix calculation issues with refresh rate selection"

parents 90f78f21 f6b77071
Loading
Loading
Loading
Loading
+48 −48
Original line number Original line Diff line number Diff line
@@ -84,8 +84,8 @@ static status_t getProcessName(int pid, String8& name) {
    return INVALID_OPERATION;
    return INVALID_OPERATION;
}
}


BufferQueueCore::BufferQueueCore() :
BufferQueueCore::BufferQueueCore()
    mMutex(),
      : mMutex(),
        mIsAbandoned(false),
        mIsAbandoned(false),
        mConsumerControlledByApp(false),
        mConsumerControlledByApp(false),
        mConsumerName(getUniqueName()),
        mConsumerName(getUniqueName()),
@@ -130,8 +130,8 @@ BufferQueueCore::BufferQueueCore() :
        mLastQueuedSlot(INVALID_BUFFER_SLOT),
        mLastQueuedSlot(INVALID_BUFFER_SLOT),
        mUniqueId(getUniqueId()),
        mUniqueId(getUniqueId()),
        mAutoPrerotation(false),
        mAutoPrerotation(false),
    mTransformHintInUse(0)
        mTransformHintInUse(0),
{
        mFrameRate(0) {
    int numStartingBuffers = getMaxBufferCountLocked();
    int numStartingBuffers = getMaxBufferCountLocked();
    for (int s = 0; s < numStartingBuffers; s++) {
    for (int s = 0; s < numStartingBuffers; s++) {
        mFreeSlots.insert(s);
        mFreeSlots.insert(s);
+4 −2
Original line number Original line Diff line number Diff line
@@ -130,8 +130,10 @@ bool BufferQueueLayer::setFrameRate(float frameRate) {
}
}


std::optional<float> BufferQueueLayer::getFrameRate() const {
std::optional<float> BufferQueueLayer::getFrameRate() const {
    if (mLatchedFrameRate > 0.f || mLatchedFrameRate == FRAME_RATE_NO_VOTE)
    const auto frameRate = mLatchedFrameRate.load();
        return mLatchedFrameRate;
    if (frameRate > 0.f || frameRate == FRAME_RATE_NO_VOTE) {
        return frameRate;
    }


    return {};
    return {};
}
}
+2 −3
Original line number Original line Diff line number Diff line
@@ -57,7 +57,7 @@ bool LayerInfoV2::isRecentlyActive(nsecs_t now) const {
bool LayerInfoV2::isFrequent(nsecs_t now) const {
bool LayerInfoV2::isFrequent(nsecs_t now) const {
    // Assume layer is infrequent if too few present times have been recorded.
    // Assume layer is infrequent if too few present times have been recorded.
    if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) {
    if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) {
        return true;
        return false;
    }
    }


    // Layer is frequent if the earliest value in the window of most recent present times is
    // Layer is frequent if the earliest value in the window of most recent present times is
@@ -100,8 +100,7 @@ std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible() {
            static_cast<float>(totalPresentTimeDeltas) / (mFrameTimes.size() - 1);
            static_cast<float>(totalPresentTimeDeltas) / (mFrameTimes.size() - 1);


    // Now once we calculated the refresh rate we need to make sure that all the frames we captured
    // Now once we calculated the refresh rate we need to make sure that all the frames we captured
    // are evenly distrubuted and we don't calculate the average across some burst of frames.
    // are evenly distributed and we don't calculate the average across some burst of frames.

    for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) {
    for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) {
        const nsecs_t presentTimeDeltas =
        const nsecs_t presentTimeDeltas =
                std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
                std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
+8 −5
Original line number Original line Diff line number Diff line
@@ -125,12 +125,13 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2(
    }
    }


    for (const auto& layer : layers) {
    for (const auto& layer : layers) {
        ALOGV("Calculating score for %s (type: %d)", layer.name.c_str(), layer.vote);
        if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min ||
        if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min ||
            layer.vote == LayerVoteType::Max) {
            layer.vote == LayerVoteType::Max) {
            continue;
            continue;
        }
        }


        // If we have Explicit layers, ignore the Huristic ones
        // If we have Explicit layers, ignore the Hueristic ones
        if (explicitVoteLayers > 0 && layer.vote == LayerVoteType::Heuristic) {
        if (explicitVoteLayers > 0 && layer.vote == LayerVoteType::Heuristic) {
            continue;
            continue;
        }
        }
@@ -148,24 +149,26 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2(
            }
            }


            float layerScore;
            float layerScore;
            static constexpr size_t MAX_FRAMES_TO_FIT = 10; // Stop calculating when score < 0.1
            if (displayFramesRem == 0) {
            if (displayFramesRem == 0) {
                // Layer desired refresh rate matches the display rate.
                // Layer desired refresh rate matches the display rate.
                layerScore = layer.weight * 1.0f;
                layerScore = layer.weight * 1.0f;
            } else if (displayFramesQuot == 0) {
            } else if (displayFramesQuot == 0) {
                // Layer desired refresh rate is higher the display rate.
                // Layer desired refresh rate is higher the display rate.
                layerScore = layer.weight * layerPeriod / displayPeriod;
                layerScore = layer.weight *
                        (static_cast<float>(layerPeriod) / static_cast<float>(displayPeriod)) *
                        (1.0f / (MAX_FRAMES_TO_FIT + 1));
            } else {
            } else {
                // Layer desired refresh rate is lower the display rate. Check how well it fits the
                // Layer desired refresh rate is lower the display rate. Check how well it fits the
                // cadence
                // cadence
                auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem));
                auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem));
                int iter = 2;
                int iter = 2;
                static constexpr size_t MAX_ITERATOR = 10; // Stop calculating when score < 0.1
                while (diff > MARGIN && iter < MAX_FRAMES_TO_FIT) {
                while (diff > MARGIN && iter < MAX_ITERATOR) {
                    diff = diff - (displayPeriod - diff);
                    diff = diff - (displayPeriod - diff);
                    iter++;
                    iter++;
                }
                }


                layerScore = layer.weight * 1.0f / iter;
                layerScore = layer.weight * (1.0f / iter);
            }
            }


            ALOGV("%s (weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(),
            ALOGV("%s (weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(),
+7 −2
Original line number Original line Diff line number Diff line
@@ -34,6 +34,7 @@ namespace android::scheduler {


class LayerHistoryTestV2 : public testing::Test {
class LayerHistoryTestV2 : public testing::Test {
protected:
protected:
    static constexpr auto FREQUENT_LAYER_WINDOW_SIZE = LayerInfoV2::FREQUENT_LAYER_WINDOW_SIZE;
    static constexpr auto PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE;
    static constexpr auto PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE;
    static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS;
    static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS;


@@ -105,7 +106,10 @@ TEST_F(LayerHistoryTestV2, oneLayer) {
    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
        history().record(layer.get(), 0, mTime);
        history().record(layer.get(), 0, mTime);
        ASSERT_EQ(1, history().summarize(mTime).size());
        ASSERT_EQ(1, history().summarize(mTime).size());
        EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(mTime)[0].vote);
        const auto expectedType = (i + 1 < FREQUENT_LAYER_WINDOW_SIZE)
                ? LayerHistory::LayerVoteType::Min
                : LayerHistory::LayerVoteType::Max;
        EXPECT_EQ(expectedType, history().summarize(mTime)[0].vote);
        EXPECT_EQ(1, activeLayerCount());
        EXPECT_EQ(1, activeLayerCount());
    }
    }


@@ -129,7 +133,8 @@ TEST_F(LayerHistoryTestV2, oneInvisibleLayer) {
    history().record(layer.get(), 0, mTime);
    history().record(layer.get(), 0, mTime);
    auto summary = history().summarize(mTime);
    auto summary = history().summarize(mTime);
    ASSERT_EQ(1, history().summarize(mTime).size());
    ASSERT_EQ(1, history().summarize(mTime).size());
    EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(mTime)[0].vote);
    // Layer is still considered inactive so we expect to get Min
    EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(mTime)[0].vote);
    EXPECT_EQ(1, activeLayerCount());
    EXPECT_EQ(1, activeLayerCount());


    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false));
    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false));
Loading