diff options
author | 2024-12-03 22:10:45 -0800 | |
---|---|---|
committer | 2025-01-06 10:53:26 -0800 | |
commit | 10fc8990be2c0b81d29b3241eff3cb7994397e92 (patch) | |
tree | 9dc4ffc9d50f689c3440ad5934d047278ceec73f | |
parent | edc714653a4f690c34ff6897e3ae4d1e79d1d38e (diff) |
[Lut screenshot] backend implementation v2
Relnote: real implementation to call getLuts() binder in screenshot.
1. screenshot compositionengine doesn't have valid hwc composer object,
we modify `setHwComposer` function to allow hwcomposer object to be
used in multiple places. and set hwcomposer to screenshot
compositionengine.
2. extend compositionengine::LayerFE::LayerSettings to include layer
sequence number, and we use this unique value to identify which Luts
should be used for which layer.
Bug: 352585077
Test: libcompositionengine_test; libsurfaceflinger_unittest
Flag: android.hardware.flags.luts_api
Change-Id: I4ef43bfd515541d23a8de8785f04e3a21c46b410
12 files changed, 95 insertions, 12 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h index e32cc02974..fd58191ed2 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h @@ -53,7 +53,7 @@ public: createLayerFECompositionState() = 0; virtual HWComposer& getHwComposer() const = 0; - virtual void setHwComposer(std::unique_ptr<HWComposer>) = 0; + virtual void setHwComposer(HWComposer*) = 0; virtual renderengine::RenderEngine& getRenderEngine() const = 0; virtual void setRenderEngine(renderengine::RenderEngine*) = 0; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h index cda4edc216..20aceb1a82 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h @@ -131,6 +131,9 @@ public: // Currently latched frame number, 0 if invalid. uint64_t frameNumber = 0; + + // layer serial number, -1 if invalid. + int32_t sequence = -1; }; // Describes the states of the release fence. Checking the states allows checks diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h index 45208dd3c7..2992b6d843 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h @@ -31,7 +31,7 @@ public: override; HWComposer& getHwComposer() const override; - void setHwComposer(std::unique_ptr<HWComposer>) override; + void setHwComposer(HWComposer*) override; renderengine::RenderEngine& getRenderEngine() const override; void setRenderEngine(renderengine::RenderEngine*) override; @@ -59,7 +59,7 @@ public: void setNeedsAnotherUpdateForTest(bool); private: - std::unique_ptr<HWComposer> mHwComposer; + HWComposer* mHwComposer; renderengine::RenderEngine* mRenderEngine; std::shared_ptr<TimeStats> mTimeStats; bool mNeedsAnotherUpdate = false; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h index a1b728232c..bb1a2227be 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h @@ -37,7 +37,7 @@ public: std::unique_ptr<compositionengine::LayerFECompositionState>()); MOCK_CONST_METHOD0(getHwComposer, HWComposer&()); - MOCK_METHOD1(setHwComposer, void(std::unique_ptr<HWComposer>)); + MOCK_METHOD1(setHwComposer, void(HWComposer*)); MOCK_CONST_METHOD0(getRenderEngine, renderengine::RenderEngine&()); MOCK_METHOD1(setRenderEngine, void(renderengine::RenderEngine*)); diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp index cfcce473a2..989f8e3c5e 100644 --- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp +++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp @@ -58,11 +58,11 @@ CompositionEngine::createLayerFECompositionState() { } HWComposer& CompositionEngine::getHwComposer() const { - return *mHwComposer.get(); + return *mHwComposer; } -void CompositionEngine::setHwComposer(std::unique_ptr<HWComposer> hwComposer) { - mHwComposer = std::move(hwComposer); +void CompositionEngine::setHwComposer(HWComposer* hwComposer) { + mHwComposer = hwComposer; } renderengine::RenderEngine& CompositionEngine::getRenderEngine() const { diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp index 3e0c390a5d..ad65c4422e 100644 --- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp @@ -61,7 +61,7 @@ TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) { TEST_F(CompositionEngineTest, canSetHWComposer) { android::mock::HWComposer* hwc = new StrictMock<android::mock::HWComposer>(); - mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(hwc)); + mEngine.setHwComposer(static_cast<android::HWComposer*>(hwc)); EXPECT_EQ(hwc, &mEngine.getHwComposer()); } diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp index fea7671af2..dbb1ed3a9f 100644 --- a/services/surfaceflinger/LayerFE.cpp +++ b/services/surfaceflinger/LayerFE.cpp @@ -191,6 +191,7 @@ void LayerFE::prepareClearClientComposition(LayerFE::LayerSettings& layerSetting layerSettings.disableBlending = true; layerSettings.bufferId = 0; layerSettings.frameNumber = 0; + layerSettings.sequence = -1; // If layer is blacked out, force alpha to 1 so that we draw a black color layer. layerSettings.alpha = blackout ? 1.0f : 0.0f; @@ -262,6 +263,7 @@ void LayerFE::prepareBufferStateClientComposition( layerSettings.source.buffer.maxLuminanceNits = maxLuminance; layerSettings.frameNumber = mSnapshot->frameNumber; layerSettings.bufferId = mSnapshot->externalTexture->getId(); + layerSettings.sequence = mSnapshot->sequence; const bool useFiltering = targetSettings.needsFiltering || mSnapshot->geomLayerTransform.needsBilinearFiltering(); diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp index 41a9a1bb22..5f71b88d01 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -16,11 +16,13 @@ #include "ScreenCaptureOutput.h" #include "ScreenCaptureRenderSurface.h" +#include "common/include/common/FlagManager.h" #include "ui/Rotation.h" #include <compositionengine/CompositionEngine.h> #include <compositionengine/DisplayColorProfileCreationArgs.h> #include <compositionengine/impl/DisplayColorProfile.h> +#include <ui/HdrRenderTypeUtils.h> #include <ui/Rotation.h> namespace android { @@ -104,14 +106,84 @@ renderengine::DisplaySettings ScreenCaptureOutput::generateClientCompositionDisp return clientCompositionDisplay; } +std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> +ScreenCaptureOutput::generateLuts() { + std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> lutsMapper; + if (FlagManager::getInstance().luts_api()) { + std::vector<sp<GraphicBuffer>> buffers; + std::vector<int32_t> layerIds; + + for (const auto* layer : getOutputLayersOrderedByZ()) { + const auto& layerState = layer->getState(); + const auto* layerFEState = layer->getLayerFE().getCompositionState(); + auto pixelFormat = layerFEState->buffer + ? std::make_optional( + static_cast<ui::PixelFormat>(layerFEState->buffer->getPixelFormat())) + : std::nullopt; + const auto hdrType = getHdrRenderType(layerState.dataspace, pixelFormat, + layerFEState->desiredHdrSdrRatio); + if (layerFEState->buffer && !layerFEState->luts && + hdrType == HdrRenderType::GENERIC_HDR) { + buffers.push_back(layerFEState->buffer); + layerIds.push_back(layer->getLayerFE().getSequence()); + } + } + + std::vector<aidl::android::hardware::graphics::composer3::Luts> luts; + if (auto displayDevice = mRenderArea.getDisplayDevice()) { + const auto id = PhysicalDisplayId::tryCast(displayDevice->getId()); + if (id) { + auto& hwc = getCompositionEngine().getHwComposer(); + hwc.getLuts(*id, buffers, &luts); + } + } + + if (buffers.size() == luts.size()) { + for (size_t i = 0; i < luts.size(); i++) { + lutsMapper[layerIds[i]] = std::move(luts[i]); + } + } + } + return lutsMapper; +} + std::vector<compositionengine::LayerFE::LayerSettings> ScreenCaptureOutput::generateClientCompositionRequests( bool supportsProtectedContent, ui::Dataspace outputDataspace, std::vector<compositionengine::LayerFE*>& outLayerFEs) { + // This map maps the layer unique id to a Lut + std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> lutsMapper = + generateLuts(); + auto clientCompositionLayers = compositionengine::impl::Output:: generateClientCompositionRequests(supportsProtectedContent, outputDataspace, outLayerFEs); + for (auto& layer : clientCompositionLayers) { + if (lutsMapper.find(layer.sequence) != lutsMapper.end()) { + auto& aidlLuts = lutsMapper[layer.sequence]; + if (aidlLuts.pfd.get() >= 0 && aidlLuts.offsets) { + std::vector<int32_t> offsets = *aidlLuts.offsets; + std::vector<int32_t> dimensions; + dimensions.reserve(offsets.size()); + std::vector<int32_t> sizes; + sizes.reserve(offsets.size()); + std::vector<int32_t> keys; + keys.reserve(offsets.size()); + for (size_t j = 0; j < offsets.size(); j++) { + dimensions.emplace_back( + static_cast<int32_t>(aidlLuts.lutProperties[j].dimension)); + sizes.emplace_back(aidlLuts.lutProperties[j].size); + keys.emplace_back( + static_cast<int32_t>(aidlLuts.lutProperties[j].samplingKeys[0])); + } + layer.luts = std::make_shared<gui::DisplayLuts>(base::unique_fd( + aidlLuts.pfd.dup().get()), + offsets, dimensions, sizes, keys); + } + } + } + if (mRegionSampling) { for (auto& layer : clientCompositionLayers) { layer.backgroundBlurRadius = 0; diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h index c233ead575..444a28fbf0 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.h +++ b/services/surfaceflinger/ScreenCaptureOutput.h @@ -20,6 +20,7 @@ #include <compositionengine/RenderSurface.h> #include <compositionengine/impl/Output.h> #include <ui/Rect.h> +#include <unordered_map> #include "RenderArea.h" @@ -65,6 +66,7 @@ protected: const std::shared_ptr<renderengine::ExternalTexture>& buffer) const override; private: + std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> generateLuts(); const RenderArea& mRenderArea; const compositionengine::Output::ColorProfile& mColorProfile; const bool mRegionSampling; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index dd1119a5d1..1c185b1dd1 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -920,7 +920,8 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { mCompositionEngine->setTimeStats(mTimeStats); - mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName)); + mHWComposer = getFactory().createHWComposer(mHwcServiceName); + mCompositionEngine->setHwComposer(mHWComposer.get()); auto& composer = mCompositionEngine->getHwComposer(); composer.setCallback(*this); mDisplayModeController.setHwComposer(&composer); @@ -7697,6 +7698,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( std::unique_ptr<compositionengine::CompositionEngine> compositionEngine = mFactory.createCompositionEngine(); compositionEngine->setRenderEngine(mRenderEngine.get()); + compositionEngine->setHwComposer(mHWComposer.get()); std::vector<sp<compositionengine::LayerFE>> layerFEs; layerFEs.reserve(layers.size()); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c2e687f385..824a55a652 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1368,6 +1368,7 @@ private: std::atomic<int> mNumTrustedPresentationListeners = 0; std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine; + std::unique_ptr<HWComposer> mHWComposer; CompositionCoveragePerDisplay mCompositionCoverage; diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 3455c13bb7..c2e88688e0 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -184,8 +184,8 @@ public: } void setupComposer(std::unique_ptr<Hwc2::Composer> composer) { - mFlinger->mCompositionEngine->setHwComposer( - std::make_unique<impl::HWComposer>(std::move(composer))); + mFlinger->mHWComposer = std::make_unique<impl::HWComposer>(std::move(composer)); + mFlinger->mCompositionEngine->setHwComposer(mFlinger->mHWComposer.get()); mFlinger->mDisplayModeController.setHwComposer( &mFlinger->mCompositionEngine->getHwComposer()); } @@ -771,7 +771,8 @@ public: mutableCurrentState().displays.clear(); mutableDrawingState().displays.clear(); mFlinger->mScheduler.reset(); - mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>()); + mFlinger->mHWComposer = std::unique_ptr<HWComposer>(); + mFlinger->mCompositionEngine->setHwComposer(mFlinger->mHWComposer.get()); mFlinger->mRenderEngine = std::unique_ptr<renderengine::RenderEngine>(); mFlinger->mCompositionEngine->setRenderEngine(mFlinger->mRenderEngine.get()); mFlinger->mTransactionTracing.reset(); |