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

Commit d08178e5 authored by Rachel Lee's avatar Rachel Lee Committed by Android (Google) Code Review
Browse files

Merge "Non-visible layers are now "inactive"" into main

parents 7bb1d333 414f4080
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "LayerHistory.h"

#include <android-base/stringprintf.h>
#include <com_android_graphics_surfaceflinger_flags.h>
#include <cutils/properties.h>
#include <gui/TraceUtils.h>
#include <utils/Log.h>
@@ -39,8 +40,14 @@ namespace android::scheduler {

namespace {

using namespace com::android::graphics::surfaceflinger;

bool isLayerActive(const LayerInfo& info, nsecs_t threshold) {
    // Layers with an explicit frame rate or frame rate category are always kept active,
    if (flags::misc1() && !info.isVisible()) {
        return false;
    }

    // Layers with an explicit frame rate or frame rate category are kept active,
    // but ignore NoVote.
    if (info.getSetFrameRateVote().isValid() && !info.getSetFrameRateVote().isNoVote()) {
        return true;
+9 −6
Original line number Diff line number Diff line
@@ -304,12 +304,15 @@ LayerInfo::RefreshRateVotes LayerInfo::getRefreshRateVote(const RefreshRateSelec

    if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
        if (mLayerVote.category != FrameRateCategory::Default) {
            ATRACE_FORMAT_INSTANT("ExplicitCategory (%s)",
            const auto voteType = mLayerVote.type == LayerHistory::LayerVoteType::NoVote
                    ? LayerHistory::LayerVoteType::NoVote
                    : LayerHistory::LayerVoteType::ExplicitCategory;
            ATRACE_FORMAT_INSTANT("Vote %s (category=%s)", ftl::enum_string(voteType).c_str(),
                                  ftl::enum_string(mLayerVote.category).c_str());
            ALOGV("%s uses frame rate category: %d", mName.c_str(),
                  static_cast<int>(mLayerVote.category));
            votes.push_back({LayerHistory::LayerVoteType::ExplicitCategory, Fps(),
                             Seamlessness::Default, mLayerVote.category,
            ALOGV("%s voted %s with category: %s", mName.c_str(),
                  ftl::enum_string(voteType).c_str(),
                  ftl::enum_string(mLayerVote.category).c_str());
            votes.push_back({voteType, Fps(), Seamlessness::Default, mLayerVote.category,
                             mLayerVote.categorySmoothSwitchOnly});
        }

+0 −1
Original line number Diff line number Diff line
@@ -401,7 +401,6 @@ float RefreshRateSelector::calculateDistanceScoreFromMax(Fps refreshRate) const

float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate,
                                                     bool isSeamlessSwitch) const {
    ATRACE_CALL();
    // Slightly prefer seamless switches.
    constexpr float kSeamedSwitchPenalty = 0.95f;
    const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty;
+31 −1
Original line number Diff line number Diff line
@@ -18,12 +18,14 @@
#define LOG_TAG "LayerHistoryIntegrationTest"

#include <Layer.h>
#include <com_android_graphics_surfaceflinger_flags.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <log/log.h>

#include <renderengine/mock/FakeExternalTexture.h>

#include "FlagUtils.h"
#include "FpsOps.h"
#include "LayerHierarchyTest.h"
#include "Scheduler/LayerHistory.h"
@@ -36,6 +38,7 @@
namespace android::scheduler {

using android::mock::createDisplayMode;
using namespace com::android::graphics::surfaceflinger;

class LayerHistoryIntegrationTest : public surfaceflinger::frontend::LayerSnapshotTestBase {
protected:
@@ -492,7 +495,9 @@ TEST_F(LayerHistoryIntegrationTest, inactiveLayers) {
    EXPECT_EQ(1, frequentLayerCount(time));
}

TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayer) {
TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayerIsActive) {
    SET_FLAG_FOR_TEST(flags::misc1, false);

    auto explicitVisiblelayer = createLegacyAndFrontedEndLayer(1);
    auto explicitInvisiblelayer = createLegacyAndFrontedEndLayer(2);
    hideLayer(2);
@@ -515,6 +520,31 @@ TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayer) {
    EXPECT_EQ(2, frequentLayerCount(time));
}

TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayerIsNotActive) {
    SET_FLAG_FOR_TEST(flags::misc1, true);

    auto explicitVisiblelayer = createLegacyAndFrontedEndLayer(1);
    auto explicitInvisiblelayer = createLegacyAndFrontedEndLayer(2);
    hideLayer(2);
    setFrameRate(1, 60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
                 ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
    setFrameRate(2, 90.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
                 ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
    nsecs_t time = systemTime();

    // Post a buffer to the layers to make them active
    setBufferWithPresentTime(explicitVisiblelayer, time);
    setBufferWithPresentTime(explicitInvisiblelayer, time);

    EXPECT_EQ(2u, layerCount());
    ASSERT_EQ(1u, summarizeLayerHistory(time).size());
    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
              summarizeLayerHistory(time)[0].vote);
    EXPECT_EQ(60_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
    EXPECT_EQ(1u, activeLayerCount());
    EXPECT_EQ(1, frequentLayerCount(time));
}

TEST_F(LayerHistoryIntegrationTest, infrequentAnimatingLayer) {
    auto layer = createLegacyAndFrontedEndLayer(1);

+66 −0
Original line number Diff line number Diff line
@@ -22,10 +22,12 @@
#define LOG_TAG "LayerHistoryTest"

#include <Layer.h>
#include <com_android_graphics_surfaceflinger_flags.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <log/log.h>

#include "FlagUtils.h"
#include "FpsOps.h"
#include "Scheduler/LayerHistory.h"
#include "Scheduler/LayerInfo.h"
@@ -149,6 +151,8 @@ protected:

namespace {

using namespace com::android::graphics::surfaceflinger;

TEST_F(LayerHistoryTest, singleLayerNoVoteDefaultCompatibility) {
    const auto layer = createLayer();
    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
@@ -555,6 +559,33 @@ TEST_F(LayerHistoryTest, oneLayerExplicitVoteWithCategory) {
    EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[0].frameRateCategory);
}

TEST_F(LayerHistoryTest, oneLayerExplicitVoteWithCategoryNotVisibleDoesNotVote) {
    SET_FLAG_FOR_TEST(flags::misc1, true);

    auto layer = createLayer();
    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false));
    EXPECT_CALL(*layer, getFrameRateForLayerTree())
            .WillRepeatedly(
                    Return(Layer::FrameRate(12.34_Hz, Layer::FrameRateCompatibility::Default,
                                            Seamlessness::OnlySeamless, FrameRateCategory::High)));

    EXPECT_EQ(1, layerCount());
    EXPECT_EQ(0, activeLayerCount());

    nsecs_t time = systemTime();
    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
        history().record(layer->getSequence(), layer->getLayerProps(), time, time,
                         LayerHistory::LayerUpdateType::Buffer);
        time += HI_FPS_PERIOD;
    }

    // Layer is not visible, so the layer is moved to inactive, infrequent, and it will not have
    // votes to consider for refresh rate selection.
    ASSERT_EQ(0, summarizeLayerHistory(time).size());
    EXPECT_EQ(0, activeLayerCount());
    EXPECT_EQ(0, frequentLayerCount(time));
}

TEST_F(LayerHistoryTest, multipleLayers) {
    auto layer1 = createLayer("A");
    auto layer2 = createLayer("B");
@@ -780,6 +811,8 @@ TEST_F(LayerHistoryTest, inactiveLayers) {
}

TEST_F(LayerHistoryTest, invisibleExplicitLayer) {
    SET_FLAG_FOR_TEST(flags::misc1, false);

    auto explicitVisiblelayer = createLayer();
    auto explicitInvisiblelayer = createLayer();

@@ -810,6 +843,39 @@ TEST_F(LayerHistoryTest, invisibleExplicitLayer) {
    EXPECT_EQ(2, frequentLayerCount(time));
}

TEST_F(LayerHistoryTest, invisibleExplicitLayerDoesNotVote) {
    SET_FLAG_FOR_TEST(flags::misc1, true);

    auto explicitVisiblelayer = createLayer();
    auto explicitInvisiblelayer = createLayer();

    EXPECT_CALL(*explicitVisiblelayer, isVisible()).WillRepeatedly(Return(true));
    EXPECT_CALL(*explicitVisiblelayer, getFrameRateForLayerTree())
            .WillRepeatedly(Return(
                    Layer::FrameRate(60_Hz, Layer::FrameRateCompatibility::ExactOrMultiple)));

    EXPECT_CALL(*explicitInvisiblelayer, isVisible()).WillRepeatedly(Return(false));
    EXPECT_CALL(*explicitInvisiblelayer, getFrameRateForLayerTree())
            .WillRepeatedly(Return(
                    Layer::FrameRate(90_Hz, Layer::FrameRateCompatibility::ExactOrMultiple)));

    nsecs_t time = systemTime();

    // Post a buffer to the layers to make them active
    history().record(explicitVisiblelayer->getSequence(), explicitVisiblelayer->getLayerProps(),
                     time, time, LayerHistory::LayerUpdateType::Buffer);
    history().record(explicitInvisiblelayer->getSequence(), explicitInvisiblelayer->getLayerProps(),
                     time, time, LayerHistory::LayerUpdateType::Buffer);

    EXPECT_EQ(2, layerCount());
    ASSERT_EQ(1, summarizeLayerHistory(time).size());
    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
              summarizeLayerHistory(time)[0].vote);
    EXPECT_EQ(60_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
    EXPECT_EQ(1, activeLayerCount());
    EXPECT_EQ(1, frequentLayerCount(time));
}

TEST_F(LayerHistoryTest, infrequentAnimatingLayer) {
    auto layer = createLayer();

Loading