[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
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
index e32cc02..fd58191 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
@@ -53,7 +53,7 @@
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 cda4edc..20aceb1 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -131,6 +131,9 @@
// 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 45208dd..2992b6d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
@@ -31,7 +31,7 @@
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 @@
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 a1b7282..bb1a222 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
@@ -37,7 +37,7 @@
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 cfcce47..989f8e3 100644
--- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -58,11 +58,11 @@
}
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 3e0c390..ad65c44 100644
--- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -61,7 +61,7 @@
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 fea7671..dbb1ed3 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -191,6 +191,7 @@
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 @@
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 41a9a1b..5f71b88 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 @@
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 c233ead..444a28f 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 @@
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 dd1119a..1c185b1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -920,7 +920,8 @@
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 @@
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 c2e687f..824a55a6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1368,6 +1368,7 @@
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 3455c13..c2e8868 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -184,8 +184,8 @@
}
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 @@
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();