Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/GpuCompositionResult.h +0 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,6 @@ namespace android::compositionengine::impl { struct GpuCompositionResult { // True if composition strategy was predicted successfully. bool succeeded = false; // Composition ready fence. base::unique_fd fence{}; Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h +12 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,18 @@ struct OutputCompositionState { // This is slightly distinct from nits, in that nits cannot be passed to hw composer. std::optional<float> displayBrightness = std::nullopt; enum class CompositionStrategyPredictionState : uint32_t { // Composition strategy prediction did not run for this frame. DISABLED = 0, // Composition strategy predicted successfully for this frame. SUCCESS = 1, // Composition strategy prediction failed for this frame. FAIL = 2, }; CompositionStrategyPredictionState strategyPrediction = CompositionStrategyPredictionState::DISABLED; // Debugging void dump(std::string& result) const; }; Loading services/surfaceflinger/CompositionEngine/src/Output.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -58,7 +58,8 @@ namespace android::compositionengine { Output::~Output() = default; namespace impl { using CompositionStrategyPredictionState = OutputCompositionState::CompositionStrategyPredictionState; namespace { template <typename T> Loading Loading @@ -970,6 +971,7 @@ void Output::prepareFrame() { std::optional<android::HWComposer::DeviceRequestedChanges> changes; bool success = chooseCompositionStrategy(&changes); resetCompositionStrategy(); outputState.strategyPrediction = CompositionStrategyPredictionState::DISABLED; outputState.previousDeviceRequestedChanges = changes; outputState.previousDeviceRequestedSuccess = success; if (success) { Loading Loading @@ -1012,7 +1014,8 @@ GpuCompositionResult Output::prepareFrameAsync(const CompositionRefreshArgs& ref auto chooseCompositionSuccess = hwcResult.get(); const bool predictionSucceeded = dequeueSucceeded && changes == previousChanges; compositionResult.succeeded = predictionSucceeded; state.strategyPrediction = predictionSucceeded ? CompositionStrategyPredictionState::SUCCESS : CompositionStrategyPredictionState::FAIL; if (!predictionSucceeded) { ATRACE_NAME("CompositionStrategyPredictionMiss"); resetCompositionStrategy(); Loading Loading @@ -1056,15 +1059,15 @@ void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& void Output::finishFrame(const CompositionRefreshArgs& refreshArgs, GpuCompositionResult&& result) { ATRACE_CALL(); ALOGV(__FUNCTION__); if (!getState().isEnabled) { const auto& outputState = getState(); if (!outputState.isEnabled) { return; } std::optional<base::unique_fd> optReadyFence; std::shared_ptr<renderengine::ExternalTexture> buffer; base::unique_fd bufferFence; if (result.succeeded) { if (outputState.strategyPrediction == CompositionStrategyPredictionState::SUCCESS) { optReadyFence = std::move(result.fence); } else { if (result.bufferAvailable()) { Loading services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,19 @@ #include <compositionengine/impl/OutputCompositionState.h> namespace android::compositionengine::impl { using CompositionStrategyPredictionState = OutputCompositionState::CompositionStrategyPredictionState; std::string toString(CompositionStrategyPredictionState state) { switch (state) { case CompositionStrategyPredictionState::DISABLED: return "Disabled"; case CompositionStrategyPredictionState::SUCCESS: return "Success"; case CompositionStrategyPredictionState::FAIL: return "Fail"; } } void OutputCompositionState::dump(std::string& out) const { out.append(" "); Loading Loading @@ -56,6 +69,7 @@ void OutputCompositionState::dump(std::string& out) const { dumpVal(out, "sdrWhitePointNits", sdrWhitePointNits); dumpVal(out, "clientTargetBrightness", clientTargetBrightness); dumpVal(out, "displayBrightness", displayBrightness); dumpVal(out, "compositionStrategyPredictionState", toString(strategyPrediction)); out.append("\n"); } Loading services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ const mat4 kNonIdentityQuarter = mat4() * 0.25f; constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting = static_cast<OutputColorSetting>(0x100); using CompositionStrategyPredictionState = android::compositionengine::impl:: OutputCompositionState::CompositionStrategyPredictionState; struct OutputPartialMockBase : public impl::Output { // compositionengine::Output overrides const OutputCompositionState& getState() const override { return mState; } Loading Loading @@ -1024,6 +1027,7 @@ TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurf EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)); mOutput.prepareFrame(); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED); } // Note: Use OutputTest and not OutputPrepareFrameTest, so the real Loading @@ -1039,6 +1043,7 @@ TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) { EXPECT_TRUE(mOutput->getState().usesClientComposition); EXPECT_FALSE(mOutput->getState().usesDeviceComposition); EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED); } struct OutputPrepareFrameAsyncTest : public testing::Test { Loading Loading @@ -1093,7 +1098,7 @@ TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRende EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _)); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_TRUE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS); EXPECT_FALSE(result.bufferAvailable()); } Loading @@ -1116,7 +1121,7 @@ TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) { Return(ByMove(p.get_future())))); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_FALSE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL); EXPECT_FALSE(result.bufferAvailable()); } Loading Loading @@ -1146,7 +1151,7 @@ TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepare EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _)); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_FALSE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL); EXPECT_TRUE(result.bufferAvailable()); } Loading Loading @@ -1178,7 +1183,7 @@ TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) { EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _)); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_FALSE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL); EXPECT_TRUE(result.bufferAvailable()); } Loading Loading @@ -3047,22 +3052,21 @@ TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) { TEST_F(OutputFinishFrameTest, predictionSucceeded) { mOutput.mState.isEnabled = true; mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS; InSequence seq; EXPECT_CALL(*mRenderSurface, queueBuffer(_)); impl::GpuCompositionResult result; result.succeeded = true; mOutput.finishFrame(mRefreshArgs, std::move(result)); } TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) { mOutput.mState.isEnabled = true; mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL; InSequence seq; impl::GpuCompositionResult result; result.succeeded = false; result.buffer = std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, Loading Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/GpuCompositionResult.h +0 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,6 @@ namespace android::compositionengine::impl { struct GpuCompositionResult { // True if composition strategy was predicted successfully. bool succeeded = false; // Composition ready fence. base::unique_fd fence{}; Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h +12 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,18 @@ struct OutputCompositionState { // This is slightly distinct from nits, in that nits cannot be passed to hw composer. std::optional<float> displayBrightness = std::nullopt; enum class CompositionStrategyPredictionState : uint32_t { // Composition strategy prediction did not run for this frame. DISABLED = 0, // Composition strategy predicted successfully for this frame. SUCCESS = 1, // Composition strategy prediction failed for this frame. FAIL = 2, }; CompositionStrategyPredictionState strategyPrediction = CompositionStrategyPredictionState::DISABLED; // Debugging void dump(std::string& result) const; }; Loading
services/surfaceflinger/CompositionEngine/src/Output.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -58,7 +58,8 @@ namespace android::compositionengine { Output::~Output() = default; namespace impl { using CompositionStrategyPredictionState = OutputCompositionState::CompositionStrategyPredictionState; namespace { template <typename T> Loading Loading @@ -970,6 +971,7 @@ void Output::prepareFrame() { std::optional<android::HWComposer::DeviceRequestedChanges> changes; bool success = chooseCompositionStrategy(&changes); resetCompositionStrategy(); outputState.strategyPrediction = CompositionStrategyPredictionState::DISABLED; outputState.previousDeviceRequestedChanges = changes; outputState.previousDeviceRequestedSuccess = success; if (success) { Loading Loading @@ -1012,7 +1014,8 @@ GpuCompositionResult Output::prepareFrameAsync(const CompositionRefreshArgs& ref auto chooseCompositionSuccess = hwcResult.get(); const bool predictionSucceeded = dequeueSucceeded && changes == previousChanges; compositionResult.succeeded = predictionSucceeded; state.strategyPrediction = predictionSucceeded ? CompositionStrategyPredictionState::SUCCESS : CompositionStrategyPredictionState::FAIL; if (!predictionSucceeded) { ATRACE_NAME("CompositionStrategyPredictionMiss"); resetCompositionStrategy(); Loading Loading @@ -1056,15 +1059,15 @@ void Output::devOptRepaintFlash(const compositionengine::CompositionRefreshArgs& void Output::finishFrame(const CompositionRefreshArgs& refreshArgs, GpuCompositionResult&& result) { ATRACE_CALL(); ALOGV(__FUNCTION__); if (!getState().isEnabled) { const auto& outputState = getState(); if (!outputState.isEnabled) { return; } std::optional<base::unique_fd> optReadyFence; std::shared_ptr<renderengine::ExternalTexture> buffer; base::unique_fd bufferFence; if (result.succeeded) { if (outputState.strategyPrediction == CompositionStrategyPredictionState::SUCCESS) { optReadyFence = std::move(result.fence); } else { if (result.bufferAvailable()) { Loading
services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,19 @@ #include <compositionengine/impl/OutputCompositionState.h> namespace android::compositionengine::impl { using CompositionStrategyPredictionState = OutputCompositionState::CompositionStrategyPredictionState; std::string toString(CompositionStrategyPredictionState state) { switch (state) { case CompositionStrategyPredictionState::DISABLED: return "Disabled"; case CompositionStrategyPredictionState::SUCCESS: return "Success"; case CompositionStrategyPredictionState::FAIL: return "Fail"; } } void OutputCompositionState::dump(std::string& out) const { out.append(" "); Loading Loading @@ -56,6 +69,7 @@ void OutputCompositionState::dump(std::string& out) const { dumpVal(out, "sdrWhitePointNits", sdrWhitePointNits); dumpVal(out, "clientTargetBrightness", clientTargetBrightness); dumpVal(out, "displayBrightness", displayBrightness); dumpVal(out, "compositionStrategyPredictionState", toString(strategyPrediction)); out.append("\n"); } Loading
services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +11 −7 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ const mat4 kNonIdentityQuarter = mat4() * 0.25f; constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting = static_cast<OutputColorSetting>(0x100); using CompositionStrategyPredictionState = android::compositionengine::impl:: OutputCompositionState::CompositionStrategyPredictionState; struct OutputPartialMockBase : public impl::Output { // compositionengine::Output overrides const OutputCompositionState& getState() const override { return mState; } Loading Loading @@ -1024,6 +1027,7 @@ TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurf EXPECT_CALL(*mRenderSurface, prepareFrame(false, true)); mOutput.prepareFrame(); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED); } // Note: Use OutputTest and not OutputPrepareFrameTest, so the real Loading @@ -1039,6 +1043,7 @@ TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) { EXPECT_TRUE(mOutput->getState().usesClientComposition); EXPECT_FALSE(mOutput->getState().usesDeviceComposition); EXPECT_EQ(mOutput->getState().strategyPrediction, CompositionStrategyPredictionState::DISABLED); } struct OutputPrepareFrameAsyncTest : public testing::Test { Loading Loading @@ -1093,7 +1098,7 @@ TEST_F(OutputPrepareFrameAsyncTest, delegatesToChooseCompositionStrategyAndRende EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _)); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_TRUE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::SUCCESS); EXPECT_FALSE(result.bufferAvailable()); } Loading @@ -1116,7 +1121,7 @@ TEST_F(OutputPrepareFrameAsyncTest, skipCompositionOnDequeueFailure) { Return(ByMove(p.get_future())))); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_FALSE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL); EXPECT_FALSE(result.bufferAvailable()); } Loading Loading @@ -1146,7 +1151,7 @@ TEST_F(OutputPrepareFrameAsyncTest, chooseCompositionStrategyFailureCallsPrepare EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _)); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_FALSE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL); EXPECT_TRUE(result.bufferAvailable()); } Loading Loading @@ -1178,7 +1183,7 @@ TEST_F(OutputPrepareFrameAsyncTest, predictionMiss) { EXPECT_CALL(mOutput, composeSurfaces(_, Ref(mRefreshArgs), _, _)); impl::GpuCompositionResult result = mOutput.prepareFrameAsync(mRefreshArgs); EXPECT_FALSE(result.succeeded); EXPECT_EQ(mOutput.getState().strategyPrediction, CompositionStrategyPredictionState::FAIL); EXPECT_TRUE(result.bufferAvailable()); } Loading Loading @@ -3047,22 +3052,21 @@ TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) { TEST_F(OutputFinishFrameTest, predictionSucceeded) { mOutput.mState.isEnabled = true; mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::SUCCESS; InSequence seq; EXPECT_CALL(*mRenderSurface, queueBuffer(_)); impl::GpuCompositionResult result; result.succeeded = true; mOutput.finishFrame(mRefreshArgs, std::move(result)); } TEST_F(OutputFinishFrameTest, predictionFailedAndBufferIsReused) { mOutput.mState.isEnabled = true; mOutput.mState.strategyPrediction = CompositionStrategyPredictionState::FAIL; InSequence seq; impl::GpuCompositionResult result; result.succeeded = false; result.buffer = std::make_shared<renderengine::mock::FakeExternalTexture>(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, Loading