Loading services/surfaceflinger/SurfaceFlinger.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -2408,6 +2408,8 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, frontend::LayerSnapshotBuilder::Args args{.root = mLayerHierarchyBuilder.getHierarchy(), .layerLifecycleManager = mLayerLifecycleManager, .includeMetadata = mCompositionEngine->getFeatureFlags().test( compositionengine::Feature::kSnapshotLayerMetadata), .displays = mFrontEndDisplayInfos, .displayChanges = mFrontEndDisplayInfosChanged, .globalShadowSettings = mDrawingState.globalShadowSettings, Loading services/surfaceflinger/tests/unittests/CommitTest.cpp +105 −4 Original line number Diff line number Diff line Loading @@ -17,9 +17,17 @@ #undef LOG_TAG #define LOG_TAG "CommitTest" #include <DisplayHardware/HWComposer.h> #include <FrontEnd/LayerCreationArgs.h> #include <FrontEnd/RequestedLayerState.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/Feature.h> #include <compositionengine/mock/CompositionEngine.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <gui/LayerMetadata.h> #include <gui/SurfaceComposerClient.h> #include <mock/DisplayHardware/MockComposer.h> #include <renderengine/mock/RenderEngine.h> #include "TestableSurfaceFlinger.h" Loading @@ -27,18 +35,27 @@ namespace android { class CommitTest : public testing::Test { protected: CommitTest() { TestableSurfaceFlinger mFlinger; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); void flinger_setup() { mFlinger.setupMockScheduler(); mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); } TestableSurfaceFlinger mFlinger; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); LayerCreationArgs createArgs(uint32_t id, LayerMetadata metadata, uint32_t parentId) { LayerCreationArgs args(mFlinger.flinger(), nullptr, "layer", gui::ISurfaceComposerClient::eNoColorFill, metadata, id); args.parentId = parentId; return args; } }; namespace { TEST_F(CommitTest, noUpdatesDoesNotScheduleComposite) { flinger_setup(); bool unused; bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0, /*transactionsFlushed=*/0, unused); Loading @@ -47,6 +64,7 @@ TEST_F(CommitTest, noUpdatesDoesNotScheduleComposite) { // Ensure that we handle eTransactionNeeded correctly TEST_F(CommitTest, eTransactionNeededFlagSchedulesComposite) { flinger_setup(); // update display level color matrix mFlinger.setDaltonizerType(ColorBlindnessType::Deuteranomaly); bool unused; Loading @@ -55,5 +73,88 @@ TEST_F(CommitTest, eTransactionNeededFlagSchedulesComposite) { EXPECT_TRUE(mustComposite); } TEST_F(CommitTest, metadataNotIncluded) { mFlinger.setupMockScheduler(); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); compositionengine::mock::CompositionEngine* mCompositionEngine = new compositionengine::mock::CompositionEngine(); // CompositionEngine setup with unset flag compositionengine::FeatureFlags flags; impl::HWComposer hwc = impl::HWComposer(std::make_unique<Hwc2::mock::Composer>()); EXPECT_CALL(*mCompositionEngine, getFeatureFlags).WillOnce(testing::Return(flags)); EXPECT_THAT(flags.test(compositionengine::Feature::kSnapshotLayerMetadata), false); EXPECT_CALL(*mCompositionEngine, getHwComposer).WillOnce(testing::ReturnRef(hwc)); mFlinger.setupCompositionEngine( std::unique_ptr<compositionengine::CompositionEngine>(mCompositionEngine)); // Create a parent layer with metadata and a child layer without. Metadata should not // be included in the child layer when the flag is not set. std::unordered_map<uint32_t, std::vector<uint8_t>> metadata = {{1, {'a', 'b'}}}; auto parent = std::make_unique<frontend::RequestedLayerState>( createArgs(1, LayerMetadata(metadata), UNASSIGNED_LAYER_ID)); mFlinger.addLayer(parent); auto child = std::make_unique<frontend::RequestedLayerState>(createArgs(11, LayerMetadata(), 1)); mFlinger.addLayer(child); bool unused; bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0, /*transactionsFlushed=*/1, unused); EXPECT_TRUE(mustComposite); auto parentMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(1)->layerMetadata.mMap; auto childMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(11)->layerMetadata.mMap; EXPECT_EQ(metadata.at(1), parentMetadata.at(1)); EXPECT_NE(parentMetadata, childMetadata); } TEST_F(CommitTest, metadataIsIncluded) { mFlinger.setupMockScheduler(); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); compositionengine::mock::CompositionEngine* mCompositionEngine = new compositionengine::mock::CompositionEngine(); // CompositionEngine setup with set flag compositionengine::FeatureFlags flags; flags |= compositionengine::Feature::kSnapshotLayerMetadata; impl::HWComposer hwc = impl::HWComposer(std::make_unique<Hwc2::mock::Composer>()); EXPECT_CALL(*mCompositionEngine, getFeatureFlags).WillOnce(testing::Return(flags)); EXPECT_THAT(flags.test(compositionengine::Feature::kSnapshotLayerMetadata), true); EXPECT_CALL(*mCompositionEngine, getHwComposer).WillOnce(testing::ReturnRef(hwc)); mFlinger.setupCompositionEngine( std::unique_ptr<compositionengine::CompositionEngine>(mCompositionEngine)); // Create a parent layer with metadata and a child layer without. Metadata from the // parent should be included in the child layer when the flag is set. std::unordered_map<uint32_t, std::vector<uint8_t>> metadata = {{1, {'a', 'b'}}}; auto parent = std::make_unique<frontend::RequestedLayerState>( createArgs(1, LayerMetadata(metadata), UNASSIGNED_LAYER_ID)); mFlinger.addLayer(parent); auto child = std::make_unique<frontend::RequestedLayerState>(createArgs(11, LayerMetadata(), 1)); mFlinger.addLayer(child); bool unused; bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0, /*transactionsFlushed=*/1, unused); EXPECT_TRUE(mustComposite); auto parentMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(1)->layerMetadata.mMap; auto childMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(11)->layerMetadata.mMap; EXPECT_EQ(metadata.at(1), parentMetadata.at(1)); EXPECT_EQ(parentMetadata, childMetadata); } } // namespace } // namespace android services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +16 −0 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ #include <algorithm> #include <chrono> #include <memory> #include <variant> #include <ftl/fake_guard.h> #include <ftl/match.h> #include <gui/LayerMetadata.h> #include <gui/ScreenCaptureResults.h> #include <ui/DynamicDisplayInfo.h> Loading @@ -38,6 +40,7 @@ #include "FrameTracer/FrameTracer.h" #include "FrontEnd/LayerCreationArgs.h" #include "FrontEnd/LayerHandle.h" #include "FrontEnd/RequestedLayerState.h" #include "Layer.h" #include "NativeWindowSurface.h" #include "RenderArea.h" Loading @@ -45,6 +48,7 @@ #include "Scheduler/RefreshRateSelector.h" #include "SurfaceFlinger.h" #include "TestableScheduler.h" #include "android/gui/ISurfaceComposerClient.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/DisplayHardware/MockDisplayMode.h" #include "mock/DisplayHardware/MockPowerAdvisor.h" Loading Loading @@ -197,6 +201,11 @@ public: mFlinger->mCompositionEngine->setTimeStats(timeStats); } void setupCompositionEngine( std::unique_ptr<compositionengine::CompositionEngine> compositionEngine) { mFlinger->mCompositionEngine = std::move(compositionEngine); } enum class SchedulerCallbackImpl { kNoOp, kMock }; struct DefaultDisplayMode { Loading Loading @@ -587,6 +596,13 @@ public: return mFlinger->getDisplayStats(displayToken, outInfo); } // Used to add a layer before updateLayerSnapshots is called. // Must have transactionsFlushed enabled for the new layer to be updated. void addLayer(std::unique_ptr<frontend::RequestedLayerState>& layer) { std::scoped_lock<std::mutex> lock(mFlinger->mCreatedLayersLock); mFlinger->mNewLayers.emplace_back(std::move(layer)); } /* ------------------------------------------------------------------------ * Read-only access to private data to assert post-conditions. */ Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -2408,6 +2408,8 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, frontend::LayerSnapshotBuilder::Args args{.root = mLayerHierarchyBuilder.getHierarchy(), .layerLifecycleManager = mLayerLifecycleManager, .includeMetadata = mCompositionEngine->getFeatureFlags().test( compositionengine::Feature::kSnapshotLayerMetadata), .displays = mFrontEndDisplayInfos, .displayChanges = mFrontEndDisplayInfosChanged, .globalShadowSettings = mDrawingState.globalShadowSettings, Loading
services/surfaceflinger/tests/unittests/CommitTest.cpp +105 −4 Original line number Diff line number Diff line Loading @@ -17,9 +17,17 @@ #undef LOG_TAG #define LOG_TAG "CommitTest" #include <DisplayHardware/HWComposer.h> #include <FrontEnd/LayerCreationArgs.h> #include <FrontEnd/RequestedLayerState.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/Feature.h> #include <compositionengine/mock/CompositionEngine.h> #include <gmock/gmock.h> #include <gtest/gtest.h> #include <gui/LayerMetadata.h> #include <gui/SurfaceComposerClient.h> #include <mock/DisplayHardware/MockComposer.h> #include <renderengine/mock/RenderEngine.h> #include "TestableSurfaceFlinger.h" Loading @@ -27,18 +35,27 @@ namespace android { class CommitTest : public testing::Test { protected: CommitTest() { TestableSurfaceFlinger mFlinger; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); void flinger_setup() { mFlinger.setupMockScheduler(); mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); } TestableSurfaceFlinger mFlinger; renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine(); LayerCreationArgs createArgs(uint32_t id, LayerMetadata metadata, uint32_t parentId) { LayerCreationArgs args(mFlinger.flinger(), nullptr, "layer", gui::ISurfaceComposerClient::eNoColorFill, metadata, id); args.parentId = parentId; return args; } }; namespace { TEST_F(CommitTest, noUpdatesDoesNotScheduleComposite) { flinger_setup(); bool unused; bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0, /*transactionsFlushed=*/0, unused); Loading @@ -47,6 +64,7 @@ TEST_F(CommitTest, noUpdatesDoesNotScheduleComposite) { // Ensure that we handle eTransactionNeeded correctly TEST_F(CommitTest, eTransactionNeededFlagSchedulesComposite) { flinger_setup(); // update display level color matrix mFlinger.setDaltonizerType(ColorBlindnessType::Deuteranomaly); bool unused; Loading @@ -55,5 +73,88 @@ TEST_F(CommitTest, eTransactionNeededFlagSchedulesComposite) { EXPECT_TRUE(mustComposite); } TEST_F(CommitTest, metadataNotIncluded) { mFlinger.setupMockScheduler(); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); compositionengine::mock::CompositionEngine* mCompositionEngine = new compositionengine::mock::CompositionEngine(); // CompositionEngine setup with unset flag compositionengine::FeatureFlags flags; impl::HWComposer hwc = impl::HWComposer(std::make_unique<Hwc2::mock::Composer>()); EXPECT_CALL(*mCompositionEngine, getFeatureFlags).WillOnce(testing::Return(flags)); EXPECT_THAT(flags.test(compositionengine::Feature::kSnapshotLayerMetadata), false); EXPECT_CALL(*mCompositionEngine, getHwComposer).WillOnce(testing::ReturnRef(hwc)); mFlinger.setupCompositionEngine( std::unique_ptr<compositionengine::CompositionEngine>(mCompositionEngine)); // Create a parent layer with metadata and a child layer without. Metadata should not // be included in the child layer when the flag is not set. std::unordered_map<uint32_t, std::vector<uint8_t>> metadata = {{1, {'a', 'b'}}}; auto parent = std::make_unique<frontend::RequestedLayerState>( createArgs(1, LayerMetadata(metadata), UNASSIGNED_LAYER_ID)); mFlinger.addLayer(parent); auto child = std::make_unique<frontend::RequestedLayerState>(createArgs(11, LayerMetadata(), 1)); mFlinger.addLayer(child); bool unused; bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0, /*transactionsFlushed=*/1, unused); EXPECT_TRUE(mustComposite); auto parentMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(1)->layerMetadata.mMap; auto childMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(11)->layerMetadata.mMap; EXPECT_EQ(metadata.at(1), parentMetadata.at(1)); EXPECT_NE(parentMetadata, childMetadata); } TEST_F(CommitTest, metadataIsIncluded) { mFlinger.setupMockScheduler(); mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine)); compositionengine::mock::CompositionEngine* mCompositionEngine = new compositionengine::mock::CompositionEngine(); // CompositionEngine setup with set flag compositionengine::FeatureFlags flags; flags |= compositionengine::Feature::kSnapshotLayerMetadata; impl::HWComposer hwc = impl::HWComposer(std::make_unique<Hwc2::mock::Composer>()); EXPECT_CALL(*mCompositionEngine, getFeatureFlags).WillOnce(testing::Return(flags)); EXPECT_THAT(flags.test(compositionengine::Feature::kSnapshotLayerMetadata), true); EXPECT_CALL(*mCompositionEngine, getHwComposer).WillOnce(testing::ReturnRef(hwc)); mFlinger.setupCompositionEngine( std::unique_ptr<compositionengine::CompositionEngine>(mCompositionEngine)); // Create a parent layer with metadata and a child layer without. Metadata from the // parent should be included in the child layer when the flag is set. std::unordered_map<uint32_t, std::vector<uint8_t>> metadata = {{1, {'a', 'b'}}}; auto parent = std::make_unique<frontend::RequestedLayerState>( createArgs(1, LayerMetadata(metadata), UNASSIGNED_LAYER_ID)); mFlinger.addLayer(parent); auto child = std::make_unique<frontend::RequestedLayerState>(createArgs(11, LayerMetadata(), 1)); mFlinger.addLayer(child); bool unused; bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0, /*transactionsFlushed=*/1, unused); EXPECT_TRUE(mustComposite); auto parentMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(1)->layerMetadata.mMap; auto childMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(11)->layerMetadata.mMap; EXPECT_EQ(metadata.at(1), parentMetadata.at(1)); EXPECT_EQ(parentMetadata, childMetadata); } } // namespace } // namespace android
services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +16 −0 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ #include <algorithm> #include <chrono> #include <memory> #include <variant> #include <ftl/fake_guard.h> #include <ftl/match.h> #include <gui/LayerMetadata.h> #include <gui/ScreenCaptureResults.h> #include <ui/DynamicDisplayInfo.h> Loading @@ -38,6 +40,7 @@ #include "FrameTracer/FrameTracer.h" #include "FrontEnd/LayerCreationArgs.h" #include "FrontEnd/LayerHandle.h" #include "FrontEnd/RequestedLayerState.h" #include "Layer.h" #include "NativeWindowSurface.h" #include "RenderArea.h" Loading @@ -45,6 +48,7 @@ #include "Scheduler/RefreshRateSelector.h" #include "SurfaceFlinger.h" #include "TestableScheduler.h" #include "android/gui/ISurfaceComposerClient.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/DisplayHardware/MockDisplayMode.h" #include "mock/DisplayHardware/MockPowerAdvisor.h" Loading Loading @@ -197,6 +201,11 @@ public: mFlinger->mCompositionEngine->setTimeStats(timeStats); } void setupCompositionEngine( std::unique_ptr<compositionengine::CompositionEngine> compositionEngine) { mFlinger->mCompositionEngine = std::move(compositionEngine); } enum class SchedulerCallbackImpl { kNoOp, kMock }; struct DefaultDisplayMode { Loading Loading @@ -587,6 +596,13 @@ public: return mFlinger->getDisplayStats(displayToken, outInfo); } // Used to add a layer before updateLayerSnapshots is called. // Must have transactionsFlushed enabled for the new layer to be updated. void addLayer(std::unique_ptr<frontend::RequestedLayerState>& layer) { std::scoped_lock<std::mutex> lock(mFlinger->mCreatedLayersLock); mFlinger->mNewLayers.emplace_back(std::move(layer)); } /* ------------------------------------------------------------------------ * Read-only access to private data to assert post-conditions. */ Loading