diff options
| author | 2023-10-23 08:55:48 +0800 | |
|---|---|---|
| committer | 2024-03-01 01:13:50 +0000 | |
| commit | 48d09516be5e761d6817fdcd544be50086c7bd0c (patch) | |
| tree | 528fd83da12c966324c552d6a20add669641a4ce | |
| parent | c2e69665235335d5964bc61b689f587193f95a05 (diff) | |
Fix "Abnormal while playing netflix in PIP mode"
protected buffer usage of output buffer of framebuffer is determined
by if any input layer contains protected buffer.
If all the protected layers are handled by HWC,then GPU will process
normal layers only. It means, GPU got normal buffer as input but need
output to protected buffer.It would be memory violation for ARM as it
required at least one normal buffer as input for such case
Bug: 307674749
Test: atest
libcompositionengine_test:OutputUpdateProtectedContentStateTest
Change-Id: I11d7c73c8eee4a46383516e8eb672827b26314e6
Merged-In: I11d7c73c8eee4a46383516e8eb672827b26314e6
| -rw-r--r-- | services/surfaceflinger/CompositionEngine/src/Output.cpp | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp | 65 |
2 files changed, 67 insertions, 1 deletions
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 1205a2ce71..6314d2830f 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -1213,7 +1213,8 @@ void Output::updateProtectedContentState() { if (outputState.isSecure && supportsProtectedContent) { auto layers = getOutputLayersOrderedByZ(); bool needsProtected = std::any_of(layers.begin(), layers.end(), [](auto* layer) { - return layer->getLayerFE().getCompositionState()->hasProtectedContent; + return layer->getLayerFE().getCompositionState()->hasProtectedContent + && layer->requiresClientComposition(); }); if (needsProtected != mRenderSurface->isProtected()) { mRenderSurface->setProtected(needsProtected); diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index bf2d568503..774dc91a9e 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -3992,6 +3992,7 @@ struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeS Layer() { EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState)); EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE)); + EXPECT_CALL(mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); } StrictMock<mock::OutputLayer> mOutputLayer; @@ -4970,5 +4971,69 @@ TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]); } +/* + * Output::updateProtectedContentState() + */ + +struct OutputUpdateProtectedContentStateTest : public testing::Test { + struct OutputPartialMock : public OutputPartialMockBase { + // Sets up the helper functions called by the function under test to use + // mock implementations. + MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&()); + }; + + OutputUpdateProtectedContentStateTest() { + mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface)); + EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine)); + EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine)); + EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0)) + .WillRepeatedly(Return(&mLayer1.mOutputLayer)); + EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1)) + .WillRepeatedly(Return(&mLayer2.mOutputLayer)); + } + + struct Layer { + Layer() { + EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState)); + EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE)); + } + + StrictMock<mock::OutputLayer> mOutputLayer; + sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make(); + LayerFECompositionState mLayerFEState; + }; + + mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>(); + StrictMock<OutputPartialMock> mOutput; + StrictMock<mock::CompositionEngine> mCompositionEngine; + StrictMock<renderengine::mock::RenderEngine> mRenderEngine; + Layer mLayer1; + Layer mLayer2; +}; + +TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByHWC) { + mOutput.mState.isSecure = true; + mLayer1.mLayerFEState.hasProtectedContent = false; + mLayer2.mLayerFEState.hasProtectedContent = true; + EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true)); + EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false)); + EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); + EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false)); + mOutput.updateProtectedContentState(); +} + +TEST_F(OutputUpdateProtectedContentStateTest, ifProtectedContentLayerComposeByClient) { + mOutput.mState.isSecure = true; + mLayer1.mLayerFEState.hasProtectedContent = false; + mLayer2.mLayerFEState.hasProtectedContent = true; + EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true)); + EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false)); + EXPECT_CALL(*mRenderSurface, setProtected(true)); + EXPECT_CALL(mLayer1.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); + EXPECT_CALL(mLayer2.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true)); + mOutput.updateProtectedContentState(); +} + } // namespace } // namespace android::compositionengine |