diff options
| author | 2019-08-29 18:16:49 +0000 | |
|---|---|---|
| committer | 2019-08-29 18:16:49 +0000 | |
| commit | d37aeeb139df313efc0aa7ea11964ea6837da9b2 (patch) | |
| tree | af775eb093efb2a841697bc4682a2b0505fd6195 | |
| parent | 7fcea26183280ad81d09835c8fabf4fe095e3300 (diff) | |
| parent | c2d54d4038202406573191ffdc54c96d8079d09c (diff) | |
Merge "SF: Clear layers properly doing client composition"
| -rw-r--r-- | services/surfaceflinger/CompositionEngine/src/Output.cpp | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp | 79 |
2 files changed, 80 insertions, 1 deletions
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index e4404bffd6..2483c0682b 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -432,7 +432,7 @@ std::vector<renderengine::LayerSettings> Output::generateClientCompositionReques clientComposition ? clearRegion : dummyRegion, }; if (auto result = layerFE.prepareClientComposition(targetSettings)) { - if (clearClientComposition) { + if (!clientComposition) { auto& layerSettings = *result; layerSettings.source.buffer.buffer = nullptr; layerSettings.source.solidColor = half3(0.0, 0.0, 0.0); diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index 318818a11c..f4d2cf180b 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -717,5 +717,84 @@ TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWit EXPECT_EQ(0u, requests.size()); } +TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) { + // If client composition is performed with some layers set to use device + // composition, device layers after the first layer (device or client) will + // clear the frame buffer if they are opaque and if that layer has a flag + // set to do so. The first layer is skipped as the frame buffer is already + // expected to be clear. + + mock::OutputLayer* leftOutputLayer = new StrictMock<mock::OutputLayer>(); + mock::OutputLayer* rightOutputLayer = new StrictMock<mock::OutputLayer>(); + + StrictMock<mock::Layer> leftLayer; + StrictMock<mock::LayerFE> leftLayerFE; + StrictMock<mock::Layer> rightLayer; + StrictMock<mock::LayerFE> rightLayerFE; + + impl::OutputLayerCompositionState leftOutputLayerState; + leftOutputLayerState.clearClientTarget = true; + + impl::LayerCompositionState leftLayerState; + leftLayerState.frontEnd.geomVisibleRegion = Region{Rect{0, 0, 1000, 1000}}; + leftLayerState.frontEnd.isOpaque = true; + + impl::OutputLayerCompositionState rightOutputLayerState; + rightOutputLayerState.clearClientTarget = true; + + impl::LayerCompositionState rightLayerState; + rightLayerState.frontEnd.geomVisibleRegion = Region{Rect{1000, 0, 2000, 1000}}; + rightLayerState.frontEnd.isOpaque = true; + + const half3 rightLayerColor{0.f, 1.f, 0.f}; + renderengine::LayerSettings rightLayerRESettings; + rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0}; + rightLayerRESettings.source.solidColor = rightLayerColor; + + EXPECT_CALL(*leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState)); + EXPECT_CALL(*leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer)); + EXPECT_CALL(*leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE)); + EXPECT_CALL(*leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); + EXPECT_CALL(*leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); + EXPECT_CALL(leftLayer, getState()).WillRepeatedly(ReturnRef(leftLayerState)); + + EXPECT_CALL(*rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState)); + EXPECT_CALL(*rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer)); + EXPECT_CALL(*rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE)); + EXPECT_CALL(*rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); + EXPECT_CALL(*rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false)); + EXPECT_CALL(rightLayer, getState()).WillRepeatedly(ReturnRef(rightLayerState)); + EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings)); + + Output::OutputLayers outputLayers; + outputLayers.emplace_back(std::unique_ptr<OutputLayer>(leftOutputLayer)); + outputLayers.emplace_back(std::unique_ptr<OutputLayer>(rightOutputLayer)); + mOutput.setOutputLayersOrderedByZ(std::move(outputLayers)); + + const Rect kPortraitFrame(0, 0, 1000, 2000); + const Rect kPortraitViewport(0, 0, 2000, 1000); + const Rect kPortraitScissor(0, 0, 1000, 2000); + const uint32_t kPortraitOrientation = TR_ROT_90; + + mOutput.editState().frame = kPortraitFrame; + mOutput.editState().viewport = kPortraitViewport; + mOutput.editState().scissor = kPortraitScissor; + mOutput.editState().transform = ui::Transform{kPortraitOrientation}; + mOutput.editState().orientation = kPortraitOrientation; + mOutput.editState().needsFiltering = true; + mOutput.editState().isSecure = false; + + constexpr bool supportsProtectedContent = false; + Region clearRegion; + auto requests = + mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion); + + const half3 clearColor{0.f, 0.f, 0.f}; + + ASSERT_EQ(1u, requests.size()); + EXPECT_EQ(456.f, requests[0].geometry.boundaries.left); + EXPECT_EQ(clearColor, requests[0].source.solidColor); +} + } // namespace } // namespace android::compositionengine |