diff options
| -rw-r--r-- | cmds/surfacereplayer/proto/src/trace.proto | 7 | ||||
| -rw-r--r-- | libs/gui/LayerState.cpp | 7 | ||||
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 6 | ||||
| -rw-r--r-- | libs/gui/include/gui/LayerState.h | 4 | ||||
| -rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 44 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceInterceptor.cpp | 11 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceInterceptor.h | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp | 68 |
12 files changed, 148 insertions, 14 deletions
diff --git a/cmds/surfacereplayer/proto/src/trace.proto b/cmds/surfacereplayer/proto/src/trace.proto index 3798ba73a4..29d4409a86 100644 --- a/cmds/surfacereplayer/proto/src/trace.proto +++ b/cmds/surfacereplayer/proto/src/trace.proto @@ -100,6 +100,10 @@ message LayerStackChange { required uint32 layer_stack = 1; } +message DisplayFlagsChange { + required uint32 flags = 1; +} + message HiddenFlagChange { required bool hidden_flag = 1; } @@ -120,6 +124,7 @@ message DisplayChange { LayerStackChange layer_stack = 3; SizeChange size = 4; ProjectionChange projection = 5; + DisplayFlagsChange flags = 6; } } @@ -212,4 +217,4 @@ message BlurRegionChange { message Origin { required int32 pid = 1; required int32 uid = 2; -}
\ No newline at end of file +} diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e65c721ae1..d102e07623 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -315,6 +315,7 @@ status_t ComposerState::read(const Parcel& input) { DisplayState::DisplayState() : what(0), layerStack(0), + flags(0), layerStackSpaceRect(Rect::EMPTY_RECT), orientedDisplaySpaceRect(Rect::EMPTY_RECT), width(0), @@ -325,6 +326,7 @@ status_t DisplayState::write(Parcel& output) const { SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(surface)); SAFE_PARCEL(output.writeUint32, what); SAFE_PARCEL(output.writeUint32, layerStack); + SAFE_PARCEL(output.writeUint32, flags); SAFE_PARCEL(output.writeUint32, toRotationInt(orientation)); SAFE_PARCEL(output.write, layerStackSpaceRect); SAFE_PARCEL(output.write, orientedDisplaySpaceRect); @@ -341,6 +343,7 @@ status_t DisplayState::read(const Parcel& input) { SAFE_PARCEL(input.readUint32, &what); SAFE_PARCEL(input.readUint32, &layerStack); + SAFE_PARCEL(input.readUint32, &flags); uint32_t tmpUint = 0; SAFE_PARCEL(input.readUint32, &tmpUint); orientation = ui::toRotation(tmpUint); @@ -361,6 +364,10 @@ void DisplayState::merge(const DisplayState& other) { what |= eLayerStackChanged; layerStack = other.layerStack; } + if (other.what & eFlagsChanged) { + what |= eFlagsChanged; + flags = other.flags; + } if (other.what & eDisplayProjectionChanged) { what |= eDisplayProjectionChanged; orientation = other.orientation; diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 8af21d3c5d..d006df7cca 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1736,6 +1736,12 @@ void SurfaceComposerClient::Transaction::setDisplayLayerStack(const sp<IBinder>& s.what |= DisplayState::eLayerStackChanged; } +void SurfaceComposerClient::Transaction::setDisplayFlags(const sp<IBinder>& token, uint32_t flags) { + DisplayState& s(getDisplayState(token)); + s.flags = flags; + s.what |= DisplayState::eFlagsChanged; +} + void SurfaceComposerClient::Transaction::setDisplayProjection(const sp<IBinder>& token, ui::Rotation orientation, const Rect& layerStackRect, diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 16430b324d..869c082ab1 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -247,7 +247,8 @@ struct DisplayState { eSurfaceChanged = 0x01, eLayerStackChanged = 0x02, eDisplayProjectionChanged = 0x04, - eDisplaySizeChanged = 0x08 + eDisplaySizeChanged = 0x08, + eFlagsChanged = 0x10 }; DisplayState(); @@ -257,6 +258,7 @@ struct DisplayState { sp<IBinder> token; sp<IGraphicBufferProducer> surface; uint32_t layerStack; + uint32_t flags; // These states define how layers are projected onto the physical display. // diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 28b4a3724e..c9db92390d 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -564,6 +564,8 @@ public: void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack); + void setDisplayFlags(const sp<IBinder>& token, uint32_t flags); + /* setDisplayProjection() defines the projection of layer stacks * to a given display. * diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index ca4b6abc03..c391901faa 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -220,6 +220,10 @@ void DisplayDevice::setLayerStack(ui::LayerStack stack) { mCompositionDisplay->setLayerStackFilter(stack, isPrimary()); } +void DisplayDevice::setFlags(uint32_t flags) { + mFlags = flags; +} + void DisplayDevice::setDisplaySize(int width, int height) { LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays."); mCompositionDisplay->setDisplaySize(ui::Size(width, height)); diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 7e4d92308c..70dcc1e8b5 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -64,6 +64,7 @@ class DisplayDevice : public RefBase { public: constexpr static float sDefaultMinLumiance = 0.0; constexpr static float sDefaultMaxLumiance = 500.0; + enum { eReceivesInput = 0x01 }; explicit DisplayDevice(DisplayDeviceCreationArgs& args); @@ -90,6 +91,7 @@ public: void setLayerStack(ui::LayerStack); void setDisplaySize(int width, int height); void setProjection(ui::Rotation orientation, Rect viewport, Rect frame); + void setFlags(uint32_t flags); ui::Rotation getPhysicalOrientation() const { return mPhysicalOrientation; } ui::Rotation getOrientation() const { return mOrientation; } @@ -102,6 +104,7 @@ public: const Rect& getOrientedDisplaySpaceRect() const; bool needsFiltering() const; ui::LayerStack getLayerStack() const; + bool receivesInput() const { return mFlags & eReceivesInput; } DisplayId getId() const; @@ -227,6 +230,8 @@ private: // TODO(b/74619554): Remove special cases for primary display. const bool mIsPrimary; + uint32_t mFlags = 0; + std::optional<DeviceProductInfo> mDeviceProductInfo; std::vector<ui::Hdr> mOverrideHdrTypes; @@ -252,6 +257,7 @@ struct DisplayDeviceState { std::optional<Physical> physical; sp<IGraphicBufferProducer> surface; ui::LayerStack layerStack = ui::NO_LAYER_STACK; + uint32_t flags = 0; Rect layerStackSpaceRect; Rect orientedDisplaySpaceRect; ui::Rotation orientation = ui::ROTATION_0; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index c1d28b1746..13a27d02f0 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2852,6 +2852,9 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (currentState.layerStack != drawingState.layerStack) { display->setLayerStack(currentState.layerStack); } + if (currentState.flags != drawingState.flags) { + display->setFlags(currentState.flags); + } if ((currentState.orientation != drawingState.orientation) || (currentState.layerStackSpaceRect != drawingState.layerStackSpaceRect) || (currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) { @@ -3069,18 +3072,9 @@ void SurfaceFlinger::updateInputWindowInfo() { mDrawingState.traverseInReverseZOrder([&](Layer* layer) { if (!layer->needsInputInfo()) return; - sp<DisplayDevice> display; - if (enablePerWindowInputRotation()) { - for (const auto& pair : ON_MAIN_THREAD(mDisplays)) { - const auto& displayDevice = pair.second; - if (!displayDevice->getCompositionDisplay() - ->belongsInOutput(layer->getLayerStack(), - layer->getPrimaryDisplayOnly())) { - continue; - } - display = displayDevice; - } - } + sp<DisplayDevice> display = enablePerWindowInputRotation() + ? ON_MAIN_THREAD(getDisplayWithInputByLayer(layer)) + : nullptr; // When calculating the screen bounds we ignore the transparent region since it may // result in an unwanted offset. inputInfos.push_back(layer->fillInputInfo(display)); @@ -3819,6 +3813,12 @@ uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) { flags |= eDisplayTransactionNeeded; } } + if (what & DisplayState::eFlagsChanged) { + if (state.flags != s.flags) { + state.flags = s.flags; + flags |= eDisplayTransactionNeeded; + } + } if (what & DisplayState::eDisplayProjectionChanged) { if (state.orientation != s.orientation) { state.orientation = s.orientation; @@ -4485,6 +4485,26 @@ void SurfaceFlinger::initializeDisplays() { static_cast<void>(schedule([this]() MAIN_THREAD { onInitializeDisplays(); })); } +sp<DisplayDevice> SurfaceFlinger::getDisplayWithInputByLayer(Layer* layer) const { + sp<DisplayDevice> display; + for (const auto& pair : mDisplays) { + const auto& displayDevice = pair.second; + if (!displayDevice->receivesInput() || + !displayDevice->getCompositionDisplay() + ->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) { + continue; + } + // Don't return immediately so that we can log duplicates. + if (display) { + ALOGE("Multiple display devices claim to accept input for the same layerstack: %d", + layer->getLayerStack()); + continue; + } + display = displayDevice; + } + return display; +} + void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) { if (display->isVirtual()) { ALOGE("%s: Invalid operation on virtual display", __FUNCTION__); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a3fa8d654f..8656778186 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -981,6 +981,8 @@ private: // region of all screens presenting this layer stack. void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty); + sp<DisplayDevice> getDisplayWithInputByLayer(Layer* layer) const REQUIRES(mStateLock); + /* * H/W composer */ diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index c5f1598d15..843c966bea 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -160,6 +160,7 @@ void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment, addDisplaySurfaceLocked(transaction, display.sequenceId, display.surface); addDisplayLayerStackLocked(transaction, display.sequenceId, display.layerStack); + addDisplayFlagsLocked(transaction, display.sequenceId, display.flags); addDisplaySizeLocked(transaction, display.sequenceId, display.width, display.height); addDisplayProjectionLocked(transaction, display.sequenceId, toRotationInt(display.orientation), display.layerStackSpaceRect, display.orientedDisplaySpaceRect); @@ -474,6 +475,9 @@ void SurfaceInterceptor::addDisplayChangesLocked(Transaction* transaction, if (state.what & DisplayState::eLayerStackChanged) { addDisplayLayerStackLocked(transaction, sequenceId, state.layerStack); } + if (state.what & DisplayState::eFlagsChanged) { + addDisplayFlagsLocked(transaction, sequenceId, state.flags); + } if (state.what & DisplayState::eDisplaySizeChanged) { addDisplaySizeLocked(transaction, sequenceId, state.width, state.height); } @@ -565,6 +569,13 @@ void SurfaceInterceptor::addDisplayLayerStackLocked(Transaction* transaction, layerStackChange->set_layer_stack(layerStack); } +void SurfaceInterceptor::addDisplayFlagsLocked(Transaction* transaction, int32_t sequenceId, + uint32_t flags) { + DisplayChange* dispChange(createDisplayChangeLocked(transaction, sequenceId)); + DisplayFlagsChange* flagsChange(dispChange->mutable_flags()); + flagsChange->set_flags(flags); +} + void SurfaceInterceptor::addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId, uint32_t w, uint32_t h) { diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index 30aca8340e..e498e7d067 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -184,6 +184,7 @@ private: const sp<const IGraphicBufferProducer>& surface); void addDisplayLayerStackLocked(Transaction* transaction, int32_t sequenceId, uint32_t layerStack); + void addDisplayFlagsLocked(Transaction* transaction, int32_t sequenceId, uint32_t flags); void addDisplaySizeLocked(Transaction* transaction, int32_t sequenceId, uint32_t w, uint32_t h); void addDisplayProjectionLocked(Transaction* transaction, int32_t sequenceId, diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp index be019848fb..fc40818ad1 100644 --- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp +++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetDisplayStateTest.cpp @@ -224,6 +224,74 @@ TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfLayerStac EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack); } +TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfFlagsNotChanged) { + using Case = SimplePrimaryDisplayCase; + + // -------------------------------------------------------------------- + // Preconditions + + // A display is set up + auto display = Case::Display::makeFakeExistingDisplayInjector(this); + display.inject(); + + // The display has flags set + display.mutableCurrentDisplayState().flags = 1u; + + // The incoming request sets a different layer stack + DisplayState state; + state.what = DisplayState::eFlagsChanged; + state.token = display.token(); + state.flags = 1u; + + // -------------------------------------------------------------------- + // Invocation + + uint32_t flags = mFlinger.setDisplayStateLocked(state); + + // -------------------------------------------------------------------- + // Postconditions + + // The returned flags are empty + EXPECT_EQ(0u, flags); + + // The desired display state has been set to the new value. + EXPECT_EQ(1u, display.getCurrentDisplayState().flags); +} + +TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfFlagsChanged) { + using Case = SimplePrimaryDisplayCase; + + // -------------------------------------------------------------------- + // Preconditions + + // A display is set up + auto display = Case::Display::makeFakeExistingDisplayInjector(this); + display.inject(); + + // The display has a layer stack set + display.mutableCurrentDisplayState().flags = 0u; + + // The incoming request sets a different layer stack + DisplayState state; + state.what = DisplayState::eFlagsChanged; + state.token = display.token(); + state.flags = 1u; + + // -------------------------------------------------------------------- + // Invocation + + uint32_t flags = mFlinger.setDisplayStateLocked(state); + + // -------------------------------------------------------------------- + // Postconditions + + // The returned flags indicate a transaction is needed + EXPECT_EQ(eDisplayTransactionNeeded, flags); + + // The desired display state has been set to the new value. + EXPECT_EQ(1u, display.getCurrentDisplayState().flags); +} + TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) { using Case = SimplePrimaryDisplayCase; constexpr ui::Rotation initialOrientation = ui::ROTATION_180; |