|  | /* | 
|  | * Copyright 2023 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. | 
|  | */ | 
|  |  | 
|  | #undef LOG_TAG | 
|  | #define LOG_TAG "LibSurfaceFlingerUnittests" | 
|  |  | 
|  | #include <gmock/gmock.h> | 
|  | #include <gtest/gtest.h> | 
|  | #include <gui/LayerMetadata.h> | 
|  |  | 
|  | #include "Layer.h" | 
|  | #include "LayerTestUtils.h" | 
|  | #include "TestableSurfaceFlinger.h" | 
|  | #include "mock/DisplayHardware/MockComposer.h" | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | using testing::DoAll; | 
|  | using testing::Mock; | 
|  | using testing::SetArgPointee; | 
|  |  | 
|  | using android::Hwc2::IComposer; | 
|  | using android::Hwc2::IComposerClient; | 
|  |  | 
|  | using scheduler::LayerHistory; | 
|  |  | 
|  | using FrameRate = Layer::FrameRate; | 
|  | using FrameRateCompatibility = Layer::FrameRateCompatibility; | 
|  | using FrameRateSelectionStrategy = scheduler::LayerInfo::FrameRateSelectionStrategy; | 
|  |  | 
|  | /** | 
|  | * This class tests the behaviour of Layer::setFrameRateSelectionStrategy. | 
|  | */ | 
|  | class FrameRateSelectionStrategyTest : public BaseLayerTest { | 
|  | protected: | 
|  | const FrameRate FRAME_RATE_VOTE1 = FrameRate(11_Hz, FrameRateCompatibility::Default); | 
|  | const FrameRate FRAME_RATE_VOTE2 = FrameRate(22_Hz, FrameRateCompatibility::Default); | 
|  | const FrameRate FRAME_RATE_VOTE3 = FrameRate(33_Hz, FrameRateCompatibility::Default); | 
|  | const FrameRate FRAME_RATE_TREE = FrameRate(Fps(), FrameRateCompatibility::NoVote); | 
|  |  | 
|  | FrameRateSelectionStrategyTest(); | 
|  |  | 
|  | void addChild(sp<Layer> layer, sp<Layer> child); | 
|  | void removeChild(sp<Layer> layer, sp<Layer> child); | 
|  | void commitTransaction(); | 
|  |  | 
|  | std::vector<sp<Layer>> mLayers; | 
|  | }; | 
|  |  | 
|  | FrameRateSelectionStrategyTest::FrameRateSelectionStrategyTest() { | 
|  | const ::testing::TestInfo* const test_info = | 
|  | ::testing::UnitTest::GetInstance()->current_test_info(); | 
|  | ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); | 
|  |  | 
|  | mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); | 
|  | } | 
|  |  | 
|  | void FrameRateSelectionStrategyTest::addChild(sp<Layer> layer, sp<Layer> child) { | 
|  | layer->addChild(child); | 
|  | } | 
|  |  | 
|  | void FrameRateSelectionStrategyTest::removeChild(sp<Layer> layer, sp<Layer> child) { | 
|  | layer->removeChild(child); | 
|  | } | 
|  |  | 
|  | void FrameRateSelectionStrategyTest::commitTransaction() { | 
|  | for (auto layer : mLayers) { | 
|  | layer->commitTransaction(); | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | INSTANTIATE_TEST_SUITE_P(PerLayerType, FrameRateSelectionStrategyTest, | 
|  | testing::Values(std::make_shared<BufferStateLayerFactory>(), | 
|  | std::make_shared<EffectLayerFactory>()), | 
|  | PrintToStringParamName); | 
|  |  | 
|  | TEST_P(FrameRateSelectionStrategyTest, SetAndGet) { | 
|  | EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1); | 
|  |  | 
|  | const auto& layerFactory = GetParam(); | 
|  | auto layer = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); | 
|  | layer->setFrameRate(FRAME_RATE_VOTE1.vote); | 
|  | layer->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::OverrideChildren); | 
|  | commitTransaction(); | 
|  | EXPECT_EQ(FRAME_RATE_VOTE1, layer->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::OverrideChildren, | 
|  | layer->getDrawingState().frameRateSelectionStrategy); | 
|  | } | 
|  |  | 
|  | TEST_P(FrameRateSelectionStrategyTest, SetChildAndGetParent) { | 
|  | EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1); | 
|  |  | 
|  | const auto& layerFactory = GetParam(); | 
|  | auto parent = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); | 
|  | auto child1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); | 
|  | auto child2 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); | 
|  | addChild(parent, child1); | 
|  | addChild(child1, child2); | 
|  |  | 
|  | child2->setFrameRate(FRAME_RATE_VOTE1.vote); | 
|  | child2->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::OverrideChildren); | 
|  | commitTransaction(); | 
|  | EXPECT_EQ(FRAME_RATE_TREE, parent->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::Self, | 
|  | parent->getDrawingState().frameRateSelectionStrategy); | 
|  | EXPECT_EQ(FRAME_RATE_TREE, child1->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::Self, | 
|  | child1->getDrawingState().frameRateSelectionStrategy); | 
|  | EXPECT_EQ(FRAME_RATE_VOTE1, child2->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::OverrideChildren, | 
|  | child2->getDrawingState().frameRateSelectionStrategy); | 
|  | } | 
|  |  | 
|  | TEST_P(FrameRateSelectionStrategyTest, SetParentAndGet) { | 
|  | EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1); | 
|  |  | 
|  | const auto& layerFactory = GetParam(); | 
|  | auto layer1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); | 
|  | auto layer2 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); | 
|  | auto layer3 = mLayers.emplace_back(layerFactory->createLayer(mFlinger)); | 
|  | addChild(layer1, layer2); | 
|  | addChild(layer2, layer3); | 
|  |  | 
|  | layer1->setFrameRate(FRAME_RATE_VOTE1.vote); | 
|  | layer1->setFrameRate(FRAME_RATE_VOTE1.vote); | 
|  | layer1->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::OverrideChildren); | 
|  | layer2->setFrameRate(FRAME_RATE_VOTE2.vote); | 
|  | layer2->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::OverrideChildren); | 
|  | layer3->setFrameRate(FRAME_RATE_VOTE3.vote); | 
|  | commitTransaction(); | 
|  |  | 
|  | EXPECT_EQ(FRAME_RATE_VOTE1, layer1->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::OverrideChildren, | 
|  | layer1->getDrawingState().frameRateSelectionStrategy); | 
|  | EXPECT_EQ(FRAME_RATE_VOTE1, layer2->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::OverrideChildren, | 
|  | layer2->getDrawingState().frameRateSelectionStrategy); | 
|  | EXPECT_EQ(FRAME_RATE_VOTE1, layer3->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::Self, | 
|  | layer3->getDrawingState().frameRateSelectionStrategy); | 
|  |  | 
|  | layer1->setFrameRateSelectionStrategy(FrameRateSelectionStrategy::Self); | 
|  | commitTransaction(); | 
|  |  | 
|  | EXPECT_EQ(FRAME_RATE_VOTE1, layer1->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::Self, | 
|  | layer1->getDrawingState().frameRateSelectionStrategy); | 
|  | EXPECT_EQ(FRAME_RATE_VOTE2, layer2->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::OverrideChildren, | 
|  | layer2->getDrawingState().frameRateSelectionStrategy); | 
|  | EXPECT_EQ(FRAME_RATE_VOTE2, layer3->getFrameRateForLayerTree()); | 
|  | EXPECT_EQ(FrameRateSelectionStrategy::Self, | 
|  | layer3->getDrawingState().frameRateSelectionStrategy); | 
|  | } | 
|  |  | 
|  | } // namespace | 
|  | } // namespace android |