Loading services/surfaceflinger/DisplayDevice.cpp +54 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #undef LOG_TAG #define LOG_TAG "DisplayDevice" #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <android-base/stringprintf.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/Display.h> Loading Loading @@ -66,6 +68,8 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mSequenceId(args.sequenceId), mConnectionType(args.connectionType), mCompositionDisplay{args.compositionDisplay}, mActiveModeFPSTrace("ActiveModeFPS -" + to_string(getId())), mActiveModeFPSHwcTrace("ActiveModeFPS_HWC -" + to_string(getId())), mPhysicalOrientation(args.physicalOrientation), mSupportedModes(std::move(args.supportedModes)), mIsPrimary(args.isPrimary), Loading Loading @@ -156,6 +160,7 @@ bool DisplayDevice::isPoweredOn() const { void DisplayDevice::setActiveMode(DisplayModeId id) { const auto mode = getMode(id); LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported."); ATRACE_INT(mActiveModeFPSTrace.c_str(), mode->getFps().getIntValue()); mActiveMode = mode; if (mRefreshRateConfigs) { mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId()); Loading @@ -165,17 +170,19 @@ void DisplayDevice::setActiveMode(DisplayModeId id) { } } status_t DisplayDevice::initiateModeChange(DisplayModeId modeId, status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) const { const auto mode = getMode(modeId); if (!mode) { hal::VsyncPeriodChangeTimeline* outTimeline) { if (!info.mode || info.mode->getPhysicalDisplayId() != getPhysicalId()) { ALOGE("Trying to initiate a mode change to invalid mode %s on display %s", std::to_string(modeId.value()).c_str(), to_string(getId()).c_str()); info.mode ? std::to_string(info.mode->getId().value()).c_str() : "null", to_string(getId()).c_str()); return BAD_VALUE; } return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), mode->getHwcId(), constraints, outTimeline); mUpcomingActiveMode = info; ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(), constraints, outTimeline); } const DisplayModePtr& DisplayDevice::getActiveMode() const { Loading Loading @@ -435,6 +442,46 @@ void DisplayDevice::onInvalidate() { } } bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) { ATRACE_CALL(); LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided"); LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch"); ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str()); std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) { // If a mode change is pending, just cache the latest request in mDesiredActiveMode const Scheduler::ModeEvent prevConfig = mDesiredActiveMode.event; mDesiredActiveMode = info; mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig; return false; } // Check if we are already at the desired mode if (getActiveMode()->getId() == info.mode->getId()) { return false; } // Initiate a mode change. mDesiredActiveModeChanged = true; mDesiredActiveMode = info; return true; } std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const { std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) return mDesiredActiveMode; return std::nullopt; } void DisplayDevice::clearDesiredActiveModeState() { std::scoped_lock lock(mActiveModeLock); mDesiredActiveMode.event = Scheduler::ModeEvent::None; mDesiredActiveModeChanged = false; } std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1); } // namespace android Loading services/surfaceflinger/DisplayDevice.h +33 −3 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ #include <utils/RefBase.h> #include <utils/Timers.h> #include "MainThreadGuard.h" #include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/DisplayMode.h" #include "DisplayHardware/Hal.h" Loading @@ -46,6 +48,8 @@ #include "Scheduler/RefreshRateConfigs.h" #include "TracedOrdinal.h" namespace android { class Fence; Loading Loading @@ -181,10 +185,28 @@ public: * Display mode management. */ const DisplayModePtr& getActiveMode() const; void setActiveMode(DisplayModeId); status_t initiateModeChange(DisplayModeId modeId, struct ActiveModeInfo { DisplayModePtr mode; scheduler::RefreshRateConfigEvent event = scheduler::RefreshRateConfigEvent::None; bool operator!=(const ActiveModeInfo& other) const { return mode != other.mode || event != other.event; } }; bool setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock); std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock); void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock); ActiveModeInfo getUpcomingActiveMode() const REQUIRES(SF_MAIN_THREAD) { return mUpcomingActiveMode; } void setActiveMode(DisplayModeId) REQUIRES(SF_MAIN_THREAD); status_t initiateModeChange(const ActiveModeInfo&, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) const; hal::VsyncPeriodChangeTimeline* outTimeline) REQUIRES(SF_MAIN_THREAD); // Return the immutable list of supported display modes. The HWC may report different modes // after a hotplug reconnect event, in which case the DisplayDevice object will be recreated. Loading Loading @@ -236,6 +258,8 @@ private: const std::shared_ptr<compositionengine::Display> mCompositionDisplay; std::string mDisplayName; std::string mActiveModeFPSTrace; std::string mActiveModeFPSHwcTrace; const ui::Rotation mPhysicalOrientation; ui::Rotation mOrientation = ui::ROTATION_0; Loading @@ -260,6 +284,12 @@ private: std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs; std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay; mutable std::mutex mActiveModeLock; ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock); TracedOrdinal<bool> mDesiredActiveModeChanged GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false}; ActiveModeInfo mUpcomingActiveMode GUARDED_BY(SF_MAIN_THREAD); }; struct DisplayDeviceState { Loading services/surfaceflinger/DisplayHardware/DisplayMode.h +8 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <android-base/stringprintf.h> #include <android/configuration.h> #include <ui/DisplayId.h> #include <ui/DisplayMode.h> #include <ui/Size.h> #include <utils/Timers.h> Loading Loading @@ -54,6 +55,11 @@ public: return *this; } Builder& setPhysicalDisplayId(PhysicalDisplayId id) { mDisplayMode->mPhysicalDisplayId = id; return *this; } Builder& setWidth(int32_t width) { mDisplayMode->mWidth = width; return *this; Loading Loading @@ -112,6 +118,7 @@ public: DisplayModeId getId() const { return mId; } hal::HWConfigId getHwcId() const { return mHwcId; } PhysicalDisplayId getPhysicalDisplayId() const { return mPhysicalDisplayId; } int32_t getWidth() const { return mWidth; } int32_t getHeight() const { return mHeight; } Loading @@ -136,6 +143,7 @@ private: hal::HWConfigId mHwcId; DisplayModeId mId; PhysicalDisplayId mPhysicalDisplayId; int32_t mWidth = -1; int32_t mHeight = -1; Loading services/surfaceflinger/MainThreadGuard.h 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <utils/Mutex.h> namespace android { namespace { // Helps to ensure that some functions runs on SF's main thread by using the // clang thread safety annotations. class CAPABILITY("mutex") MainThreadGuard { } SF_MAIN_THREAD; struct SCOPED_CAPABILITY MainThreadScopedGuard { public: explicit MainThreadScopedGuard(MainThreadGuard& mutex) ACQUIRE(mutex) {} ~MainThreadScopedGuard() RELEASE() {} }; } // namespace } // namespace android services/surfaceflinger/Scheduler/EventThread.cpp +7 −8 Original line number Diff line number Diff line Loading @@ -118,12 +118,12 @@ DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t times return event; } DisplayEventReceiver::Event makeModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId, nsecs_t vsyncPeriod) { DisplayEventReceiver::Event makeModeChanged(DisplayModePtr mode) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, displayId, systemTime()}; event.modeChange.modeId = modeId.value(); event.modeChange.vsyncPeriod = vsyncPeriod; event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, mode->getPhysicalDisplayId(), systemTime()}; event.modeChange.modeId = mode->getId().value(); event.modeChange.vsyncPeriod = mode->getVsyncPeriod(); return event; } Loading Loading @@ -375,11 +375,10 @@ void EventThread::onHotplugReceived(PhysicalDisplayId displayId, bool connected) mCondition.notify_all(); } void EventThread::onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId, nsecs_t vsyncPeriod) { void EventThread::onModeChanged(DisplayModePtr mode) { std::lock_guard<std::mutex> lock(mMutex); mPendingEvents.push_back(makeModeChanged(displayId, modeId, vsyncPeriod)); mPendingEvents.push_back(makeModeChanged(mode)); mCondition.notify_all(); } Loading Loading
services/surfaceflinger/DisplayDevice.cpp +54 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ #undef LOG_TAG #define LOG_TAG "DisplayDevice" #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include <android-base/stringprintf.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/Display.h> Loading Loading @@ -66,6 +68,8 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mSequenceId(args.sequenceId), mConnectionType(args.connectionType), mCompositionDisplay{args.compositionDisplay}, mActiveModeFPSTrace("ActiveModeFPS -" + to_string(getId())), mActiveModeFPSHwcTrace("ActiveModeFPS_HWC -" + to_string(getId())), mPhysicalOrientation(args.physicalOrientation), mSupportedModes(std::move(args.supportedModes)), mIsPrimary(args.isPrimary), Loading Loading @@ -156,6 +160,7 @@ bool DisplayDevice::isPoweredOn() const { void DisplayDevice::setActiveMode(DisplayModeId id) { const auto mode = getMode(id); LOG_FATAL_IF(!mode, "Cannot set active mode which is not supported."); ATRACE_INT(mActiveModeFPSTrace.c_str(), mode->getFps().getIntValue()); mActiveMode = mode; if (mRefreshRateConfigs) { mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId()); Loading @@ -165,17 +170,19 @@ void DisplayDevice::setActiveMode(DisplayModeId id) { } } status_t DisplayDevice::initiateModeChange(DisplayModeId modeId, status_t DisplayDevice::initiateModeChange(const ActiveModeInfo& info, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) const { const auto mode = getMode(modeId); if (!mode) { hal::VsyncPeriodChangeTimeline* outTimeline) { if (!info.mode || info.mode->getPhysicalDisplayId() != getPhysicalId()) { ALOGE("Trying to initiate a mode change to invalid mode %s on display %s", std::to_string(modeId.value()).c_str(), to_string(getId()).c_str()); info.mode ? std::to_string(info.mode->getId().value()).c_str() : "null", to_string(getId()).c_str()); return BAD_VALUE; } return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), mode->getHwcId(), constraints, outTimeline); mUpcomingActiveMode = info; ATRACE_INT(mActiveModeFPSHwcTrace.c_str(), info.mode->getFps().getIntValue()); return mHwComposer.setActiveModeWithConstraints(getPhysicalId(), info.mode->getHwcId(), constraints, outTimeline); } const DisplayModePtr& DisplayDevice::getActiveMode() const { Loading Loading @@ -435,6 +442,46 @@ void DisplayDevice::onInvalidate() { } } bool DisplayDevice::setDesiredActiveMode(const ActiveModeInfo& info) { ATRACE_CALL(); LOG_ALWAYS_FATAL_IF(!info.mode, "desired mode not provided"); LOG_ALWAYS_FATAL_IF(getPhysicalId() != info.mode->getPhysicalDisplayId(), "DisplayId mismatch"); ALOGV("%s(%s)", __func__, to_string(*info.mode).c_str()); std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) { // If a mode change is pending, just cache the latest request in mDesiredActiveMode const Scheduler::ModeEvent prevConfig = mDesiredActiveMode.event; mDesiredActiveMode = info; mDesiredActiveMode.event = mDesiredActiveMode.event | prevConfig; return false; } // Check if we are already at the desired mode if (getActiveMode()->getId() == info.mode->getId()) { return false; } // Initiate a mode change. mDesiredActiveModeChanged = true; mDesiredActiveMode = info; return true; } std::optional<DisplayDevice::ActiveModeInfo> DisplayDevice::getDesiredActiveMode() const { std::scoped_lock lock(mActiveModeLock); if (mDesiredActiveModeChanged) return mDesiredActiveMode; return std::nullopt; } void DisplayDevice::clearDesiredActiveModeState() { std::scoped_lock lock(mActiveModeLock); mDesiredActiveMode.event = Scheduler::ModeEvent::None; mDesiredActiveModeChanged = false; } std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1); } // namespace android Loading
services/surfaceflinger/DisplayDevice.h +33 −3 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ #include <utils/RefBase.h> #include <utils/Timers.h> #include "MainThreadGuard.h" #include "DisplayHardware/DisplayIdentification.h" #include "DisplayHardware/DisplayMode.h" #include "DisplayHardware/Hal.h" Loading @@ -46,6 +48,8 @@ #include "Scheduler/RefreshRateConfigs.h" #include "TracedOrdinal.h" namespace android { class Fence; Loading Loading @@ -181,10 +185,28 @@ public: * Display mode management. */ const DisplayModePtr& getActiveMode() const; void setActiveMode(DisplayModeId); status_t initiateModeChange(DisplayModeId modeId, struct ActiveModeInfo { DisplayModePtr mode; scheduler::RefreshRateConfigEvent event = scheduler::RefreshRateConfigEvent::None; bool operator!=(const ActiveModeInfo& other) const { return mode != other.mode || event != other.event; } }; bool setDesiredActiveMode(const ActiveModeInfo&) EXCLUDES(mActiveModeLock); std::optional<ActiveModeInfo> getDesiredActiveMode() const EXCLUDES(mActiveModeLock); void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock); ActiveModeInfo getUpcomingActiveMode() const REQUIRES(SF_MAIN_THREAD) { return mUpcomingActiveMode; } void setActiveMode(DisplayModeId) REQUIRES(SF_MAIN_THREAD); status_t initiateModeChange(const ActiveModeInfo&, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) const; hal::VsyncPeriodChangeTimeline* outTimeline) REQUIRES(SF_MAIN_THREAD); // Return the immutable list of supported display modes. The HWC may report different modes // after a hotplug reconnect event, in which case the DisplayDevice object will be recreated. Loading Loading @@ -236,6 +258,8 @@ private: const std::shared_ptr<compositionengine::Display> mCompositionDisplay; std::string mDisplayName; std::string mActiveModeFPSTrace; std::string mActiveModeFPSHwcTrace; const ui::Rotation mPhysicalOrientation; ui::Rotation mOrientation = ui::ROTATION_0; Loading @@ -260,6 +284,12 @@ private: std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs; std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay; mutable std::mutex mActiveModeLock; ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock); TracedOrdinal<bool> mDesiredActiveModeChanged GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false}; ActiveModeInfo mUpcomingActiveMode GUARDED_BY(SF_MAIN_THREAD); }; struct DisplayDeviceState { Loading
services/surfaceflinger/DisplayHardware/DisplayMode.h +8 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <android-base/stringprintf.h> #include <android/configuration.h> #include <ui/DisplayId.h> #include <ui/DisplayMode.h> #include <ui/Size.h> #include <utils/Timers.h> Loading Loading @@ -54,6 +55,11 @@ public: return *this; } Builder& setPhysicalDisplayId(PhysicalDisplayId id) { mDisplayMode->mPhysicalDisplayId = id; return *this; } Builder& setWidth(int32_t width) { mDisplayMode->mWidth = width; return *this; Loading Loading @@ -112,6 +118,7 @@ public: DisplayModeId getId() const { return mId; } hal::HWConfigId getHwcId() const { return mHwcId; } PhysicalDisplayId getPhysicalDisplayId() const { return mPhysicalDisplayId; } int32_t getWidth() const { return mWidth; } int32_t getHeight() const { return mHeight; } Loading @@ -136,6 +143,7 @@ private: hal::HWConfigId mHwcId; DisplayModeId mId; PhysicalDisplayId mPhysicalDisplayId; int32_t mWidth = -1; int32_t mHeight = -1; Loading
services/surfaceflinger/MainThreadGuard.h 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * Copyright 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <utils/Mutex.h> namespace android { namespace { // Helps to ensure that some functions runs on SF's main thread by using the // clang thread safety annotations. class CAPABILITY("mutex") MainThreadGuard { } SF_MAIN_THREAD; struct SCOPED_CAPABILITY MainThreadScopedGuard { public: explicit MainThreadScopedGuard(MainThreadGuard& mutex) ACQUIRE(mutex) {} ~MainThreadScopedGuard() RELEASE() {} }; } // namespace } // namespace android
services/surfaceflinger/Scheduler/EventThread.cpp +7 −8 Original line number Diff line number Diff line Loading @@ -118,12 +118,12 @@ DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t times return event; } DisplayEventReceiver::Event makeModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId, nsecs_t vsyncPeriod) { DisplayEventReceiver::Event makeModeChanged(DisplayModePtr mode) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, displayId, systemTime()}; event.modeChange.modeId = modeId.value(); event.modeChange.vsyncPeriod = vsyncPeriod; event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, mode->getPhysicalDisplayId(), systemTime()}; event.modeChange.modeId = mode->getId().value(); event.modeChange.vsyncPeriod = mode->getVsyncPeriod(); return event; } Loading Loading @@ -375,11 +375,10 @@ void EventThread::onHotplugReceived(PhysicalDisplayId displayId, bool connected) mCondition.notify_all(); } void EventThread::onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId, nsecs_t vsyncPeriod) { void EventThread::onModeChanged(DisplayModePtr mode) { std::lock_guard<std::mutex> lock(mMutex); mPendingEvents.push_back(makeModeChanged(displayId, modeId, vsyncPeriod)); mPendingEvents.push_back(makeModeChanged(mode)); mCondition.notify_all(); } Loading