summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h10
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp27
-rw-r--r--services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp1
-rw-r--r--services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp14
-rw-r--r--services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp2
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp9
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp13
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp33
10 files changed, 86 insertions, 26 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index a3e84e2a9c..6c02759bf8 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -16,10 +16,7 @@
#pragma once
-#include <cstdint>
-#include <optional>
-#include <string>
-
+#include <compositionengine/ProjectionSpace.h>
#include <compositionengine/impl/HwcBufferCache.h>
#include <renderengine/Mesh.h>
#include <ui/FloatRect.h>
@@ -27,6 +24,10 @@
#include <ui/Rect.h>
#include <ui/Region.h>
+#include <cstdint>
+#include <optional>
+#include <string>
+
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
@@ -90,6 +91,7 @@ struct OutputLayerCompositionState {
sp<Fence> acquireFence = nullptr;
Rect displayFrame = {};
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
+ ProjectionSpace displaySpace;
} overrideInfo;
/*
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
index cfb496269c..fae17d9747 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
@@ -64,6 +64,7 @@ public:
size_t getAge() const { return mAge; }
const sp<GraphicBuffer>& getBuffer() const { return mTexture.getBuffer(); }
const sp<Fence>& getDrawFence() const { return mDrawFence; }
+ const ProjectionSpace& getOutputSpace() const { return mOutputSpace; }
ui::Dataspace getOutputDataspace() const { return mOutputDataspace; }
NonBufferHash getNonBufferHash() const;
@@ -134,6 +135,7 @@ private:
Texture mTexture;
sp<Fence> mDrawFence;
+ ProjectionSpace mOutputSpace;
ui::Dataspace mOutputDataspace;
ui::Transform::RotationFlags mOrientation = ui::Transform::ROT_0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
index e21b5bc433..313a180f4f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Flattener.h
@@ -16,6 +16,7 @@
#pragma once
+#include <compositionengine/Output.h>
#include <compositionengine/impl/planner/CachedSet.h>
#include <compositionengine/impl/planner/LayerState.h>
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index e662491791..48327931db 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -381,8 +381,9 @@ void OutputLayer::writeOutputDependentGeometryStateToHWC(
outputDependentState.z, to_string(error).c_str(), static_cast<int32_t>(error));
}
- // Solid-color layers should always use an identity transform.
- const auto bufferTransform = requestedCompositionType != hal::Composition::SOLID_COLOR
+ // Solid-color layers and overridden buffers should always use an identity transform.
+ const auto bufferTransform = (requestedCompositionType != hal::Composition::SOLID_COLOR &&
+ getState().overrideInfo.buffer == nullptr)
? outputDependentState.bufferTransform
: static_cast<hal::Transform>(0);
if (auto error = hwcLayer->setTransform(static_cast<hal::Transform>(bufferTransform));
@@ -674,16 +675,26 @@ std::vector<LayerFE::LayerSettings> OutputLayer::getOverrideCompositionList() co
return {};
}
+ // Compute the geometry boundaries in layer stack space: we need to transform from the
+ // framebuffer space of the override buffer to layer space.
+ const ProjectionSpace& layerSpace = getOutput().getState().layerStackSpace;
+ const ui::Transform transform = getState().overrideInfo.displaySpace.getTransform(layerSpace);
+ const Rect boundaries = transform.transform(getState().overrideInfo.displayFrame);
+
LayerFE::LayerSettings settings;
settings.geometry = renderengine::Geometry{
- .boundaries = getState().overrideInfo.displayFrame.toFloatRect(),
+ .boundaries = boundaries.toFloatRect(),
};
settings.bufferId = getState().overrideInfo.buffer->getId();
- settings.source =
- renderengine::PixelSource{.buffer = renderengine::Buffer{
- .buffer = getState().overrideInfo.buffer,
- .fence = getState().overrideInfo.acquireFence,
- }};
+ settings.source = renderengine::PixelSource{
+ .buffer = renderengine::Buffer{
+ .buffer = getState().overrideInfo.buffer,
+ .fence = getState().overrideInfo.acquireFence,
+ // If the transform from layer space to display space contains a rotation, we
+ // need to undo the rotation in the texture transform
+ .textureTransform =
+ ui::Transform(transform.inverse().getOrientation(), 1, 1).asMatrix4(),
+ }};
settings.sourceDataspace = getState().overrideInfo.dataspace;
settings.alpha = 1.0f;
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
index 45dce9842b..0f6804d0ab 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp
@@ -72,6 +72,7 @@ void OutputLayerCompositionState::dump(std::string& out) const {
dumpVal(out, "override acquire fence", overrideInfo.acquireFence.get());
dumpVal(out, "override display frame", overrideInfo.displayFrame);
dumpVal(out, "override dataspace", toString(overrideInfo.dataspace), overrideInfo.dataspace);
+ dumpVal(out, "override display space", to_string(overrideInfo.displaySpace));
if (hwc) {
dumpHwc(*hwc, out);
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index e8c6de0eed..b95a3db547 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -152,20 +152,20 @@ void CachedSet::updateAge(std::chrono::steady_clock::time_point now) {
void CachedSet::render(renderengine::RenderEngine& renderEngine,
const OutputCompositionState& outputState) {
+ const Rect& viewport = outputState.layerStackSpace.content;
const ui::Dataspace& outputDataspace = outputState.dataspace;
const ui::Transform::RotationFlags orientation =
- ui::Transform::toRotationFlags(outputState.displaySpace.orientation);
+ ui::Transform::toRotationFlags(outputState.framebufferSpace.orientation);
renderengine::DisplaySettings displaySettings{
.physicalDisplay = Rect(0, 0, mBounds.getWidth(), mBounds.getHeight()),
- .clip = mBounds,
- .orientation = orientation,
+ .clip = viewport,
.outputDataspace = outputDataspace,
+ .orientation = orientation,
};
Region clearRegion = Region::INVALID_REGION;
- Rect viewport = mBounds;
LayerFE::ClientCompositionTargetSettings targetSettings{
- .clip = Region(mBounds),
+ .clip = Region(viewport),
.needsFiltering = false,
.isSecure = true,
.supportsProtectedContent = false,
@@ -223,6 +223,10 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine,
if (result == NO_ERROR) {
mTexture.setBuffer(buffer, &renderEngine);
mDrawFence = new Fence(drawFence.release());
+ mOutputSpace = ProjectionSpace(ui::Size(outputState.framebufferSpace.bounds.getWidth(),
+ outputState.framebufferSpace.bounds.getHeight()),
+ mBounds);
+ mOutputSpace.orientation = outputState.framebufferSpace.orientation;
mOutputDataspace = outputDataspace;
mOrientation = orientation;
}
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
index 06f7e7a256..439cfb3507 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
@@ -213,6 +213,7 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers
.acquireFence = mNewCachedSet->getDrawFence(),
.displayFrame = mNewCachedSet->getBounds(),
.dataspace = mNewCachedSet->getOutputDataspace(),
+ .displaySpace = mNewCachedSet->getOutputSpace(),
};
++incomingLayerIter;
}
@@ -244,6 +245,7 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers
.acquireFence = currentLayerIter->getDrawFence(),
.displayFrame = currentLayerIter->getBounds(),
.dataspace = currentLayerIter->getOutputDataspace(),
+ .displaySpace = currentLayerIter->getOutputSpace(),
};
++incomingLayerIter;
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 83fb9e3f78..cbbc966790 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -690,6 +690,7 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
static constexpr uint32_t kZOrder = 21u;
static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
+ static constexpr Hwc2::Transform kOverrideBufferTransform = static_cast<Hwc2::Transform>(0);
static constexpr Hwc2::IComposerClient::BlendMode kBlendMode =
static_cast<Hwc2::IComposerClient::BlendMode>(41);
static constexpr float kAlpha = 51.f;
@@ -765,11 +766,12 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
}
void expectGeometryCommonCalls(Rect displayFrame = kDisplayFrame,
- FloatRect sourceCrop = kSourceCrop) {
+ FloatRect sourceCrop = kSourceCrop,
+ Hwc2::Transform bufferTransform = kBufferTransform) {
EXPECT_CALL(*mHwcLayer, setDisplayFrame(displayFrame)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setSourceCrop(sourceCrop)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setZOrder(kZOrder)).WillOnce(Return(kError));
- EXPECT_CALL(*mHwcLayer, setTransform(kBufferTransform)).WillOnce(Return(kError));
+ EXPECT_CALL(*mHwcLayer, setTransform(bufferTransform)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setBlendMode(kBlendMode)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setPlaneAlpha(kAlpha)).WillOnce(Return(kError));
@@ -1006,7 +1008,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) {
mLayerFEState.compositionType = Hwc2::IComposerClient::Composition::DEVICE;
includeOverrideInfo();
- expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideDisplayFrame.toFloatRect());
+ expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideDisplayFrame.toFloatRect(),
+ kOverrideBufferTransform);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace);
expectSetHdrMetadataAndBufferCalls(kOverrideBuffer, kOverrideFence);
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index 0e7ef71c65..d3c4b1f822 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -92,7 +92,9 @@ void CachedSetTest::SetUp() {
// set up minimium params needed for rendering
mOutputState.dataspace = ui::Dataspace::SRGB;
- mOutputState.displaySpace.orientation = ui::ROTATION_0;
+ mOutputState.framebufferSpace = ProjectionSpace(ui::Size(10, 20), Rect(10, 5));
+ mOutputState.framebufferSpace.orientation = ui::ROTATION_90;
+ mOutputState.layerStackSpace = ProjectionSpace(ui::Size(20, 10), Rect(5, 10));
}
}
@@ -294,7 +296,9 @@ TEST_F(CachedSetTest, render) {
const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
base::unique_fd*) -> size_t {
EXPECT_EQ(Rect(0, 0, 2, 2), displaySettings.physicalDisplay);
- EXPECT_EQ(Rect(0, 0, 2, 2), displaySettings.clip);
+ EXPECT_EQ(mOutputState.layerStackSpace.content, displaySettings.clip);
+ EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.orientation),
+ displaySettings.orientation);
EXPECT_EQ(0.5f, layers[0]->alpha);
EXPECT_EQ(0.75f, layers[1]->alpha);
EXPECT_EQ(ui::Dataspace::SRGB, displaySettings.outputDataspace);
@@ -309,6 +313,11 @@ TEST_F(CachedSetTest, render) {
cachedSet.render(mRenderEngine, mOutputState);
expectReadyBuffer(cachedSet);
+ EXPECT_EQ(Rect(0, 0, 2, 2), cachedSet.getOutputSpace().content);
+ EXPECT_EQ(Rect(mOutputState.framebufferSpace.bounds.getWidth(),
+ mOutputState.framebufferSpace.bounds.getHeight()),
+ cachedSet.getOutputSpace().bounds);
+
// Now check that appending a new cached set properly cleans up RenderEngine resources.
EXPECT_CALL(mRenderEngine, unbindExternalTextureBuffer(_));
CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
index 211b4dc1b4..1bbf11a163 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp
@@ -125,7 +125,8 @@ void FlattenerTest::SetUp() {
// set up minimium params needed for rendering
mOutputState.dataspace = ui::Dataspace::SRGB;
- mOutputState.displaySpace.orientation = ui::ROTATION_0;
+ mOutputState.framebufferSpace = ProjectionSpace(ui::Size(10, 20), Rect(10, 5));
+ mOutputState.framebufferSpace.orientation = ui::ROTATION_90;
}
}
@@ -254,6 +255,30 @@ TEST_F(FlattenerTest, flattenLayers_FlattenedLayersStayFlattenWhenNoUpdate) {
EXPECT_EQ(overrideBuffer2, overrideBuffer3);
}
+TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsProjectionSpace) {
+ auto& layerState1 = mTestLayers[0]->layerState;
+ const auto& overrideDisplaySpace =
+ layerState1->getOutputLayer()->getState().overrideInfo.displaySpace;
+
+ auto& layerState2 = mTestLayers[1]->layerState;
+
+ const std::vector<const LayerState*> layers = {
+ layerState1.get(),
+ layerState2.get(),
+ };
+
+ initializeFlattener(layers);
+
+ // make all layers inactive
+ mTime += 200ms;
+ expectAllLayersFlattened(layers);
+ EXPECT_EQ(overrideDisplaySpace.bounds,
+ Rect(mOutputState.framebufferSpace.bounds.getWidth(),
+ mOutputState.framebufferSpace.bounds.getHeight()));
+ EXPECT_EQ(overrideDisplaySpace.content, Rect(0, 0, 2, 2));
+ EXPECT_EQ(overrideDisplaySpace.orientation, mOutputState.framebufferSpace.orientation);
+}
+
TEST_F(FlattenerTest, flattenLayers_addLayerToFlattenedCauseReset) {
auto& layerState1 = mTestLayers[0]->layerState;
const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer;
@@ -405,7 +430,7 @@ TEST_F(FlattenerTest, flattenLayers_BufferUpdateForMiddleLayer) {
initializeOverrideBuffer(layers);
EXPECT_NE(getNonBufferHash(layers),
mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
- mOutputState.displaySpace.orientation = ui::ROTATION_90;
+ mOutputState.framebufferSpace.orientation = ui::ROTATION_90;
mFlattener->renderCachedSets(mRenderEngine, mOutputState);
EXPECT_NE(nullptr, overrideBuffer1);
@@ -418,7 +443,7 @@ TEST_F(FlattenerTest, flattenLayers_BufferUpdateForMiddleLayer) {
initializeOverrideBuffer(layers);
EXPECT_NE(getNonBufferHash(layers),
mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
- mOutputState.displaySpace.orientation = ui::ROTATION_180;
+ mOutputState.framebufferSpace.orientation = ui::ROTATION_180;
mFlattener->renderCachedSets(mRenderEngine, mOutputState);
EXPECT_NE(nullptr, overrideBuffer1);
@@ -445,7 +470,7 @@ TEST_F(FlattenerTest, flattenLayers_BufferUpdateForMiddleLayer) {
initializeOverrideBuffer(layers);
EXPECT_NE(getNonBufferHash(layers),
mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime));
- mOutputState.displaySpace.orientation = ui::ROTATION_270;
+ mOutputState.framebufferSpace.orientation = ui::ROTATION_270;
mFlattener->renderCachedSets(mRenderEngine, mOutputState);
EXPECT_NE(nullptr, overrideBuffer1);