SF: add render frame rate to the scheduler
Schedule SF at the rate of the render frame rate instead of
the display refresh rate.
Test: SF unit tests
Bug: 257072060
Change-Id: Idaf9be5f25373d38c0ef6440f9f401dc90de7a91
diff --git a/services/surfaceflinger/tests/unittests/DisplayDevice_InitiateModeChange.cpp b/services/surfaceflinger/tests/unittests/DisplayDevice_InitiateModeChange.cpp
index 982b9ff..60ad7a3 100644
--- a/services/surfaceflinger/tests/unittests/DisplayDevice_InitiateModeChange.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayDevice_InitiateModeChange.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "LibSurfaceFlingerUnittests"
#include "DisplayTransactionTestHelpers.h"
+#include "mock/MockFrameRateMode.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -29,6 +30,7 @@
class InitiateModeChangeTest : public DisplayTransactionTest {
public:
+ using Action = DisplayDevice::DesiredActiveModeAction;
using Event = scheduler::DisplayModeEvent;
void SetUp() override {
@@ -56,31 +58,42 @@
static constexpr DisplayModeId kModeId90{1};
static constexpr DisplayModeId kModeId120{2};
- static inline const DisplayModePtr kMode60 = createDisplayMode(kModeId60, 60_Hz);
- static inline const DisplayModePtr kMode90 = createDisplayMode(kModeId90, 90_Hz);
- static inline const DisplayModePtr kMode120 = createDisplayMode(kModeId120, 120_Hz);
+ static inline const ftl::NonNull<DisplayModePtr> kMode60 =
+ ftl::as_non_null(createDisplayMode(kModeId60, 60_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode90 =
+ ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode120 =
+ ftl::as_non_null(createDisplayMode(kModeId120, 120_Hz));
};
TEST_F(InitiateModeChangeTest, setDesiredActiveMode_setCurrentMode) {
- EXPECT_FALSE(mDisplay->setDesiredActiveMode({kMode60, Event::None}));
+ EXPECT_EQ(Action::None,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{60_Hz, kMode60}, Event::None}));
EXPECT_EQ(std::nullopt, mDisplay->getDesiredActiveMode());
}
TEST_F(InitiateModeChangeTest, setDesiredActiveMode_setNewMode) {
- EXPECT_TRUE(mDisplay->setDesiredActiveMode({kMode90, Event::None}));
+ EXPECT_EQ(Action::InitiateDisplayModeSwitch,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{90_Hz, kMode90}, Event::None}));
ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
- EXPECT_EQ(kMode90, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, mDisplay->getDesiredActiveMode()->modeOpt);
EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
- // Setting another mode should be cached but return false
- EXPECT_FALSE(mDisplay->setDesiredActiveMode({kMode120, Event::None}));
+ // Setting another mode should be cached but return None
+ EXPECT_EQ(Action::None,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{120_Hz, kMode120}, Event::None}));
ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
- EXPECT_EQ(kMode120, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, mDisplay->getDesiredActiveMode()->modeOpt);
EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
}
TEST_F(InitiateModeChangeTest, clearDesiredActiveModeState) {
- EXPECT_TRUE(mDisplay->setDesiredActiveMode({kMode90, Event::None}));
+ EXPECT_EQ(Action::InitiateDisplayModeSwitch,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{90_Hz, kMode90}, Event::None}));
ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
mDisplay->clearDesiredActiveModeState();
@@ -88,9 +101,11 @@
}
TEST_F(InitiateModeChangeTest, initiateModeChange) NO_THREAD_SAFETY_ANALYSIS {
- EXPECT_TRUE(mDisplay->setDesiredActiveMode({kMode90, Event::None}));
+ EXPECT_EQ(Action::InitiateDisplayModeSwitch,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{90_Hz, kMode90}, Event::None}));
ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
- EXPECT_EQ(kMode90, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, mDisplay->getDesiredActiveMode()->modeOpt);
EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
hal::VsyncPeriodChangeConstraints constraints{
@@ -101,18 +116,27 @@
EXPECT_EQ(OK,
mDisplay->initiateModeChange(*mDisplay->getDesiredActiveMode(), constraints,
&timeline));
- EXPECT_EQ(kMode90, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, *mDisplay->getUpcomingActiveMode().modeOpt);
EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
mDisplay->clearDesiredActiveModeState();
ASSERT_EQ(std::nullopt, mDisplay->getDesiredActiveMode());
}
+TEST_F(InitiateModeChangeTest, initiateRenderRateChange) {
+ EXPECT_EQ(Action::InitiateRenderRateSwitch,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{30_Hz, kMode60}, Event::None}));
+ EXPECT_EQ(std::nullopt, mDisplay->getDesiredActiveMode());
+}
+
TEST_F(InitiateModeChangeTest, getUpcomingActiveMode_desiredActiveModeChanged)
NO_THREAD_SAFETY_ANALYSIS {
- EXPECT_TRUE(mDisplay->setDesiredActiveMode({kMode90, Event::None}));
+ EXPECT_EQ(Action::InitiateDisplayModeSwitch,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{90_Hz, kMode90}, Event::None}));
ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
- EXPECT_EQ(kMode90, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, mDisplay->getDesiredActiveMode()->modeOpt);
EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
hal::VsyncPeriodChangeConstraints constraints{
@@ -123,21 +147,23 @@
EXPECT_EQ(OK,
mDisplay->initiateModeChange(*mDisplay->getDesiredActiveMode(), constraints,
&timeline));
- EXPECT_EQ(kMode90, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, *mDisplay->getUpcomingActiveMode().modeOpt);
EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
- EXPECT_FALSE(mDisplay->setDesiredActiveMode({kMode120, Event::None}));
+ EXPECT_EQ(Action::None,
+ mDisplay->setDesiredActiveMode(
+ {scheduler::FrameRateMode{120_Hz, kMode120}, Event::None}));
ASSERT_NE(std::nullopt, mDisplay->getDesiredActiveMode());
- EXPECT_EQ(kMode120, mDisplay->getDesiredActiveMode()->mode);
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, mDisplay->getDesiredActiveMode()->modeOpt);
EXPECT_EQ(Event::None, mDisplay->getDesiredActiveMode()->event);
- EXPECT_EQ(kMode90, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, *mDisplay->getUpcomingActiveMode().modeOpt);
EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
EXPECT_EQ(OK,
mDisplay->initiateModeChange(*mDisplay->getDesiredActiveMode(), constraints,
&timeline));
- EXPECT_EQ(kMode120, mDisplay->getUpcomingActiveMode().mode);
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, *mDisplay->getUpcomingActiveMode().modeOpt);
EXPECT_EQ(Event::None, mDisplay->getUpcomingActiveMode().event);
mDisplay->clearDesiredActiveModeState();
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index 8757e63..fdf2ffe 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -31,6 +31,9 @@
#include "FpsOps.h"
#include "Scheduler/RefreshRateSelector.h"
#include "mock/DisplayHardware/MockDisplayMode.h"
+#include "mock/MockFrameRateMode.h"
+
+#include "libsurfaceflinger_unittest_main.h"
using namespace std::chrono_literals;
@@ -45,44 +48,41 @@
using mock::createDisplayMode;
-// Use a C style macro to keep the line numbers printed in gtest
-#define EXPECT_SCORED_FRAME_RATE(modePtr, fps, scored) \
- EXPECT_EQ((FrameRateMode{(fps), (modePtr)}), (scored).frameRateMode)
-
struct TestableRefreshRateSelector : RefreshRateSelector {
using RefreshRateSelector::FrameRateRanking;
using RefreshRateSelector::RefreshRateOrder;
using RefreshRateSelector::RefreshRateSelector;
- void setActiveModeId(DisplayModeId modeId) {
+ void setActiveMode(DisplayModeId modeId, Fps renderFrameRate) {
ftl::FakeGuard guard(kMainThreadContext);
- return RefreshRateSelector::setActiveModeId(modeId);
+ return RefreshRateSelector::setActiveMode(modeId, renderFrameRate);
}
const DisplayMode& getActiveMode() const {
- ftl::FakeGuard guard(kMainThreadContext);
- return RefreshRateSelector::getActiveMode();
+ std::lock_guard lock(mLock);
+ return *RefreshRateSelector::getActiveModeLocked().modePtr;
}
- DisplayModePtr getMinSupportedRefreshRate() const {
+ ftl::NonNull<DisplayModePtr> getMinSupportedRefreshRate() const {
std::lock_guard lock(mLock);
- return mMinRefreshRateModeIt->second;
+ return ftl::as_non_null(mMinRefreshRateModeIt->second);
}
- DisplayModePtr getMaxSupportedRefreshRate() const {
+ ftl::NonNull<DisplayModePtr> getMaxSupportedRefreshRate() const {
std::lock_guard lock(mLock);
- return mMaxRefreshRateModeIt->second;
+ return ftl::as_non_null(mMaxRefreshRateModeIt->second);
}
- DisplayModePtr getMinRefreshRateByPolicy() const {
+ ftl::NonNull<DisplayModePtr> getMinRefreshRateByPolicy() const {
std::lock_guard lock(mLock);
- return getMinRefreshRateByPolicyLocked();
+ return ftl::as_non_null(getMinRefreshRateByPolicyLocked());
}
- DisplayModePtr getMaxRefreshRateByPolicy() const {
+ ftl::NonNull<DisplayModePtr> getMaxRefreshRateByPolicy() const {
std::lock_guard lock(mLock);
- return getMaxRefreshRateByPolicyLocked(getActiveModeItLocked()->second->getGroup());
+ return ftl::as_non_null(
+ getMaxRefreshRateByPolicyLocked(getActiveModeLocked().modePtr->getGroup()));
}
FrameRateRanking rankRefreshRates(std::optional<int> anchorGroupOpt,
@@ -112,8 +112,8 @@
return std::make_pair(ranking, consideredSignals);
}
- DisplayModePtr getBestFrameRateMode(const std::vector<LayerRequirement>& layers = {},
- GlobalSignals signals = {}) const {
+ ftl::NonNull<DisplayModePtr> getBestFrameRateMode(
+ const std::vector<LayerRequirement>& layers = {}, GlobalSignals signals = {}) const {
return getRankedFrameRates(layers, signals).ranking.front().frameRateMode.modePtr;
}
@@ -154,25 +154,42 @@
static constexpr DisplayModeId kModeId60Frac{10};
static constexpr DisplayModeId kModeId35{11};
- static inline const DisplayModePtr kMode60 = createDisplayMode(kModeId60, 60_Hz);
- static inline const DisplayModePtr kMode60Frac = createDisplayMode(kModeId60Frac, 59.94_Hz);
- static inline const DisplayModePtr kMode90 = createDisplayMode(kModeId90, 90_Hz);
- static inline const DisplayModePtr kMode90_G1 = createDisplayMode(kModeId90, 90_Hz, 1);
- static inline const DisplayModePtr kMode90_4K =
- createDisplayMode(kModeId90, 90_Hz, 0, {3840, 2160});
- static inline const DisplayModePtr kMode72 = createDisplayMode(kModeId72, 72_Hz);
- static inline const DisplayModePtr kMode72_G1 = createDisplayMode(kModeId72, 72_Hz, 1);
- static inline const DisplayModePtr kMode120 = createDisplayMode(kModeId120, 120_Hz);
- static inline const DisplayModePtr kMode120_G1 = createDisplayMode(kModeId120, 120_Hz, 1);
- static inline const DisplayModePtr kMode30 = createDisplayMode(kModeId30, 30_Hz);
- static inline const DisplayModePtr kMode30_G1 = createDisplayMode(kModeId30, 30_Hz, 1);
- static inline const DisplayModePtr kMode30Frac = createDisplayMode(kModeId30Frac, 29.97_Hz);
- static inline const DisplayModePtr kMode25 = createDisplayMode(kModeId25, 25_Hz);
- static inline const DisplayModePtr kMode25_G1 = createDisplayMode(kModeId25, 25_Hz, 1);
- static inline const DisplayModePtr kMode35 = createDisplayMode(kModeId35, 35_Hz);
- static inline const DisplayModePtr kMode50 = createDisplayMode(kModeId50, 50_Hz);
- static inline const DisplayModePtr kMode24 = createDisplayMode(kModeId24, 24_Hz);
- static inline const DisplayModePtr kMode24Frac = createDisplayMode(kModeId24Frac, 23.976_Hz);
+ static inline const ftl::NonNull<DisplayModePtr> kMode60 =
+ ftl::as_non_null(createDisplayMode(kModeId60, 60_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode60Frac =
+ ftl::as_non_null(createDisplayMode(kModeId60Frac, 59.94_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode90 =
+ ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode90_G1 =
+ ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz, 1));
+ static inline const ftl::NonNull<DisplayModePtr> kMode90_4K =
+ ftl::as_non_null(createDisplayMode(kModeId90, 90_Hz, 0, {3840, 2160}));
+ static inline const ftl::NonNull<DisplayModePtr> kMode72 =
+ ftl::as_non_null(createDisplayMode(kModeId72, 72_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode72_G1 =
+ ftl::as_non_null(createDisplayMode(kModeId72, 72_Hz, 1));
+ static inline const ftl::NonNull<DisplayModePtr> kMode120 =
+ ftl::as_non_null(createDisplayMode(kModeId120, 120_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode120_G1 =
+ ftl::as_non_null(createDisplayMode(kModeId120, 120_Hz, 1));
+ static inline const ftl::NonNull<DisplayModePtr> kMode30 =
+ ftl::as_non_null(createDisplayMode(kModeId30, 30_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode30_G1 =
+ ftl::as_non_null(createDisplayMode(kModeId30, 30_Hz, 1));
+ static inline const ftl::NonNull<DisplayModePtr> kMode30Frac =
+ ftl::as_non_null(createDisplayMode(kModeId30Frac, 29.97_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode25 =
+ ftl::as_non_null(createDisplayMode(kModeId25, 25_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode25_G1 =
+ ftl::as_non_null(createDisplayMode(kModeId25, 25_Hz, 1));
+ static inline const ftl::NonNull<DisplayModePtr> kMode35 =
+ ftl::as_non_null(createDisplayMode(kModeId35, 35_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode50 =
+ ftl::as_non_null(createDisplayMode(kModeId50, 50_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode24 =
+ ftl::as_non_null(createDisplayMode(kModeId24, 24_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kMode24Frac =
+ ftl::as_non_null(createDisplayMode(kModeId24Frac, 23.976_Hz));
// Test configurations.
static inline const DisplayModes kModes_60 = makeModes(kMode60);
@@ -298,7 +315,7 @@
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
const auto minRate90 = selector.getMinRefreshRateByPolicy();
const auto performanceRate90 = selector.getMaxRefreshRateByPolicy();
@@ -322,7 +339,7 @@
EXPECT_EQ(SetPolicyResult::Changed,
selector.setDisplayManagerPolicy({kModeId90, {60_Hz, 90_Hz}}));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
const auto minRate90 = selector.getMinRefreshRateByPolicy();
const auto performanceRate90 = selector.getMaxRefreshRateByPolicy();
@@ -358,7 +375,7 @@
EXPECT_EQ(mode.getId(), kModeId60);
}
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
{
const auto& mode = selector.getActiveMode();
EXPECT_EQ(mode.getId(), kModeId90);
@@ -1805,7 +1822,7 @@
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
// Verify that we won't do a seamless switch if we request the same mode as the default
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
@@ -1826,7 +1843,7 @@
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
// Verify that if the active mode is in another group and there are no layers with
// Seamlessness::SeamedAndSeamless, we should switch back to the default group.
@@ -1850,7 +1867,7 @@
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
// If there's a layer with Seamlessness::SeamedAndSeamless, another layer with
// Seamlessness::OnlySeamless can't change the mode group.
@@ -1879,7 +1896,7 @@
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
// If there's a focused layer with Seamlessness::SeamedAndSeamless, another layer with
// Seamlessness::Default can't change the mode group back to the group of the default
@@ -1912,7 +1929,7 @@
policy.allowGroupSwitching = true;
EXPECT_EQ(SetPolicyResult::Changed, selector.setPolicy(policy));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
// Layer with Seamlessness::Default can change the mode group if there's an
// unfocused layer with Seamlessness::SeamedAndSeamless. For example, this happens
@@ -1953,7 +1970,7 @@
EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId());
- selector.setActiveModeId(kModeId120);
+ selector.setActiveMode(kModeId120, 120_Hz);
EXPECT_EQ(kModeId120, selector.getBestFrameRateMode(layers)->getId());
}
@@ -1984,7 +2001,7 @@
auto& seamedLayer = layers[0];
seamedLayer.desiredRefreshRate = 30_Hz;
seamedLayer.name = "30Hz ExplicitDefault";
- selector.setActiveModeId(kModeId30);
+ selector.setActiveMode(kModeId30, 30_Hz);
EXPECT_EQ(kModeId25, selector.getBestFrameRateMode(layers)->getId());
}
@@ -2102,7 +2119,7 @@
EXPECT_EQ(kModeId90, selector.getBestFrameRateMode({}, {.touch = true, .idle = true})->getId());
// Idle should be higher precedence than other layer frame rate considerations.
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
{
constexpr bool kTouchActive = false;
@@ -2142,7 +2159,7 @@
struct Expectation {
Fps fps;
- DisplayModePtr mode;
+ ftl::NonNull<DisplayModePtr> mode;
};
const std::initializer_list<Expectation> knownFrameRatesExpectations = {
@@ -2185,33 +2202,39 @@
explicitExactOrMultipleLayer.desiredRefreshRate = 60_Hz;
if (GetParam() == Config::FrameRateOverride::Disabled) {
- EXPECT_SCORED_FRAME_RATE(kMode30, 30_Hz, selector.getBestScoredFrameRate(layers));
- EXPECT_SCORED_FRAME_RATE(kMode30, 30_Hz,
- selector.getBestScoredFrameRate(layers, {.touch = true}));
+ EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz,
+ selector.getBestScoredFrameRate(layers).frameRateMode);
+ EXPECT_FRAME_RATE_MODE(kMode30, 30_Hz,
+ selector.getBestScoredFrameRate(layers, {.touch = true})
+ .frameRateMode);
} else {
- EXPECT_SCORED_FRAME_RATE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers));
- EXPECT_SCORED_FRAME_RATE(kMode120, 120_Hz,
- selector.getBestScoredFrameRate(layers, {.touch = true}));
+ EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz,
+ selector.getBestScoredFrameRate(layers).frameRateMode);
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz,
+ selector.getBestScoredFrameRate(layers, {.touch = true})
+ .frameRateMode);
}
explicitExactOrMultipleLayer.desiredRefreshRate = 120_Hz;
explicitExactLayer.desiredRefreshRate = 60_Hz;
if (GetParam() == Config::FrameRateOverride::Disabled) {
- EXPECT_SCORED_FRAME_RATE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz,
+ selector.getBestScoredFrameRate(layers).frameRateMode);
} else {
- EXPECT_SCORED_FRAME_RATE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz,
+ selector.getBestScoredFrameRate(layers).frameRateMode);
}
explicitExactLayer.desiredRefreshRate = 72_Hz;
- EXPECT_SCORED_FRAME_RATE(kMode72, 72_Hz, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode72, 72_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
explicitExactLayer.desiredRefreshRate = 90_Hz;
- EXPECT_SCORED_FRAME_RATE(kMode90, 90_Hz, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode90, 90_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
explicitExactLayer.desiredRefreshRate = 120_Hz;
- EXPECT_SCORED_FRAME_RATE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ReadsCache) {
@@ -2295,6 +2318,10 @@
// b/190578904
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withCloseRefreshRates) {
+ if (g_noSlowTests) {
+ GTEST_SKIP();
+ }
+
const int kMinRefreshRate = RefreshRateSelector::kMinSupportedFrameRate.getIntValue();
constexpr int kMaxRefreshRate = 240;
@@ -2409,23 +2436,23 @@
Fps displayRefreshRate = selector.getActiveMode().getFps();
EXPECT_EQ(1, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
- selector.setActiveModeId(kModeId60);
+ selector.setActiveMode(kModeId60, 60_Hz);
displayRefreshRate = selector.getActiveMode().getFps();
EXPECT_EQ(2, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
- selector.setActiveModeId(kModeId72);
+ selector.setActiveMode(kModeId72, 72_Hz);
displayRefreshRate = selector.getActiveMode().getFps();
EXPECT_EQ(0, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
displayRefreshRate = selector.getActiveMode().getFps();
EXPECT_EQ(3, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
- selector.setActiveModeId(kModeId120);
+ selector.setActiveMode(kModeId120, 120_Hz);
displayRefreshRate = selector.getActiveMode().getFps();
EXPECT_EQ(4, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, frameRate));
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
displayRefreshRate = selector.getActiveMode().getFps();
EXPECT_EQ(4, RefreshRateSelector::getFrameRateDivisor(displayRefreshRate, 22.5_Hz));
@@ -2808,7 +2835,7 @@
constexpr FpsRanges kAppRequest = {/*physical*/ k0_120Hz,
/*render*/ k0_120Hz};
- EXPECT_SCORED_FRAME_RATE(kMode120, 120_Hz, selector.getBestScoredFrameRate());
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate().frameRateMode);
{
constexpr FpsRanges kPrimary = {/*physical*/ k0_120Hz,
/*render*/ k0_120Hz};
@@ -2819,7 +2846,7 @@
/*appRequestRanges*/
kAppRequest}));
}
- EXPECT_SCORED_FRAME_RATE(kMode120, 120_Hz, selector.getBestScoredFrameRate());
+ EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate().frameRateMode);
{
constexpr FpsRanges kPrimary = {/*physical*/ k0_60Hz,
@@ -2831,7 +2858,7 @@
/*appRequestRanges*/
kAppRequest}));
}
- EXPECT_SCORED_FRAME_RATE(kMode60, 60_Hz, selector.getBestScoredFrameRate());
+ EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate().frameRateMode);
{
constexpr FpsRanges kPrimary = {/*physical*/ k0_120Hz,
@@ -2843,7 +2870,7 @@
/*appRequestRanges*/
kAppRequest}));
}
- EXPECT_SCORED_FRAME_RATE(kMode60, 60_Hz, selector.getBestScoredFrameRate());
+ EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate().frameRateMode);
}
TEST_P(RefreshRateSelectorTest, renderFrameRates_60_120) {
@@ -2858,17 +2885,20 @@
layer.name = "30Hz ExplicitDefault";
layer.desiredRefreshRate = 30_Hz;
layer.vote = LayerVoteType::ExplicitDefault;
- EXPECT_SCORED_FRAME_RATE(kMode60, expectedRenderRate, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate,
+ selector.getBestScoredFrameRate(layers).frameRateMode);
layer.name = "30Hz Heuristic";
layer.desiredRefreshRate = 30_Hz;
layer.vote = LayerVoteType::Heuristic;
- EXPECT_SCORED_FRAME_RATE(kMode60, expectedRenderRate, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate,
+ selector.getBestScoredFrameRate(layers).frameRateMode);
layer.name = "30Hz ExplicitExactOrMultiple";
layer.desiredRefreshRate = 30_Hz;
layer.vote = LayerVoteType::ExplicitExactOrMultiple;
- EXPECT_SCORED_FRAME_RATE(kMode60, expectedRenderRate, selector.getBestScoredFrameRate(layers));
+ EXPECT_FRAME_RATE_MODE(kMode60, expectedRenderRate,
+ selector.getBestScoredFrameRate(layers).frameRateMode);
}
TEST_P(RefreshRateSelectorTest, idleWhenLowestRefreshRateIsNotDivisor) {
@@ -2897,7 +2927,7 @@
EXPECT_EQ(kModeId90, selector.getBestFrameRateMode({}, {.touch = true, .idle = true})->getId());
// Idle should be higher precedence than other layer frame rate considerations.
- selector.setActiveModeId(kModeId90);
+ selector.setActiveMode(kModeId90, 90_Hz);
{
constexpr bool kTouchActive = false;
EXPECT_EQ(kModeId35, getIdleDisplayModeId(LayerVoteType::NoVote, kTouchActive));
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 8e333a3..3ee53c9 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -58,22 +58,22 @@
SchedulerTest();
static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
- static inline const DisplayModePtr kDisplay1Mode60 =
- createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz);
- static inline const DisplayModePtr kDisplay1Mode120 =
- createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz);
+ static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode60 =
+ ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode120 =
+ ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz));
static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
- static inline const DisplayModePtr kDisplay2Mode60 =
- createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz);
- static inline const DisplayModePtr kDisplay2Mode120 =
- createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz);
+ static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode60 =
+ ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz));
+ static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode120 =
+ ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz));
static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
- static inline const DisplayModePtr kDisplay3Mode60 =
- createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz);
+ static inline const ftl::NonNull<DisplayModePtr> kDisplay3Mode60 =
+ ftl::as_non_null(createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz));
static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
std::shared_ptr<RefreshRateSelector> mSelector =
@@ -217,7 +217,9 @@
// If the handle is incorrect, the function should return before
// onModeChange is called.
ConnectionHandle invalidHandle = {.id = 123};
- EXPECT_NO_FATAL_FAILURE(mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle, mode));
+ EXPECT_NO_FATAL_FAILURE(
+ mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
+ {90_Hz, ftl::as_non_null(mode)}));
EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
}
@@ -232,7 +234,7 @@
}
MATCHER(Is120Hz, "") {
- return isApproxEqual(arg.front().modePtr->getFps(), 120_Hz);
+ return isApproxEqual(arg.front().mode.fps, 120_Hz);
}
TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
@@ -277,7 +279,7 @@
auto choice = modeChoices.get(kDisplayId1);
ASSERT_TRUE(choice);
- EXPECT_EQ(choice->get(), DisplayModeChoice(kDisplay1Mode60, globalSignals));
+ EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
globalSignals = {.idle = false};
mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
@@ -287,7 +289,7 @@
choice = modeChoices.get(kDisplayId1);
ASSERT_TRUE(choice);
- EXPECT_EQ(choice->get(), DisplayModeChoice(kDisplay1Mode120, globalSignals));
+ EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
globalSignals = {.touch = true};
mScheduler->replaceTouchTimer(10);
@@ -298,7 +300,7 @@
choice = modeChoices.get(kDisplayId1);
ASSERT_TRUE(choice);
- EXPECT_EQ(choice->get(), DisplayModeChoice(kDisplay1Mode120, globalSignals));
+ EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
mScheduler->unregisterDisplay(kDisplayId1);
EXPECT_FALSE(mScheduler->hasRefreshRateSelectors());
@@ -319,8 +321,11 @@
const GlobalSignals globalSignals = {.idle = true};
expectedChoices =
ftl::init::map<const PhysicalDisplayId&,
- DisplayModeChoice>(kDisplayId1, kDisplay1Mode60,
- globalSignals)(kDisplayId2, kDisplay2Mode60,
+ DisplayModeChoice>(kDisplayId1,
+ FrameRateMode{60_Hz, kDisplay1Mode60},
+ globalSignals)(kDisplayId2,
+ FrameRateMode{60_Hz,
+ kDisplay2Mode60},
globalSignals);
std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
@@ -335,8 +340,11 @@
const GlobalSignals globalSignals = {.idle = false};
expectedChoices =
ftl::init::map<const PhysicalDisplayId&,
- DisplayModeChoice>(kDisplayId1, kDisplay1Mode120,
- globalSignals)(kDisplayId2, kDisplay2Mode120,
+ DisplayModeChoice>(kDisplayId1,
+ FrameRateMode{120_Hz, kDisplay1Mode120},
+ globalSignals)(kDisplayId2,
+ FrameRateMode{120_Hz,
+ kDisplay2Mode120},
globalSignals);
mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
@@ -351,8 +359,11 @@
expectedChoices =
ftl::init::map<const PhysicalDisplayId&,
- DisplayModeChoice>(kDisplayId1, kDisplay1Mode120,
- globalSignals)(kDisplayId2, kDisplay2Mode120,
+ DisplayModeChoice>(kDisplayId1,
+ FrameRateMode{120_Hz, kDisplay1Mode120},
+ globalSignals)(kDisplayId2,
+ FrameRateMode{120_Hz,
+ kDisplay2Mode120},
globalSignals);
const auto actualChoices = mScheduler->chooseDisplayModes();
@@ -369,13 +380,15 @@
mScheduler->replaceTouchTimer(10);
mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
- expectedChoices =
- ftl::init::map<const PhysicalDisplayId&,
- DisplayModeChoice>(kDisplayId1, kDisplay1Mode60,
- globalSignals)(kDisplayId2, kDisplay2Mode60,
- globalSignals)(kDisplayId3,
- kDisplay3Mode60,
- globalSignals);
+ expectedChoices = ftl::init::map<
+ const PhysicalDisplayId&,
+ DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
+ globalSignals)(kDisplayId2,
+ FrameRateMode{60_Hz, kDisplay2Mode60},
+ globalSignals)(kDisplayId3,
+ FrameRateMode{60_Hz,
+ kDisplay3Mode60},
+ globalSignals);
const auto actualChoices = mScheduler->chooseDisplayModes();
EXPECT_EQ(expectedChoices, actualChoices);
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
index 05d0ebf..b81693a 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
@@ -116,7 +116,7 @@
ftl::FakeGuard guard(kMainThreadContext);
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId60);
mFlinger.onActiveDisplayChanged(mDisplay);
@@ -125,8 +125,8 @@
120));
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId90);
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getDesiredActiveMode()->modeOpt->modePtr->getId(), kModeId90);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId60);
// Verify that next commit will call setActiveConfigWithConstraints in HWC
const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
@@ -139,7 +139,7 @@
Mock::VerifyAndClearExpectations(mComposer);
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId60);
// Verify that the next commit will complete the mode change and send
// a onModeChanged event to the framework.
@@ -149,7 +149,7 @@
Mock::VerifyAndClearExpectations(mAppEventThread);
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId90);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId90);
}
TEST_F(DisplayModeSwitchingTest, changeRefreshRate_OnActiveDisplay_WithoutRefreshRequired) {
@@ -164,8 +164,8 @@
120));
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId90);
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getDesiredActiveMode()->modeOpt->modePtr->getId(), kModeId90);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId60);
// Verify that next commit will call setActiveConfigWithConstraints in HWC
// and complete the mode change.
@@ -180,7 +180,7 @@
mFlinger.commit();
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId90);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId90);
}
TEST_F(DisplayModeSwitchingTest, twoConsecutiveSetDesiredDisplayModeSpecs) {
@@ -190,7 +190,7 @@
// is still being processed the later call will be respected.
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId60);
mFlinger.onActiveDisplayChanged(mDisplay);
@@ -211,7 +211,7 @@
180));
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId120);
+ ASSERT_EQ(mDisplay->getDesiredActiveMode()->modeOpt->modePtr->getId(), kModeId120);
EXPECT_CALL(*mComposer,
setActiveConfigWithConstraints(PrimaryDisplayVariant::HWC_DISPLAY_ID,
@@ -221,19 +221,19 @@
mFlinger.commit();
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId120);
+ ASSERT_EQ(mDisplay->getDesiredActiveMode()->modeOpt->modePtr->getId(), kModeId120);
mFlinger.commit();
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId120);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId120);
}
TEST_F(DisplayModeSwitchingTest, changeResolution_OnActiveDisplay_WithoutRefreshRequired) {
ftl::FakeGuard guard(kMainThreadContext);
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId60);
mFlinger.onActiveDisplayChanged(mDisplay);
@@ -242,8 +242,8 @@
120));
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId90_4K);
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getDesiredActiveMode()->modeOpt->modePtr->getId(), kModeId90_4K);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId60);
// Verify that next commit will call setActiveConfigWithConstraints in HWC
// and complete the mode change.
@@ -278,7 +278,7 @@
mDisplay = mFlinger.getDisplay(displayToken);
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId90_4K);
+ ASSERT_EQ(mDisplay->getActiveMode().modePtr->getId(), kModeId90_4K);
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
index 0384568..c0796df 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
@@ -288,7 +288,7 @@
if constexpr (Case::Display::CONNECTION_TYPE::value) {
ftl::FakeGuard guard(kMainThreadContext);
- EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveMode().getHwcId());
+ EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveMode().modePtr->getHwcId());
}
}
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 3f8fe0d..54c10c5 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -44,8 +44,7 @@
: Scheduler(*this, callback, Feature::kContentDetection) {
mVsyncSchedule.emplace(VsyncSchedule(std::move(tracker), nullptr, std::move(controller)));
- const auto displayId = FTL_FAKE_GUARD(kMainThreadContext,
- selectorPtr->getActiveMode().getPhysicalDisplayId());
+ const auto displayId = selectorPtr->getActiveMode().modePtr->getPhysicalDisplayId();
registerDisplay(displayId, std::move(selectorPtr));
ON_CALL(*this, postMessage).WillByDefault([](sp<MessageHandler>&& handler) {
@@ -147,7 +146,7 @@
mPolicy.cachedModeChangedParams.reset();
}
- void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, DisplayModePtr mode) {
+ void onNonPrimaryDisplayModeChanged(ConnectionHandle handle, const FrameRateMode& mode) {
Scheduler::onNonPrimaryDisplayModeChanged(handle, mode);
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index c15b3c8..e29dd67 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -221,7 +221,7 @@
selectorPtr = std::make_shared<scheduler::RefreshRateSelector>(modes, kModeId60);
}
- const auto fps = FTL_FAKE_GUARD(kMainThreadContext, selectorPtr->getActiveMode().getFps());
+ const auto fps = selectorPtr->getActiveMode().fps;
mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(fps);
mFlinger->mVsyncModulator = sp<scheduler::VsyncModulator>::make(
mFlinger->mVsyncConfiguration->getCurrentConfigs());
@@ -857,23 +857,24 @@
const auto activeMode = modes.get(activeModeId);
LOG_ALWAYS_FATAL_IF(!activeMode);
+ const auto fps = activeMode->get()->getFps();
state.physical = {.id = physicalId,
.hwcDisplayId = *mHwcDisplayId,
.activeMode = activeMode->get()};
- const auto it = mFlinger.mutablePhysicalDisplays()
- .emplace_or_replace(physicalId, mDisplayToken, physicalId,
- *mConnectionType, std::move(modes),
- ui::ColorModes(), std::nullopt)
- .first;
+ mFlinger.mutablePhysicalDisplays().emplace_or_replace(physicalId, mDisplayToken,
+ physicalId, *mConnectionType,
+ std::move(modes),
+ ui::ColorModes(),
+ std::nullopt);
if (mFlinger.scheduler()) {
mFlinger.scheduler()->registerDisplay(physicalId,
display->holdRefreshRateSelector());
}
- display->setActiveMode(activeModeId, it->second.snapshot());
+ display->setActiveMode(activeModeId, fps, fps);
}
mFlinger.mutableCurrentState().displays.add(mDisplayToken, state);
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
index 2da266b..47c2dee 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
@@ -54,6 +54,7 @@
void resetModel() final {}
bool needsMoreSamples() const final { return false; }
bool isVSyncInPhase(nsecs_t, Fps) const final { return false; }
+ void setDivisor(unsigned) final {}
void dump(std::string&) const final {}
private:
@@ -91,6 +92,7 @@
void resetModel() final {}
bool needsMoreSamples() const final { return false; }
bool isVSyncInPhase(nsecs_t, Fps) const final { return false; }
+ void setDivisor(unsigned) final {}
void dump(std::string&) const final {}
private:
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index f660753..2b86e94 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -55,6 +55,7 @@
MOCK_METHOD0(resetModel, void());
MOCK_CONST_METHOD0(needsMoreSamples, bool());
MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
+ MOCK_METHOD(void, setDivisor, (unsigned), (override));
MOCK_CONST_METHOD1(dump, void(std::string&));
nsecs_t nextVSyncTime(nsecs_t timePoint) const {
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index 74d2b7d..3095e8a 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -532,6 +532,26 @@
EXPECT_THAT(intercept, IsCloseTo(expectedIntercept, mMaxRoundingError));
}
+TEST_F(VSyncPredictorTest, setDivisorIsRespected) {
+ auto last = mNow;
+ for (auto i = 0u; i < kMinimumSamplesForPrediction; i++) {
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(last + mPeriod));
+ mNow += mPeriod;
+ last = mNow;
+ tracker.addVsyncTimestamp(mNow);
+ }
+
+ tracker.setDivisor(3);
+
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow), Eq(mNow + mPeriod));
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 100), Eq(mNow + mPeriod));
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 1100), Eq(mNow + 4 * mPeriod));
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 2100), Eq(mNow + 4 * mPeriod));
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 3100), Eq(mNow + 4 * mPeriod));
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 4100), Eq(mNow + 7 * mPeriod));
+ EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 5100), Eq(mNow + 7 * mPeriod));
+}
+
} // namespace android::scheduler
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
index a35ff96..8bd689a 100644
--- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
@@ -50,6 +50,7 @@
MOCK_METHOD0(resetModel, void());
MOCK_CONST_METHOD0(needsMoreSamples, bool());
MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
+ MOCK_METHOD(void, setDivisor, (unsigned), (override));
MOCK_CONST_METHOD1(dump, void(std::string&));
};
diff --git a/services/surfaceflinger/tests/unittests/mock/MockFrameRateMode.h b/services/surfaceflinger/tests/unittests/mock/MockFrameRateMode.h
new file mode 100644
index 0000000..ef9cd9b
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/MockFrameRateMode.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <scheduler/FrameRateMode.h>
+
+// Use a C style macro to keep the line numbers printed in gtest
+#define EXPECT_FRAME_RATE_MODE(modePtr, fps, mode) \
+ EXPECT_EQ((scheduler::FrameRateMode{(fps), (modePtr)}), (mode))
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
index 5b0c1f3..6893154 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
@@ -34,6 +34,7 @@
MOCK_METHOD0(resetModel, void());
MOCK_CONST_METHOD0(needsMoreSamples, bool());
MOCK_CONST_METHOD2(isVSyncInPhase, bool(nsecs_t, Fps));
+ MOCK_METHOD(void, setDivisor, (unsigned), (override));
MOCK_CONST_METHOD1(dump, void(std::string&));
};