diff options
12 files changed, 117 insertions, 13 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h index f113c34ba3..ae88e7839c 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h @@ -55,7 +55,6 @@ public: std::vector<LayerFE::LayerSettings> getOverrideCompositionList() const override; void dump(std::string&) const override; - virtual FloatRect calculateOutputSourceCrop() const; virtual Rect calculateOutputDisplayFrame() const; virtual uint32_t calculateOutputRelativeBufferTransform( diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h index 6c02759bf8..328613d146 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h @@ -92,6 +92,8 @@ struct OutputLayerCompositionState { Rect displayFrame = {}; ui::Dataspace dataspace{ui::Dataspace::UNKNOWN}; ProjectionSpace displaySpace; + Region damageRegion = Region::INVALID_REGION; + Region visibleRegion; } overrideInfo; /* diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h index 056408ebb7..afa02cd0c2 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h @@ -40,6 +40,7 @@ public: const LayerState* getState() const { return mState; } const std::string& getName() const { return mState->getName(); } Rect getDisplayFrame() const { return mState->getDisplayFrame(); } + const Region& getVisibleRegion() const { return mState->getVisibleRegion(); } const sp<GraphicBuffer>& getBuffer() const { return mState->getOutputLayer()->getLayerFE().getCompositionState()->buffer; } @@ -63,6 +64,7 @@ public: size_t getLayerCount() const { return mLayers.size(); } const Layer& getFirstLayer() const { return mLayers[0]; } const Rect& getBounds() const { return mBounds; } + const Region& getVisibleRegion() const { return mVisibleRegion; } size_t getAge() const { return mAge; } const sp<GraphicBuffer>& getBuffer() const { return mTexture.getBuffer(); } const sp<Fence>& getDrawFence() const { return mDrawFence; } @@ -94,6 +96,7 @@ public: boundingRegion.orSelf(mBounds); boundingRegion.orSelf(other.mBounds); mBounds = boundingRegion.getBounds(); + mVisibleRegion.orSelf(other.mVisibleRegion); } void incrementAge() { ++mAge; } @@ -109,6 +112,7 @@ private: std::chrono::steady_clock::time_point mLastUpdate = std::chrono::steady_clock::now(); std::vector<Layer> mLayers; Rect mBounds = Rect::EMPTY_RECT; + Region mVisibleRegion; size_t mAge = 0; class Texture { diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h index d005ca37a9..eff16a849a 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h @@ -196,6 +196,7 @@ public: int32_t getId() const { return mId.get(); } const std::string& getName() const { return mName.get(); } Rect getDisplayFrame() const { return mDisplayFrame.get(); } + const Region& getVisibleRegion() const { return mVisibleRegion.get(); } hardware::graphics::composer::hal::Composition getCompositionType() const { return mCompositionType.get(); } diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index fd06de5396..3f36a8feea 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp @@ -355,7 +355,7 @@ void OutputLayer::writeOutputDependentGeometryStateToHWC( Rect displayFrame = outputDependentState.displayFrame; FloatRect sourceCrop = outputDependentState.sourceCrop; - if (outputDependentState.overrideInfo.buffer != nullptr) { // adyabr + if (outputDependentState.overrideInfo.buffer != nullptr) { displayFrame = outputDependentState.overrideInfo.displayFrame; sourceCrop = displayFrame.toFloatRect(); } @@ -429,8 +429,10 @@ void OutputLayer::writeOutputDependentPerFrameStateToHWC(HWC2::Layer* hwcLayer) // TODO(lpique): b/121291683 outputSpaceVisibleRegion is output-dependent geometry // state and should not change every frame. - if (auto error = hwcLayer->setVisibleRegion(outputDependentState.outputSpaceVisibleRegion); - error != hal::Error::NONE) { + Region visibleRegion = outputDependentState.overrideInfo.buffer + ? Region(outputDependentState.overrideInfo.visibleRegion) + : outputDependentState.outputSpaceVisibleRegion; + if (auto error = hwcLayer->setVisibleRegion(visibleRegion); error != hal::Error::NONE) { ALOGE("[%s] Failed to set visible region: %s (%d)", getLayerFE().getDebugName(), to_string(error).c_str(), static_cast<int32_t>(error)); outputDependentState.outputSpaceVisibleRegion.dump(LOG_TAG); @@ -459,8 +461,11 @@ void OutputLayer::writeOutputIndependentPerFrameStateToHWC( to_string(error).c_str(), static_cast<int32_t>(error)); } - if (auto error = hwcLayer->setSurfaceDamage(outputIndependentState.surfaceDamage); - error != hal::Error::NONE) { + const Region& surfaceDamage = getState().overrideInfo.buffer + ? getState().overrideInfo.damageRegion + : outputIndependentState.surfaceDamage; + + if (auto error = hwcLayer->setSurfaceDamage(surfaceDamage); error != hal::Error::NONE) { ALOGE("[%s] Failed to set surface damage: %s (%d)", getLayerFE().getDebugName(), to_string(error).c_str(), static_cast<int32_t>(error)); outputIndependentState.surfaceDamage.dump(LOG_TAG); diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp index 0f6804d0ab..efd23dce98 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayerCompositionState.cpp @@ -73,6 +73,12 @@ void OutputLayerCompositionState::dump(std::string& out) const { 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)); + std::string damageRegionString; + overrideInfo.damageRegion.dump(damageRegionString, ""); + dumpVal(out, "override damage region", damageRegionString); + std::string visibleRegionString; + overrideInfo.visibleRegion.dump(visibleRegionString, ""); + dumpVal(out, "override visible region", visibleRegionString); if (hwc) { dumpHwc(*hwc, out); diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp index f58addb70b..6b5597f4f2 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -61,7 +61,8 @@ CachedSet::CachedSet(const LayerState* layer, std::chrono::steady_clock::time_po CachedSet::CachedSet(Layer layer) : mFingerprint(layer.getHash()), mLastUpdate(layer.getLastUpdate()), - mBounds(layer.getDisplayFrame()) { + mBounds(layer.getDisplayFrame()), + mVisibleRegion(layer.getVisibleRegion()) { mLayers.emplace_back(std::move(layer)); } @@ -73,6 +74,7 @@ void CachedSet::addLayer(const LayerState* layer, boundingRegion.orSelf(mBounds); boundingRegion.orSelf(layer->getDisplayFrame()); mBounds = boundingRegion.getBounds(); + mVisibleRegion.orSelf(layer->getVisibleRegion()); } NonBufferHash CachedSet::getNonBufferHash() const { diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp index aae49de8b2..ffca5baab7 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp @@ -212,6 +212,8 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers .displayFrame = mNewCachedSet->getBounds(), .dataspace = mNewCachedSet->getOutputDataspace(), .displaySpace = mNewCachedSet->getOutputSpace(), + .damageRegion = Region::INVALID_REGION, + .visibleRegion = mNewCachedSet->getVisibleRegion(), }; ++incomingLayerIter; } @@ -244,6 +246,8 @@ bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers .displayFrame = currentLayerIter->getBounds(), .dataspace = currentLayerIter->getOutputDataspace(), .displaySpace = currentLayerIter->getOutputSpace(), + .damageRegion = Region(), + .visibleRegion = currentLayerIter->getVisibleRegion(), }; ++incomingLayerIter; } diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp index 7d5be60695..8a4d161289 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp @@ -708,8 +708,10 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest { static const Rect kDisplayFrame; static const Rect kOverrideDisplayFrame; static const Region kOutputSpaceVisibleRegion; + static const Region kOverrideVisibleRegion; static const mat4 kColorTransform; static const Region kSurfaceDamage; + static const Region kOverrideSurfaceDamage; static const HdrMetadata kHdrMetadata; static native_handle_t* kSidebandStreamHandle; static const sp<GraphicBuffer> kBuffer; @@ -766,6 +768,8 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest { overrideInfo.acquireFence = kOverrideFence; overrideInfo.displayFrame = kOverrideDisplayFrame; overrideInfo.dataspace = kOverrideDataspace; + overrideInfo.damageRegion = kOverrideSurfaceDamage; + overrideInfo.visibleRegion = kOverrideVisibleRegion; } void expectGeometryCommonCalls(Rect displayFrame = kDisplayFrame, @@ -783,16 +787,16 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest { } void expectPerFrameCommonCalls(SimulateUnsupported unsupported = SimulateUnsupported::None, - ui::Dataspace dataspace = kDataspace) { - EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(kOutputSpaceVisibleRegion))) - .WillOnce(Return(kError)); + ui::Dataspace dataspace = kDataspace, + const Region& visibleRegion = kOutputSpaceVisibleRegion, + const Region& surfaceDamage = kSurfaceDamage) { + EXPECT_CALL(*mHwcLayer, setVisibleRegion(RegionEq(visibleRegion))).WillOnce(Return(kError)); EXPECT_CALL(*mHwcLayer, setDataspace(dataspace)).WillOnce(Return(kError)); EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform)) .WillOnce(Return(unsupported == SimulateUnsupported::ColorTransform ? hal::Error::UNSUPPORTED : hal::Error::NONE)); - EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(kSurfaceDamage))) - .WillOnce(Return(kError)); + EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(surfaceDamage))).WillOnce(Return(kError)); } void expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition compositionType) { @@ -843,11 +847,13 @@ const Rect OutputLayerWriteStateToHWCTest::kDisplayFrame{1001, 1002, 1003, 10044 const Rect OutputLayerWriteStateToHWCTest::kOverrideDisplayFrame{1002, 1003, 1004, 20044}; const Region OutputLayerWriteStateToHWCTest::kOutputSpaceVisibleRegion{ Rect{1005, 1006, 1007, 1008}}; +const Region OutputLayerWriteStateToHWCTest::kOverrideVisibleRegion{Rect{1006, 1007, 1008, 1009}}; const mat4 OutputLayerWriteStateToHWCTest::kColorTransform{ 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, }; const Region OutputLayerWriteStateToHWCTest::kSurfaceDamage{Rect{1025, 1026, 1027, 1028}}; +const Region OutputLayerWriteStateToHWCTest::kOverrideSurfaceDamage{Rect{1026, 1027, 1028, 1029}}; const HdrMetadata OutputLayerWriteStateToHWCTest::kHdrMetadata{{/* LightFlattenable */}, 1029}; native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle = reinterpret_cast<native_handle_t*>(1031); @@ -1015,7 +1021,8 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) { expectGeometryCommonCalls(kOverrideDisplayFrame, kOverrideDisplayFrame.toFloatRect(), kOverrideBufferTransform, kOverrideBlendMode, kOverrideAlpha); - expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace); + expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion, + kOverrideSurfaceDamage); 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 d3c4b1f822..f01fe27b38 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp @@ -70,6 +70,8 @@ void CachedSetTest::SetUp() { auto testLayer = std::make_unique<TestLayer>(); auto pos = static_cast<int32_t>(i); testLayer->outputLayerCompositionState.displayFrame = Rect(pos, pos, pos + 1, pos + 1); + testLayer->outputLayerCompositionState.visibleRegion = + Region(Rect(pos + 1, pos + 1, pos + 2, pos + 2)); testLayer->layerFE = sp<mock::LayerFE>::make(); @@ -106,6 +108,7 @@ void expectEqual(const CachedSet& cachedSet, const CachedSet::Layer& layer) { EXPECT_EQ(layer.getHash(), cachedSet.getFingerprint()); EXPECT_EQ(layer.getLastUpdate(), cachedSet.getLastUpdate()); EXPECT_EQ(layer.getDisplayFrame(), cachedSet.getBounds()); + EXPECT_TRUE(layer.getVisibleRegion().hasSameRects(cachedSet.getVisibleRegion())); EXPECT_EQ(1u, cachedSet.getLayerCount()); EXPECT_EQ(layer.getState(), cachedSet.getFirstLayer().getState()); EXPECT_EQ(0u, cachedSet.getAge()); @@ -154,6 +157,10 @@ TEST_F(CachedSetTest, addLayer) { EXPECT_EQ(layer1.getHash(), cachedSet.getFingerprint()); EXPECT_EQ(kStartTime, cachedSet.getLastUpdate()); EXPECT_EQ(Rect(0, 0, 2, 2), cachedSet.getBounds()); + Region expectedRegion; + expectedRegion.orSelf(Rect(1, 1, 2, 2)); + expectedRegion.orSelf(Rect(2, 2, 3, 3)); + EXPECT_TRUE(cachedSet.getVisibleRegion().hasSameRects(expectedRegion)); EXPECT_EQ(2u, cachedSet.getLayerCount()); EXPECT_EQ(0u, cachedSet.getAge()); expectNoBuffer(cachedSet); @@ -239,6 +246,11 @@ TEST_F(CachedSetTest, append) { EXPECT_EQ(layer1.getHash(), cachedSet1.getFingerprint()); EXPECT_EQ(kStartTime, cachedSet1.getLastUpdate()); EXPECT_EQ(Rect(0, 0, 3, 3), cachedSet1.getBounds()); + Region expectedRegion; + expectedRegion.orSelf(Rect(1, 1, 2, 2)); + expectedRegion.orSelf(Rect(2, 2, 3, 3)); + expectedRegion.orSelf(Rect(3, 3, 4, 4)); + EXPECT_TRUE(cachedSet1.getVisibleRegion().hasSameRects(expectedRegion)); EXPECT_EQ(3u, cachedSet1.getLayerCount()); EXPECT_EQ(0u, cachedSet1.getAge()); expectNoBuffer(cachedSet1); diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp index 1bbf11a163..c5280877d5 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/FlattenerTest.cpp @@ -89,6 +89,8 @@ void FlattenerTest::SetUp() { testLayer->name = ss.str(); testLayer->outputLayerCompositionState.displayFrame = Rect(pos, pos, pos + 1, pos + 1); + testLayer->outputLayerCompositionState.visibleRegion = + Region(Rect(pos + 1, pos + 1, pos + 2, pos + 2)); testLayer->layerFECompositionState.buffer = new GraphicBuffer(100, 100, HAL_PIXEL_FORMAT_RGBA_8888, 1, @@ -272,6 +274,7 @@ TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsProjectionSpace) { // make all layers inactive mTime += 200ms; expectAllLayersFlattened(layers); + EXPECT_EQ(overrideDisplaySpace.bounds, Rect(mOutputState.framebufferSpace.bounds.getWidth(), mOutputState.framebufferSpace.bounds.getHeight())); @@ -279,6 +282,55 @@ TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsProjectionSpace) { EXPECT_EQ(overrideDisplaySpace.orientation, mOutputState.framebufferSpace.orientation); } +TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsDamageRegions) { + auto& layerState1 = mTestLayers[0]->layerState; + const auto& overrideDamageRegion = + layerState1->getOutputLayer()->getState().overrideInfo.damageRegion; + + 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_TRUE(overrideDamageRegion.isRect() && + overrideDamageRegion.bounds() == Rect::INVALID_RECT); + + initializeOverrideBuffer(layers); + EXPECT_NE(getNonBufferHash(layers), + mFlattener->flattenLayers(layers, getNonBufferHash(layers), mTime)); + EXPECT_TRUE(overrideDamageRegion.isRect() && overrideDamageRegion.bounds() == Rect::EMPTY_RECT); +} + +TEST_F(FlattenerTest, flattenLayers_FlattenedLayersSetsVisibleRegion) { + auto& layerState1 = mTestLayers[0]->layerState; + const auto& overrideVisibleRegion = + layerState1->getOutputLayer()->getState().overrideInfo.visibleRegion; + + 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); + Region expectedRegion; + expectedRegion.orSelf(Rect(1, 1, 2, 2)); + expectedRegion.orSelf(Rect(2, 2, 3, 3)); + EXPECT_TRUE(overrideVisibleRegion.hasSameRects(expectedRegion)); +} + TEST_F(FlattenerTest, flattenLayers_addLayerToFlattenedCauseReset) { auto& layerState1 = mTestLayers[0]->layerState; const auto& overrideBuffer1 = layerState1->getOutputLayer()->getState().overrideInfo.buffer; diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp index d5a7234372..131187d5f4 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp @@ -592,6 +592,16 @@ TEST_F(LayerStateTest, compareAlpha) { EXPECT_TRUE(otherLayerState->compare(*mLayerState)); } +TEST_F(LayerStateTest, getVisibleRegion) { + OutputLayerCompositionState outputLayerCompositionState; + outputLayerCompositionState.visibleRegion = sRegionOne; + LayerFECompositionState layerFECompositionState; + setupMocksForLayer(mOutputLayer, mLayerFE, outputLayerCompositionState, + layerFECompositionState); + mLayerState = std::make_unique<LayerState>(&mOutputLayer); + EXPECT_TRUE(mLayerState->getVisibleRegion().hasSameRects(sRegionOne)); +} + TEST_F(LayerStateTest, updateVisibleRegion) { OutputLayerCompositionState outputLayerCompositionState; outputLayerCompositionState.visibleRegion = sRegionOne; |