Loading services/surfaceflinger/SurfaceFlinger.cpp +119 −111 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,19 @@ #include "android-base/parseint.h" #include "android-base/parseint.h" #include "android-base/stringprintf.h" #include "android-base/stringprintf.h" #define MAIN_THREAD ACQUIRE(mStateLock) RELEASE(mStateLock) #define ON_MAIN_THREAD(expr) \ [&] { \ LOG_FATAL_IF(std::this_thread::get_id() != mMainThreadId); \ UnnecessaryLock lock(mStateLock); \ return (expr); \ }() #undef NO_THREAD_SAFETY_ANALYSIS #define NO_THREAD_SAFETY_ANALYSIS \ _Pragma("GCC error \"Prefer MAIN_THREAD macros or {Conditional,Timed,Unnecessary}Lock.\"") namespace android { namespace android { using namespace std::string_literals; using namespace std::string_literals; Loading Loading @@ -173,12 +186,12 @@ bool isWideColorMode(const ColorMode colorMode) { #pragma clang diagnostic pop #pragma clang diagnostic pop template <typename Mutex> template <typename Mutex> struct ConditionalLockGuard { struct SCOPED_CAPABILITY ConditionalLockGuard { ConditionalLockGuard(Mutex& mutex, bool lock) : mutex(mutex), lock(lock) { ConditionalLockGuard(Mutex& mutex, bool lock) ACQUIRE(mutex) : mutex(mutex), lock(lock) { if (lock) mutex.lock(); if (lock) mutex.lock(); } } ~ConditionalLockGuard() { ~ConditionalLockGuard() RELEASE() { if (lock) mutex.unlock(); if (lock) mutex.unlock(); } } Loading @@ -188,6 +201,27 @@ struct ConditionalLockGuard { using ConditionalLock = ConditionalLockGuard<Mutex>; using ConditionalLock = ConditionalLockGuard<Mutex>; struct SCOPED_CAPABILITY TimedLock { TimedLock(Mutex& mutex, nsecs_t timeout, const char* whence) ACQUIRE(mutex) : mutex(mutex), status(mutex.timedLock(timeout)) { ALOGE_IF(!locked(), "%s timed out locking: %s (%d)", whence, strerror(-status), status); } ~TimedLock() RELEASE() { if (locked()) mutex.unlock(); } bool locked() const { return status == NO_ERROR; } Mutex& mutex; const status_t status; }; struct SCOPED_CAPABILITY UnnecessaryLock { explicit UnnecessaryLock(Mutex& mutex) ACQUIRE(mutex) {} ~UnnecessaryLock() RELEASE() {} }; // TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity. // TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity. constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV; constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV; Loading Loading @@ -991,7 +1025,7 @@ status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int mo } } auto future = schedule([=]() -> status_t { auto future = schedule([=]() -> status_t { const auto display = getDisplayDeviceLocked(displayToken); const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken)); if (!display) { if (!display) { ALOGE("Attempt to set allowed display configs for invalid display token %p", ALOGE("Attempt to set allowed display configs for invalid display token %p", displayToken.get()); displayToken.get()); Loading Loading @@ -1176,7 +1210,7 @@ ColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& displayToken) { } } status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) { status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) { schedule([=] { schedule([=]() MAIN_THREAD { Vector<ColorMode> modes; Vector<ColorMode> modes; getDisplayColorModes(displayToken, &modes); getDisplayColorModes(displayToken, &modes); bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes); bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes); Loading Loading @@ -1222,7 +1256,7 @@ status_t SurfaceFlinger::getAutoLowLatencyModeSupport(const sp<IBinder>& display } } void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) { void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) { static_cast<void>(schedule([=] { static_cast<void>(schedule([=]() MAIN_THREAD { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { getHwComposer().setAutoLowLatencyMode(*displayId, on); getHwComposer().setAutoLowLatencyMode(*displayId, on); } else { } else { Loading Loading @@ -1253,7 +1287,7 @@ status_t SurfaceFlinger::getGameContentTypeSupport(const sp<IBinder>& displayTok } } void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) { void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) { static_cast<void>(schedule([=] { static_cast<void>(schedule([=]() MAIN_THREAD { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE; const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE; getHwComposer().setContentType(*displayId, type); getHwComposer().setContentType(*displayId, type); Loading Loading @@ -1343,7 +1377,7 @@ status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder> status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken, status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken, bool enable, uint8_t componentMask, bool enable, uint8_t componentMask, uint64_t maxFrames) { uint64_t maxFrames) { return schedule([=]() -> status_t { return schedule([=]() MAIN_THREAD -> status_t { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable, return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable, componentMask, componentMask, Loading Loading @@ -1412,13 +1446,9 @@ status_t SurfaceFlinger::injectVSync(nsecs_t when) { return mScheduler->injectVSync(when, calculateExpectedPresentTime(when)) ? NO_ERROR : BAD_VALUE; return mScheduler->injectVSync(when, calculateExpectedPresentTime(when)) ? NO_ERROR : BAD_VALUE; } } status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const { NO_THREAD_SAFETY_ANALYSIS { TimedLock lock(mStateLock, s2ns(1), __FUNCTION__); // Try to acquire a lock for 1s, fail gracefully if (!lock.locked()) { const status_t err = mStateLock.timedLock(s2ns(1)); const bool locked = (err == NO_ERROR); if (!locked) { ALOGE("LayerDebugInfo: SurfaceFlinger unresponsive (%s [%d]) - exit", strerror(-err), err); return TIMED_OUT; return TIMED_OUT; } } Loading @@ -1427,7 +1457,6 @@ status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayer mCurrentState.traverseInZOrder( mCurrentState.traverseInZOrder( [&](Layer* layer) { outLayers->push_back(layer->getLayerDebugInfo(display.get())); }); [&](Layer* layer) { outLayers->push_back(layer->getLayerDebugInfo(display.get())); }); mStateLock.unlock(); return NO_ERROR; return NO_ERROR; } } Loading Loading @@ -1484,7 +1513,7 @@ status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken, f return BAD_VALUE; return BAD_VALUE; } } return promise::chain(schedule([=] { return promise::chain(schedule([=]() MAIN_THREAD { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { return getHwComposer().setDisplayBrightness(*displayId, brightness); return getHwComposer().setDisplayBrightness(*displayId, brightness); } else { } else { Loading Loading @@ -1597,7 +1626,7 @@ void SurfaceFlinger::changeRefreshRateLocked(const RefreshRate& refreshRate, } } void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, hal::Connection connection) NO_THREAD_SAFETY_ANALYSIS { hal::Connection connection) { ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId, ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId, connection == hal::Connection::CONNECTED ? "connected" : "disconnected"); connection == hal::Connection::CONNECTED ? "connected" : "disconnected"); Loading Loading @@ -1650,8 +1679,7 @@ void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) { // Enable / Disable HWVsync from the main thread to avoid race conditions with // Enable / Disable HWVsync from the main thread to avoid race conditions with // display power state. // display power state. static_cast<void>( static_cast<void>(schedule([=]() MAIN_THREAD { setPrimaryVsyncEnabledInternal(enabled); })); schedule([=]() NO_THREAD_SAFETY_ANALYSIS { setPrimaryVsyncEnabledInternal(enabled); })); } } void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) { void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) { Loading @@ -1667,7 +1695,6 @@ void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) { } } } } // Note: it is assumed the caller holds |mStateLock| when this is called void SurfaceFlinger::resetDisplayState() { void SurfaceFlinger::resetDisplayState() { mScheduler->disableHardwareVsync(true); mScheduler->disableHardwareVsync(true); // Clear the drawing state so that the logic inside of // Clear the drawing state so that the logic inside of Loading Loading @@ -1760,7 +1787,7 @@ void SurfaceFlinger::updateVrFlinger() { setTransactionFlags(eDisplayTransactionNeeded); setTransactionFlags(eDisplayTransactionNeeded); } } sp<Fence> SurfaceFlinger::previousFrameFence() NO_THREAD_SAFETY_ANALYSIS { sp<Fence> SurfaceFlinger::previousFrameFence() { // We are storing the last 2 present fences. If sf's phase offset is to be // We are storing the last 2 present fences. If sf's phase offset is to be // woken up before the actual vsync but targeting the next vsync, we need to check // woken up before the actual vsync but targeting the next vsync, we need to check // fence N-2 // fence N-2 Loading @@ -1768,7 +1795,7 @@ sp<Fence> SurfaceFlinger::previousFrameFence() NO_THREAD_SAFETY_ANALYSIS { : mPreviousPresentFences[1]; : mPreviousPresentFences[1]; } } bool SurfaceFlinger::previousFramePending(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS { bool SurfaceFlinger::previousFramePending(int graceTimeMs) { ATRACE_CALL(); ATRACE_CALL(); const sp<Fence>& fence = previousFrameFence(); const sp<Fence>& fence = previousFrameFence(); Loading @@ -1782,7 +1809,7 @@ bool SurfaceFlinger::previousFramePending(int graceTimeMs) NO_THREAD_SAFETY_ANAL return status == -ETIME; return status == -ETIME; } } nsecs_t SurfaceFlinger::previousFramePresentTime() NO_THREAD_SAFETY_ANALYSIS { nsecs_t SurfaceFlinger::previousFramePresentTime() { const sp<Fence>& fence = previousFrameFence(); const sp<Fence>& fence = previousFrameFence(); if (fence == Fence::NO_FENCE) { if (fence == Fence::NO_FENCE) { Loading @@ -1800,8 +1827,7 @@ nsecs_t SurfaceFlinger::calculateExpectedPresentTime(nsecs_t now) const { return mVSyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod; return mVSyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod; } } void SurfaceFlinger::onMessageReceived(int32_t what, void SurfaceFlinger::onMessageReceived(int32_t what, nsecs_t expectedVSyncTime) { nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS { ATRACE_CALL(); ATRACE_CALL(); switch (what) { switch (what) { case MessageQueue::INVALIDATE: { case MessageQueue::INVALIDATE: { Loading @@ -1815,7 +1841,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what, } } } } void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS { void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) { ATRACE_CALL(); ATRACE_CALL(); const nsecs_t frameStart = systemTime(); const nsecs_t frameStart = systemTime(); Loading Loading @@ -1888,7 +1914,7 @@ void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SA // We received the present fence from the HWC, so we assume it successfully updated // We received the present fence from the HWC, so we assume it successfully updated // the config, hence we update SF. // the config, hence we update SF. mSetActiveConfigPending = false; mSetActiveConfigPending = false; setActiveConfigInternal(); ON_MAIN_THREAD(setActiveConfigInternal()); } } if (framePending && mPropagateBackpressure) { if (framePending && mPropagateBackpressure) { Loading @@ -1907,12 +1933,12 @@ void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SA std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count(); std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count(); // If we're in a user build then don't push any atoms // If we're in a user build then don't push any atoms if (!mIsUserBuild && mMissedFrameJankCount > 0) { if (!mIsUserBuild && mMissedFrameJankCount > 0) { const auto displayDevice = getDefaultDisplayDeviceLocked(); const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); // Only report jank when the display is on, as displays in DOZE // Only report jank when the display is on, as displays in DOZE // power mode may operate at a different frame rate than is // power mode may operate at a different frame rate than is // reported in their config, which causes noticeable (but less // reported in their config, which causes noticeable (but less // severe) jank. // severe) jank. if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) { if (display && display->getPowerMode() == hal::PowerMode::ON) { const nsecs_t currentTime = systemTime(); const nsecs_t currentTime = systemTime(); const nsecs_t jankDuration = currentTime - mMissedFrameJankStart; const nsecs_t jankDuration = currentTime - mMissedFrameJankStart; if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) { if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) { Loading Loading @@ -1969,7 +1995,7 @@ void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SA mScheduler->chooseRefreshRateForContent(); mScheduler->chooseRefreshRateForContent(); } } performSetActiveConfig(); ON_MAIN_THREAD(performSetActiveConfig()); updateCursorAsync(); updateCursorAsync(); updateInputFlinger(); updateInputFlinger(); Loading Loading @@ -2018,8 +2044,9 @@ void SurfaceFlinger::onMessageRefresh() { mRefreshPending = false; mRefreshPending = false; compositionengine::CompositionRefreshArgs refreshArgs; compositionengine::CompositionRefreshArgs refreshArgs; refreshArgs.outputs.reserve(mDisplays.size()); const auto& displays = ON_MAIN_THREAD(mDisplays); for (const auto& [_, display] : mDisplays) { refreshArgs.outputs.reserve(displays.size()); for (const auto& [_, display] : displays) { refreshArgs.outputs.push_back(display->getCompositionDisplay()); refreshArgs.outputs.push_back(display->getCompositionDisplay()); } } mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) { mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) { Loading Loading @@ -2074,21 +2101,18 @@ void SurfaceFlinger::onMessageRefresh() { const bool prevFrameHadDeviceComposition = mHadDeviceComposition; const bool prevFrameHadDeviceComposition = mHadDeviceComposition; mHadClientComposition = mHadClientComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) { std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) { const auto& state = pair.second->getCompositionDisplay()->getState(); auto& displayDevice = tokenDisplayPair.second; return state.usesClientComposition && !state.reusedClientComposition; return displayDevice->getCompositionDisplay()->getState().usesClientComposition && !displayDevice->getCompositionDisplay()->getState().reusedClientComposition; }); }); mHadDeviceComposition = mHadDeviceComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) { std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) { const auto& state = pair.second->getCompositionDisplay()->getState(); auto& displayDevice = tokenDisplayPair.second; return state.usesDeviceComposition; return displayDevice->getCompositionDisplay()->getState().usesDeviceComposition; }); }); mReusedClientComposition = mReusedClientComposition = std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) { std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) { auto& displayDevice = tokenDisplayPair.second; const auto& state = pair.second->getCompositionDisplay()->getState(); return displayDevice->getCompositionDisplay()->getState().reusedClientComposition; return state.reusedClientComposition; }); }); // Only report a strategy change if we move in and out of composition with hw overlays // Only report a strategy change if we move in and out of composition with hw overlays Loading Loading @@ -2194,14 +2218,14 @@ void SurfaceFlinger::postComposition() for (auto& layer : mLayersWithQueuedFrames) { for (auto& layer : mLayersWithQueuedFrames) { layer->releasePendingBuffer(dequeueReadyTime); layer->releasePendingBuffer(dequeueReadyTime); } } // |mStateLock| not needed as we are on the main thread const auto displayDevice = getDefaultDisplayDeviceLocked(); const auto* display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()).get(); getBE().mGlCompositionDoneTimeline.updateSignalTimes(); getBE().mGlCompositionDoneTimeline.updateSignalTimes(); std::shared_ptr<FenceTime> glCompositionDoneFenceTime; std::shared_ptr<FenceTime> glCompositionDoneFenceTime; if (displayDevice && displayDevice->getCompositionDisplay()->getState().usesClientComposition) { if (display && display->getCompositionDisplay()->getState().usesClientComposition) { glCompositionDoneFenceTime = glCompositionDoneFenceTime = std::make_shared<FenceTime>(displayDevice->getCompositionDisplay() std::make_shared<FenceTime>(display->getCompositionDisplay() ->getRenderSurface() ->getRenderSurface() ->getClientTargetAcquireFence()); ->getClientTargetAcquireFence()); getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime); getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime); Loading @@ -2211,9 +2235,8 @@ void SurfaceFlinger::postComposition() getBE().mDisplayTimeline.updateSignalTimes(); getBE().mDisplayTimeline.updateSignalTimes(); mPreviousPresentFences[1] = mPreviousPresentFences[0]; mPreviousPresentFences[1] = mPreviousPresentFences[0]; mPreviousPresentFences[0] = displayDevice mPreviousPresentFences[0] = ? getHwComposer().getPresentFence(*displayDevice->getId()) display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE; : Fence::NO_FENCE; auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]); auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]); getBE().mDisplayTimeline.push(presentFenceTime); getBE().mDisplayTimeline.push(presentFenceTime); Loading @@ -2232,8 +2255,7 @@ void SurfaceFlinger::postComposition() } } mDrawingState.traverse([&](Layer* layer) { mDrawingState.traverse([&](Layer* layer) { const bool frameLatched = const bool frameLatched = layer->onPostComposition(display, glCompositionDoneFenceTime, layer->onPostComposition(displayDevice.get(), glCompositionDoneFenceTime, presentFenceTime, compositorTiming); presentFenceTime, compositorTiming); if (frameLatched) { if (frameLatched) { recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); Loading @@ -2243,14 +2265,15 @@ void SurfaceFlinger::postComposition() mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]); mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]); mTransactionCompletedThread.sendCallbacks(); mTransactionCompletedThread.sendCallbacks(); if (displayDevice && displayDevice->isPrimary() && if (display && display->isPrimary() && display->getPowerMode() == hal::PowerMode::ON && displayDevice->getPowerMode() == hal::PowerMode::ON && presentFenceTime->isValid()) { presentFenceTime->isValid()) { mScheduler->addPresentFence(presentFenceTime); mScheduler->addPresentFence(presentFenceTime); } } const bool isDisplayConnected = display && getHwComposer().isConnected(*display->getId()); if (!hasSyncFramework) { if (!hasSyncFramework) { if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) && if (isDisplayConnected && display->isPoweredOn()) { displayDevice->isPoweredOn()) { mScheduler->enableHardwareVsync(); mScheduler->enableHardwareVsync(); } } } } Loading @@ -2261,11 +2284,10 @@ void SurfaceFlinger::postComposition() if (presentFenceTime->isValid()) { if (presentFenceTime->isValid()) { mAnimFrameTracker.setActualPresentFence( mAnimFrameTracker.setActualPresentFence( std::move(presentFenceTime)); std::move(presentFenceTime)); } else if (displayDevice && getHwComposer().isConnected(*displayDevice->getId())) { } else if (isDisplayConnected) { // The HWC doesn't support present fences, so use the refresh // The HWC doesn't support present fences, so use the refresh // timestamp instead. // timestamp instead. const nsecs_t presentTime = const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId()); getHwComposer().getRefreshTimestamp(*displayDevice->getId()); mAnimFrameTracker.setActualPresentTime(presentTime); mAnimFrameTracker.setActualPresentTime(presentTime); } } mAnimFrameTracker.advanceFrame(); mAnimFrameTracker.advanceFrame(); Loading @@ -2286,8 +2308,7 @@ void SurfaceFlinger::postComposition() const size_t appConnections = mScheduler->getEventThreadConnectionCount(mAppConnectionHandle); const size_t appConnections = mScheduler->getEventThreadConnectionCount(mAppConnectionHandle); mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections); mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections); if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) && if (isDisplayConnected && !display->isPoweredOn()) { !displayDevice->isPoweredOn()) { return; return; } } Loading Loading @@ -2343,7 +2364,7 @@ FloatRect SurfaceFlinger::getLayerClipBoundsForDisplay(const DisplayDevice& disp } } void SurfaceFlinger::computeLayerBounds() { void SurfaceFlinger::computeLayerBounds() { for (const auto& pair : mDisplays) { for (const auto& pair : ON_MAIN_THREAD(mDisplays)) { const auto& displayDevice = pair.second; const auto& displayDevice = pair.second; const auto display = displayDevice->getCompositionDisplay(); const auto display = displayDevice->getCompositionDisplay(); for (const auto& layer : mDrawingState.layersSortedByZ) { for (const auto& layer : mDrawingState.layersSortedByZ) { Loading @@ -2358,10 +2379,8 @@ void SurfaceFlinger::computeLayerBounds() { } } } } void SurfaceFlinger::postFrame() void SurfaceFlinger::postFrame() { { const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); // |mStateLock| not needed as we are on the main thread const auto display = getDefaultDisplayDeviceLocked(); if (display && getHwComposer().isConnected(*display->getId())) { if (display && getHwComposer().isConnected(*display->getId())) { uint32_t flipCount = display->getPageFlipCount(); uint32_t flipCount = display->getPageFlipCount(); if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { Loading Loading @@ -2789,7 +2808,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) sp<const DisplayDevice> hintDisplay; sp<const DisplayDevice> hintDisplay; uint32_t currentlayerStack = 0; uint32_t currentlayerStack = 0; bool first = true; bool first = true; mCurrentState.traverse([&](Layer* layer) { mCurrentState.traverse([&](Layer* layer) REQUIRES(mStateLock) { // NOTE: we rely on the fact that layers are sorted by // NOTE: we rely on the fact that layers are sorted by // layerStack first (so we don't have to traverse the list // layerStack first (so we don't have to traverse the list // of displays for every layer). // of displays for every layer). Loading Loading @@ -2902,10 +2921,9 @@ void SurfaceFlinger::commitInputWindowCommands() { mPendingInputWindowCommands.clear(); mPendingInputWindowCommands.clear(); } } void SurfaceFlinger::updateCursorAsync() void SurfaceFlinger::updateCursorAsync() { { compositionengine::CompositionRefreshArgs refreshArgs; compositionengine::CompositionRefreshArgs refreshArgs; for (const auto& [_, display] : mDisplays) { for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) { if (display->getId()) { if (display->getId()) { refreshArgs.outputs.push_back(display->getCompositionDisplay()); refreshArgs.outputs.push_back(display->getCompositionDisplay()); } } Loading @@ -2915,7 +2933,7 @@ void SurfaceFlinger::updateCursorAsync() } } void SurfaceFlinger::changeRefreshRate(const RefreshRate& refreshRate, void SurfaceFlinger::changeRefreshRate(const RefreshRate& refreshRate, Scheduler::ConfigEvent event) NO_THREAD_SAFETY_ANALYSIS { Scheduler::ConfigEvent event) { // If this is called from the main thread mStateLock must be locked before // If this is called from the main thread mStateLock must be locked before // Currently the only way to call this function from the main thread is from // Currently the only way to call this function from the main thread is from // Sheduler::chooseRefreshRateForContent // Sheduler::chooseRefreshRateForContent Loading Loading @@ -3041,7 +3059,7 @@ void SurfaceFlinger::commitOffscreenLayers() { } } void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) { void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) { for (const auto& [token, displayDevice] : mDisplays) { for (const auto& [token, displayDevice] : ON_MAIN_THREAD(mDisplays)) { auto display = displayDevice->getCompositionDisplay(); auto display = displayDevice->getCompositionDisplay(); if (display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) { if (display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) { display->editState().dirtyRegion.orSelf(dirty); display->editState().dirtyRegion.orSelf(dirty); Loading Loading @@ -4137,7 +4155,7 @@ void SurfaceFlinger::onInitializeDisplays() { void SurfaceFlinger::initializeDisplays() { void SurfaceFlinger::initializeDisplays() { // Async since we may be called from the main thread. // Async since we may be called from the main thread. static_cast<void>(schedule([this]() NO_THREAD_SAFETY_ANALYSIS { onInitializeDisplays(); })); static_cast<void>(schedule([this]() MAIN_THREAD { onInitializeDisplays(); })); } } void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled) { void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled) { Loading Loading @@ -4228,7 +4246,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: } } void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { schedule([=]() NO_THREAD_SAFETY_ANALYSIS { schedule([=]() MAIN_THREAD { const auto display = getDisplayDeviceLocked(displayToken); const auto display = getDisplayDeviceLocked(displayToken); if (!display) { if (!display) { ALOGE("Attempt to set power mode %d for invalid display token %p", mode, ALOGE("Attempt to set power mode %d for invalid display token %p", mode, Loading @@ -4241,8 +4259,7 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { }).wait(); }).wait(); } } status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) { bool asProto) NO_THREAD_SAFETY_ANALYSIS { std::string result; std::string result; IPCThreadState* ipc = IPCThreadState::self(); IPCThreadState* ipc = IPCThreadState::self(); Loading @@ -4254,18 +4271,6 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n", StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); pid, uid); } else { } else { // Try to get the main lock, but give up after one second // (this would indicate SF is stuck, but we want to be able to // print something in dumpsys). status_t err = mStateLock.timedLock(s2ns(1)); bool locked = (err == NO_ERROR); if (!locked) { StringAppendF(&result, "SurfaceFlinger appears to be unresponsive (%s [%d]), dumping anyways " "(no locks held)\n", strerror(-err), err); } static const std::unordered_map<std::string, Dumper> dumpers = { static const std::unordered_map<std::string, Dumper> dumpers = { {"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)}, {"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)}, {"--dispsync"s, {"--dispsync"s, Loading @@ -4283,18 +4288,23 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, const auto flag = args.empty() ? ""s : std::string(String8(args[0])); const auto flag = args.empty() ? ""s : std::string(String8(args[0])); const auto it = dumpers.find(flag); bool dumpLayers = true; if (it != dumpers.end()) { { TimedLock lock(mStateLock, s2ns(1), __FUNCTION__); if (!lock.locked()) { StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n", strerror(-lock.status), lock.status); } if (const auto it = dumpers.find(flag); it != dumpers.end()) { (it->second)(args, asProto, result); (it->second)(args, asProto, result); dumpLayers = false; } else if (!asProto) { } else if (!asProto) { dumpAllLocked(args, result); dumpAllLocked(args, result); } } if (locked) { mStateLock.unlock(); } } if (it == dumpers.end()) { if (dumpLayers) { const LayersProto layersProto = dumpProtoFromMainThread(); const LayersProto layersProto = dumpProtoFromMainThread(); if (asProto) { if (asProto) { result.append(layersProto.SerializeAsString()); result.append(layersProto.SerializeAsString()); Loading Loading @@ -4568,7 +4578,7 @@ void SurfaceFlinger::dumpWideColorInfo(std::string& result) const { LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const { LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const { // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread. // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread. const auto display = getDefaultDisplayDeviceLocked(); const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); LayersProto layersProto; LayersProto layersProto; for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) { for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) { Loading Loading @@ -5404,7 +5414,7 @@ status_t SurfaceFlinger::setSchedFifo(bool enabled) { return NO_ERROR; return NO_ERROR; } } const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) { sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) { const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack}); const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack}); if (displayToken) { if (displayToken) { return getDisplayDeviceLocked(displayToken); return getDisplayDeviceLocked(displayToken); Loading @@ -5414,7 +5424,7 @@ const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t disp return getDisplayByLayerStack(displayOrLayerStack); return getDisplayByLayerStack(displayOrLayerStack); } } const sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) { sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) { for (const auto& [token, display] : mDisplays) { for (const auto& [token, display] : mDisplays) { if (display->getLayerStack() == layerStack) { if (display->getLayerStack() == layerStack) { return display; return display; Loading Loading @@ -5989,7 +5999,7 @@ status_t SurfaceFlinger::setDesiredDisplayConfigSpecs(const sp<IBinder>& display } } auto future = schedule([=]() -> status_t { auto future = schedule([=]() -> status_t { const auto display = getDisplayDeviceLocked(displayToken); const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken)); if (!display) { if (!display) { ALOGE("Attempt to set desired display configs for invalid display token %p", ALOGE("Attempt to set desired display configs for invalid display token %p", displayToken.get()); displayToken.get()); Loading Loading @@ -6144,7 +6154,7 @@ status_t SurfaceFlinger::setFrameRate(const sp<IGraphicBufferProducer>& surface, return BAD_VALUE; return BAD_VALUE; } } static_cast<void>(schedule([=]() NO_THREAD_SAFETY_ANALYSIS { static_cast<void>(schedule([=] { Mutex::Autolock lock(mStateLock); Mutex::Autolock lock(mStateLock); if (authenticateSurfaceTextureLocked(surface)) { if (authenticateSurfaceTextureLocked(surface)) { sp<Layer> layer = (static_cast<MonitoredProducer*>(surface.get()))->getLayer(); sp<Layer> layer = (static_cast<MonitoredProducer*>(surface.get()))->getLayer(); Loading Loading @@ -6173,8 +6183,7 @@ status_t SurfaceFlinger::acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) sp<IBinder> token; sp<IBinder> token; if (mFrameRateFlexibilityTokenCount == 0) { if (mFrameRateFlexibilityTokenCount == 0) { // |mStateLock| not needed as we are on the main thread const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); const auto display = getDefaultDisplayDeviceLocked(); // This is a little racy, but not in a way that hurts anything. As we grab the // This is a little racy, but not in a way that hurts anything. As we grab the // defaultConfig from the display manager policy, we could be setting a new display // defaultConfig from the display manager policy, we could be setting a new display Loading Loading @@ -6224,8 +6233,7 @@ void SurfaceFlinger::onFrameRateFlexibilityTokenReleased() { mFrameRateFlexibilityTokenCount--; mFrameRateFlexibilityTokenCount--; ALOGD("Frame rate flexibility token released. count=%d", mFrameRateFlexibilityTokenCount); ALOGD("Frame rate flexibility token released. count=%d", mFrameRateFlexibilityTokenCount); if (mFrameRateFlexibilityTokenCount == 0) { if (mFrameRateFlexibilityTokenCount == 0) { // |mStateLock| not needed as we are on the main thread const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); const auto display = getDefaultDisplayDeviceLocked(); constexpr bool kOverridePolicy = true; constexpr bool kOverridePolicy = true; status_t result = setDesiredDisplayConfigSpecsInternal(display, {}, kOverridePolicy); status_t result = setDesiredDisplayConfigSpecsInternal(display, {}, kOverridePolicy); LOG_ALWAYS_FATAL_IF(result < 0, "Failed releasing frame rate flexibility token"); LOG_ALWAYS_FATAL_IF(result < 0, "Failed releasing frame rate flexibility token"); Loading services/surfaceflinger/SurfaceFlinger.h +29 −31 File changed.Preview size limit exceeded, changes collapsed. Show changes services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -289,14 +289,14 @@ public: return mFlinger->destroyDisplay(displayToken); return mFlinger->destroyDisplay(displayToken); } } auto resetDisplayState() { return mFlinger->resetDisplayState(); } auto resetDisplayState() NO_THREAD_SAFETY_ANALYSIS { return mFlinger->resetDisplayState(); } auto setupNewDisplayDeviceInternal( auto setupNewDisplayDeviceInternal( const wp<IBinder>& displayToken, const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay, std::shared_ptr<compositionengine::Display> compositionDisplay, const DisplayDeviceState& state, const DisplayDeviceState& state, const sp<compositionengine::DisplaySurface>& dispSurface, const sp<compositionengine::DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) { const sp<IGraphicBufferProducer>& producer) NO_THREAD_SAFETY_ANALYSIS { return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, dispSurface, producer); dispSurface, producer); } } Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +119 −111 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,19 @@ #include "android-base/parseint.h" #include "android-base/parseint.h" #include "android-base/stringprintf.h" #include "android-base/stringprintf.h" #define MAIN_THREAD ACQUIRE(mStateLock) RELEASE(mStateLock) #define ON_MAIN_THREAD(expr) \ [&] { \ LOG_FATAL_IF(std::this_thread::get_id() != mMainThreadId); \ UnnecessaryLock lock(mStateLock); \ return (expr); \ }() #undef NO_THREAD_SAFETY_ANALYSIS #define NO_THREAD_SAFETY_ANALYSIS \ _Pragma("GCC error \"Prefer MAIN_THREAD macros or {Conditional,Timed,Unnecessary}Lock.\"") namespace android { namespace android { using namespace std::string_literals; using namespace std::string_literals; Loading Loading @@ -173,12 +186,12 @@ bool isWideColorMode(const ColorMode colorMode) { #pragma clang diagnostic pop #pragma clang diagnostic pop template <typename Mutex> template <typename Mutex> struct ConditionalLockGuard { struct SCOPED_CAPABILITY ConditionalLockGuard { ConditionalLockGuard(Mutex& mutex, bool lock) : mutex(mutex), lock(lock) { ConditionalLockGuard(Mutex& mutex, bool lock) ACQUIRE(mutex) : mutex(mutex), lock(lock) { if (lock) mutex.lock(); if (lock) mutex.lock(); } } ~ConditionalLockGuard() { ~ConditionalLockGuard() RELEASE() { if (lock) mutex.unlock(); if (lock) mutex.unlock(); } } Loading @@ -188,6 +201,27 @@ struct ConditionalLockGuard { using ConditionalLock = ConditionalLockGuard<Mutex>; using ConditionalLock = ConditionalLockGuard<Mutex>; struct SCOPED_CAPABILITY TimedLock { TimedLock(Mutex& mutex, nsecs_t timeout, const char* whence) ACQUIRE(mutex) : mutex(mutex), status(mutex.timedLock(timeout)) { ALOGE_IF(!locked(), "%s timed out locking: %s (%d)", whence, strerror(-status), status); } ~TimedLock() RELEASE() { if (locked()) mutex.unlock(); } bool locked() const { return status == NO_ERROR; } Mutex& mutex; const status_t status; }; struct SCOPED_CAPABILITY UnnecessaryLock { explicit UnnecessaryLock(Mutex& mutex) ACQUIRE(mutex) {} ~UnnecessaryLock() RELEASE() {} }; // TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity. // TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity. constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV; constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV; Loading Loading @@ -991,7 +1025,7 @@ status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& displayToken, int mo } } auto future = schedule([=]() -> status_t { auto future = schedule([=]() -> status_t { const auto display = getDisplayDeviceLocked(displayToken); const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken)); if (!display) { if (!display) { ALOGE("Attempt to set allowed display configs for invalid display token %p", ALOGE("Attempt to set allowed display configs for invalid display token %p", displayToken.get()); displayToken.get()); Loading Loading @@ -1176,7 +1210,7 @@ ColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& displayToken) { } } status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) { status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) { schedule([=] { schedule([=]() MAIN_THREAD { Vector<ColorMode> modes; Vector<ColorMode> modes; getDisplayColorModes(displayToken, &modes); getDisplayColorModes(displayToken, &modes); bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes); bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes); Loading Loading @@ -1222,7 +1256,7 @@ status_t SurfaceFlinger::getAutoLowLatencyModeSupport(const sp<IBinder>& display } } void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) { void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) { static_cast<void>(schedule([=] { static_cast<void>(schedule([=]() MAIN_THREAD { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { getHwComposer().setAutoLowLatencyMode(*displayId, on); getHwComposer().setAutoLowLatencyMode(*displayId, on); } else { } else { Loading Loading @@ -1253,7 +1287,7 @@ status_t SurfaceFlinger::getGameContentTypeSupport(const sp<IBinder>& displayTok } } void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) { void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) { static_cast<void>(schedule([=] { static_cast<void>(schedule([=]() MAIN_THREAD { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE; const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE; getHwComposer().setContentType(*displayId, type); getHwComposer().setContentType(*displayId, type); Loading Loading @@ -1343,7 +1377,7 @@ status_t SurfaceFlinger::getDisplayedContentSamplingAttributes(const sp<IBinder> status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken, status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken, bool enable, uint8_t componentMask, bool enable, uint8_t componentMask, uint64_t maxFrames) { uint64_t maxFrames) { return schedule([=]() -> status_t { return schedule([=]() MAIN_THREAD -> status_t { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable, return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable, componentMask, componentMask, Loading Loading @@ -1412,13 +1446,9 @@ status_t SurfaceFlinger::injectVSync(nsecs_t when) { return mScheduler->injectVSync(when, calculateExpectedPresentTime(when)) ? NO_ERROR : BAD_VALUE; return mScheduler->injectVSync(when, calculateExpectedPresentTime(when)) ? NO_ERROR : BAD_VALUE; } } status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const { NO_THREAD_SAFETY_ANALYSIS { TimedLock lock(mStateLock, s2ns(1), __FUNCTION__); // Try to acquire a lock for 1s, fail gracefully if (!lock.locked()) { const status_t err = mStateLock.timedLock(s2ns(1)); const bool locked = (err == NO_ERROR); if (!locked) { ALOGE("LayerDebugInfo: SurfaceFlinger unresponsive (%s [%d]) - exit", strerror(-err), err); return TIMED_OUT; return TIMED_OUT; } } Loading @@ -1427,7 +1457,6 @@ status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayer mCurrentState.traverseInZOrder( mCurrentState.traverseInZOrder( [&](Layer* layer) { outLayers->push_back(layer->getLayerDebugInfo(display.get())); }); [&](Layer* layer) { outLayers->push_back(layer->getLayerDebugInfo(display.get())); }); mStateLock.unlock(); return NO_ERROR; return NO_ERROR; } } Loading Loading @@ -1484,7 +1513,7 @@ status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken, f return BAD_VALUE; return BAD_VALUE; } } return promise::chain(schedule([=] { return promise::chain(schedule([=]() MAIN_THREAD { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) { return getHwComposer().setDisplayBrightness(*displayId, brightness); return getHwComposer().setDisplayBrightness(*displayId, brightness); } else { } else { Loading Loading @@ -1597,7 +1626,7 @@ void SurfaceFlinger::changeRefreshRateLocked(const RefreshRate& refreshRate, } } void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, hal::Connection connection) NO_THREAD_SAFETY_ANALYSIS { hal::Connection connection) { ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId, ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId, connection == hal::Connection::CONNECTED ? "connected" : "disconnected"); connection == hal::Connection::CONNECTED ? "connected" : "disconnected"); Loading Loading @@ -1650,8 +1679,7 @@ void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) { // Enable / Disable HWVsync from the main thread to avoid race conditions with // Enable / Disable HWVsync from the main thread to avoid race conditions with // display power state. // display power state. static_cast<void>( static_cast<void>(schedule([=]() MAIN_THREAD { setPrimaryVsyncEnabledInternal(enabled); })); schedule([=]() NO_THREAD_SAFETY_ANALYSIS { setPrimaryVsyncEnabledInternal(enabled); })); } } void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) { void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) { Loading @@ -1667,7 +1695,6 @@ void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) { } } } } // Note: it is assumed the caller holds |mStateLock| when this is called void SurfaceFlinger::resetDisplayState() { void SurfaceFlinger::resetDisplayState() { mScheduler->disableHardwareVsync(true); mScheduler->disableHardwareVsync(true); // Clear the drawing state so that the logic inside of // Clear the drawing state so that the logic inside of Loading Loading @@ -1760,7 +1787,7 @@ void SurfaceFlinger::updateVrFlinger() { setTransactionFlags(eDisplayTransactionNeeded); setTransactionFlags(eDisplayTransactionNeeded); } } sp<Fence> SurfaceFlinger::previousFrameFence() NO_THREAD_SAFETY_ANALYSIS { sp<Fence> SurfaceFlinger::previousFrameFence() { // We are storing the last 2 present fences. If sf's phase offset is to be // We are storing the last 2 present fences. If sf's phase offset is to be // woken up before the actual vsync but targeting the next vsync, we need to check // woken up before the actual vsync but targeting the next vsync, we need to check // fence N-2 // fence N-2 Loading @@ -1768,7 +1795,7 @@ sp<Fence> SurfaceFlinger::previousFrameFence() NO_THREAD_SAFETY_ANALYSIS { : mPreviousPresentFences[1]; : mPreviousPresentFences[1]; } } bool SurfaceFlinger::previousFramePending(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS { bool SurfaceFlinger::previousFramePending(int graceTimeMs) { ATRACE_CALL(); ATRACE_CALL(); const sp<Fence>& fence = previousFrameFence(); const sp<Fence>& fence = previousFrameFence(); Loading @@ -1782,7 +1809,7 @@ bool SurfaceFlinger::previousFramePending(int graceTimeMs) NO_THREAD_SAFETY_ANAL return status == -ETIME; return status == -ETIME; } } nsecs_t SurfaceFlinger::previousFramePresentTime() NO_THREAD_SAFETY_ANALYSIS { nsecs_t SurfaceFlinger::previousFramePresentTime() { const sp<Fence>& fence = previousFrameFence(); const sp<Fence>& fence = previousFrameFence(); if (fence == Fence::NO_FENCE) { if (fence == Fence::NO_FENCE) { Loading @@ -1800,8 +1827,7 @@ nsecs_t SurfaceFlinger::calculateExpectedPresentTime(nsecs_t now) const { return mVSyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod; return mVSyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod; } } void SurfaceFlinger::onMessageReceived(int32_t what, void SurfaceFlinger::onMessageReceived(int32_t what, nsecs_t expectedVSyncTime) { nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS { ATRACE_CALL(); ATRACE_CALL(); switch (what) { switch (what) { case MessageQueue::INVALIDATE: { case MessageQueue::INVALIDATE: { Loading @@ -1815,7 +1841,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what, } } } } void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS { void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) { ATRACE_CALL(); ATRACE_CALL(); const nsecs_t frameStart = systemTime(); const nsecs_t frameStart = systemTime(); Loading Loading @@ -1888,7 +1914,7 @@ void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SA // We received the present fence from the HWC, so we assume it successfully updated // We received the present fence from the HWC, so we assume it successfully updated // the config, hence we update SF. // the config, hence we update SF. mSetActiveConfigPending = false; mSetActiveConfigPending = false; setActiveConfigInternal(); ON_MAIN_THREAD(setActiveConfigInternal()); } } if (framePending && mPropagateBackpressure) { if (framePending && mPropagateBackpressure) { Loading @@ -1907,12 +1933,12 @@ void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SA std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count(); std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count(); // If we're in a user build then don't push any atoms // If we're in a user build then don't push any atoms if (!mIsUserBuild && mMissedFrameJankCount > 0) { if (!mIsUserBuild && mMissedFrameJankCount > 0) { const auto displayDevice = getDefaultDisplayDeviceLocked(); const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); // Only report jank when the display is on, as displays in DOZE // Only report jank when the display is on, as displays in DOZE // power mode may operate at a different frame rate than is // power mode may operate at a different frame rate than is // reported in their config, which causes noticeable (but less // reported in their config, which causes noticeable (but less // severe) jank. // severe) jank. if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) { if (display && display->getPowerMode() == hal::PowerMode::ON) { const nsecs_t currentTime = systemTime(); const nsecs_t currentTime = systemTime(); const nsecs_t jankDuration = currentTime - mMissedFrameJankStart; const nsecs_t jankDuration = currentTime - mMissedFrameJankStart; if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) { if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) { Loading Loading @@ -1969,7 +1995,7 @@ void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) NO_THREAD_SA mScheduler->chooseRefreshRateForContent(); mScheduler->chooseRefreshRateForContent(); } } performSetActiveConfig(); ON_MAIN_THREAD(performSetActiveConfig()); updateCursorAsync(); updateCursorAsync(); updateInputFlinger(); updateInputFlinger(); Loading Loading @@ -2018,8 +2044,9 @@ void SurfaceFlinger::onMessageRefresh() { mRefreshPending = false; mRefreshPending = false; compositionengine::CompositionRefreshArgs refreshArgs; compositionengine::CompositionRefreshArgs refreshArgs; refreshArgs.outputs.reserve(mDisplays.size()); const auto& displays = ON_MAIN_THREAD(mDisplays); for (const auto& [_, display] : mDisplays) { refreshArgs.outputs.reserve(displays.size()); for (const auto& [_, display] : displays) { refreshArgs.outputs.push_back(display->getCompositionDisplay()); refreshArgs.outputs.push_back(display->getCompositionDisplay()); } } mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) { mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) { Loading Loading @@ -2074,21 +2101,18 @@ void SurfaceFlinger::onMessageRefresh() { const bool prevFrameHadDeviceComposition = mHadDeviceComposition; const bool prevFrameHadDeviceComposition = mHadDeviceComposition; mHadClientComposition = mHadClientComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) { std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) { const auto& state = pair.second->getCompositionDisplay()->getState(); auto& displayDevice = tokenDisplayPair.second; return state.usesClientComposition && !state.reusedClientComposition; return displayDevice->getCompositionDisplay()->getState().usesClientComposition && !displayDevice->getCompositionDisplay()->getState().reusedClientComposition; }); }); mHadDeviceComposition = mHadDeviceComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) { std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) { const auto& state = pair.second->getCompositionDisplay()->getState(); auto& displayDevice = tokenDisplayPair.second; return state.usesDeviceComposition; return displayDevice->getCompositionDisplay()->getState().usesDeviceComposition; }); }); mReusedClientComposition = mReusedClientComposition = std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) { std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) { auto& displayDevice = tokenDisplayPair.second; const auto& state = pair.second->getCompositionDisplay()->getState(); return displayDevice->getCompositionDisplay()->getState().reusedClientComposition; return state.reusedClientComposition; }); }); // Only report a strategy change if we move in and out of composition with hw overlays // Only report a strategy change if we move in and out of composition with hw overlays Loading Loading @@ -2194,14 +2218,14 @@ void SurfaceFlinger::postComposition() for (auto& layer : mLayersWithQueuedFrames) { for (auto& layer : mLayersWithQueuedFrames) { layer->releasePendingBuffer(dequeueReadyTime); layer->releasePendingBuffer(dequeueReadyTime); } } // |mStateLock| not needed as we are on the main thread const auto displayDevice = getDefaultDisplayDeviceLocked(); const auto* display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()).get(); getBE().mGlCompositionDoneTimeline.updateSignalTimes(); getBE().mGlCompositionDoneTimeline.updateSignalTimes(); std::shared_ptr<FenceTime> glCompositionDoneFenceTime; std::shared_ptr<FenceTime> glCompositionDoneFenceTime; if (displayDevice && displayDevice->getCompositionDisplay()->getState().usesClientComposition) { if (display && display->getCompositionDisplay()->getState().usesClientComposition) { glCompositionDoneFenceTime = glCompositionDoneFenceTime = std::make_shared<FenceTime>(displayDevice->getCompositionDisplay() std::make_shared<FenceTime>(display->getCompositionDisplay() ->getRenderSurface() ->getRenderSurface() ->getClientTargetAcquireFence()); ->getClientTargetAcquireFence()); getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime); getBE().mGlCompositionDoneTimeline.push(glCompositionDoneFenceTime); Loading @@ -2211,9 +2235,8 @@ void SurfaceFlinger::postComposition() getBE().mDisplayTimeline.updateSignalTimes(); getBE().mDisplayTimeline.updateSignalTimes(); mPreviousPresentFences[1] = mPreviousPresentFences[0]; mPreviousPresentFences[1] = mPreviousPresentFences[0]; mPreviousPresentFences[0] = displayDevice mPreviousPresentFences[0] = ? getHwComposer().getPresentFence(*displayDevice->getId()) display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE; : Fence::NO_FENCE; auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]); auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]); getBE().mDisplayTimeline.push(presentFenceTime); getBE().mDisplayTimeline.push(presentFenceTime); Loading @@ -2232,8 +2255,7 @@ void SurfaceFlinger::postComposition() } } mDrawingState.traverse([&](Layer* layer) { mDrawingState.traverse([&](Layer* layer) { const bool frameLatched = const bool frameLatched = layer->onPostComposition(display, glCompositionDoneFenceTime, layer->onPostComposition(displayDevice.get(), glCompositionDoneFenceTime, presentFenceTime, compositorTiming); presentFenceTime, compositorTiming); if (frameLatched) { if (frameLatched) { recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); Loading @@ -2243,14 +2265,15 @@ void SurfaceFlinger::postComposition() mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]); mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]); mTransactionCompletedThread.sendCallbacks(); mTransactionCompletedThread.sendCallbacks(); if (displayDevice && displayDevice->isPrimary() && if (display && display->isPrimary() && display->getPowerMode() == hal::PowerMode::ON && displayDevice->getPowerMode() == hal::PowerMode::ON && presentFenceTime->isValid()) { presentFenceTime->isValid()) { mScheduler->addPresentFence(presentFenceTime); mScheduler->addPresentFence(presentFenceTime); } } const bool isDisplayConnected = display && getHwComposer().isConnected(*display->getId()); if (!hasSyncFramework) { if (!hasSyncFramework) { if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) && if (isDisplayConnected && display->isPoweredOn()) { displayDevice->isPoweredOn()) { mScheduler->enableHardwareVsync(); mScheduler->enableHardwareVsync(); } } } } Loading @@ -2261,11 +2284,10 @@ void SurfaceFlinger::postComposition() if (presentFenceTime->isValid()) { if (presentFenceTime->isValid()) { mAnimFrameTracker.setActualPresentFence( mAnimFrameTracker.setActualPresentFence( std::move(presentFenceTime)); std::move(presentFenceTime)); } else if (displayDevice && getHwComposer().isConnected(*displayDevice->getId())) { } else if (isDisplayConnected) { // The HWC doesn't support present fences, so use the refresh // The HWC doesn't support present fences, so use the refresh // timestamp instead. // timestamp instead. const nsecs_t presentTime = const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId()); getHwComposer().getRefreshTimestamp(*displayDevice->getId()); mAnimFrameTracker.setActualPresentTime(presentTime); mAnimFrameTracker.setActualPresentTime(presentTime); } } mAnimFrameTracker.advanceFrame(); mAnimFrameTracker.advanceFrame(); Loading @@ -2286,8 +2308,7 @@ void SurfaceFlinger::postComposition() const size_t appConnections = mScheduler->getEventThreadConnectionCount(mAppConnectionHandle); const size_t appConnections = mScheduler->getEventThreadConnectionCount(mAppConnectionHandle); mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections); mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections); if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) && if (isDisplayConnected && !display->isPoweredOn()) { !displayDevice->isPoweredOn()) { return; return; } } Loading Loading @@ -2343,7 +2364,7 @@ FloatRect SurfaceFlinger::getLayerClipBoundsForDisplay(const DisplayDevice& disp } } void SurfaceFlinger::computeLayerBounds() { void SurfaceFlinger::computeLayerBounds() { for (const auto& pair : mDisplays) { for (const auto& pair : ON_MAIN_THREAD(mDisplays)) { const auto& displayDevice = pair.second; const auto& displayDevice = pair.second; const auto display = displayDevice->getCompositionDisplay(); const auto display = displayDevice->getCompositionDisplay(); for (const auto& layer : mDrawingState.layersSortedByZ) { for (const auto& layer : mDrawingState.layersSortedByZ) { Loading @@ -2358,10 +2379,8 @@ void SurfaceFlinger::computeLayerBounds() { } } } } void SurfaceFlinger::postFrame() void SurfaceFlinger::postFrame() { { const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); // |mStateLock| not needed as we are on the main thread const auto display = getDefaultDisplayDeviceLocked(); if (display && getHwComposer().isConnected(*display->getId())) { if (display && getHwComposer().isConnected(*display->getId())) { uint32_t flipCount = display->getPageFlipCount(); uint32_t flipCount = display->getPageFlipCount(); if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { if (flipCount % LOG_FRAME_STATS_PERIOD == 0) { Loading Loading @@ -2789,7 +2808,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) sp<const DisplayDevice> hintDisplay; sp<const DisplayDevice> hintDisplay; uint32_t currentlayerStack = 0; uint32_t currentlayerStack = 0; bool first = true; bool first = true; mCurrentState.traverse([&](Layer* layer) { mCurrentState.traverse([&](Layer* layer) REQUIRES(mStateLock) { // NOTE: we rely on the fact that layers are sorted by // NOTE: we rely on the fact that layers are sorted by // layerStack first (so we don't have to traverse the list // layerStack first (so we don't have to traverse the list // of displays for every layer). // of displays for every layer). Loading Loading @@ -2902,10 +2921,9 @@ void SurfaceFlinger::commitInputWindowCommands() { mPendingInputWindowCommands.clear(); mPendingInputWindowCommands.clear(); } } void SurfaceFlinger::updateCursorAsync() void SurfaceFlinger::updateCursorAsync() { { compositionengine::CompositionRefreshArgs refreshArgs; compositionengine::CompositionRefreshArgs refreshArgs; for (const auto& [_, display] : mDisplays) { for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) { if (display->getId()) { if (display->getId()) { refreshArgs.outputs.push_back(display->getCompositionDisplay()); refreshArgs.outputs.push_back(display->getCompositionDisplay()); } } Loading @@ -2915,7 +2933,7 @@ void SurfaceFlinger::updateCursorAsync() } } void SurfaceFlinger::changeRefreshRate(const RefreshRate& refreshRate, void SurfaceFlinger::changeRefreshRate(const RefreshRate& refreshRate, Scheduler::ConfigEvent event) NO_THREAD_SAFETY_ANALYSIS { Scheduler::ConfigEvent event) { // If this is called from the main thread mStateLock must be locked before // If this is called from the main thread mStateLock must be locked before // Currently the only way to call this function from the main thread is from // Currently the only way to call this function from the main thread is from // Sheduler::chooseRefreshRateForContent // Sheduler::chooseRefreshRateForContent Loading Loading @@ -3041,7 +3059,7 @@ void SurfaceFlinger::commitOffscreenLayers() { } } void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) { void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) { for (const auto& [token, displayDevice] : mDisplays) { for (const auto& [token, displayDevice] : ON_MAIN_THREAD(mDisplays)) { auto display = displayDevice->getCompositionDisplay(); auto display = displayDevice->getCompositionDisplay(); if (display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) { if (display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) { display->editState().dirtyRegion.orSelf(dirty); display->editState().dirtyRegion.orSelf(dirty); Loading Loading @@ -4137,7 +4155,7 @@ void SurfaceFlinger::onInitializeDisplays() { void SurfaceFlinger::initializeDisplays() { void SurfaceFlinger::initializeDisplays() { // Async since we may be called from the main thread. // Async since we may be called from the main thread. static_cast<void>(schedule([this]() NO_THREAD_SAFETY_ANALYSIS { onInitializeDisplays(); })); static_cast<void>(schedule([this]() MAIN_THREAD { onInitializeDisplays(); })); } } void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled) { void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled) { Loading Loading @@ -4228,7 +4246,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal: } } void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { schedule([=]() NO_THREAD_SAFETY_ANALYSIS { schedule([=]() MAIN_THREAD { const auto display = getDisplayDeviceLocked(displayToken); const auto display = getDisplayDeviceLocked(displayToken); if (!display) { if (!display) { ALOGE("Attempt to set power mode %d for invalid display token %p", mode, ALOGE("Attempt to set power mode %d for invalid display token %p", mode, Loading @@ -4241,8 +4259,7 @@ void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) { }).wait(); }).wait(); } } status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) { bool asProto) NO_THREAD_SAFETY_ANALYSIS { std::string result; std::string result; IPCThreadState* ipc = IPCThreadState::self(); IPCThreadState* ipc = IPCThreadState::self(); Loading @@ -4254,18 +4271,6 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n", StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n", pid, uid); pid, uid); } else { } else { // Try to get the main lock, but give up after one second // (this would indicate SF is stuck, but we want to be able to // print something in dumpsys). status_t err = mStateLock.timedLock(s2ns(1)); bool locked = (err == NO_ERROR); if (!locked) { StringAppendF(&result, "SurfaceFlinger appears to be unresponsive (%s [%d]), dumping anyways " "(no locks held)\n", strerror(-err), err); } static const std::unordered_map<std::string, Dumper> dumpers = { static const std::unordered_map<std::string, Dumper> dumpers = { {"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)}, {"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)}, {"--dispsync"s, {"--dispsync"s, Loading @@ -4283,18 +4288,23 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, const auto flag = args.empty() ? ""s : std::string(String8(args[0])); const auto flag = args.empty() ? ""s : std::string(String8(args[0])); const auto it = dumpers.find(flag); bool dumpLayers = true; if (it != dumpers.end()) { { TimedLock lock(mStateLock, s2ns(1), __FUNCTION__); if (!lock.locked()) { StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n", strerror(-lock.status), lock.status); } if (const auto it = dumpers.find(flag); it != dumpers.end()) { (it->second)(args, asProto, result); (it->second)(args, asProto, result); dumpLayers = false; } else if (!asProto) { } else if (!asProto) { dumpAllLocked(args, result); dumpAllLocked(args, result); } } if (locked) { mStateLock.unlock(); } } if (it == dumpers.end()) { if (dumpLayers) { const LayersProto layersProto = dumpProtoFromMainThread(); const LayersProto layersProto = dumpProtoFromMainThread(); if (asProto) { if (asProto) { result.append(layersProto.SerializeAsString()); result.append(layersProto.SerializeAsString()); Loading Loading @@ -4568,7 +4578,7 @@ void SurfaceFlinger::dumpWideColorInfo(std::string& result) const { LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const { LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const { // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread. // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread. const auto display = getDefaultDisplayDeviceLocked(); const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); LayersProto layersProto; LayersProto layersProto; for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) { for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) { Loading Loading @@ -5404,7 +5414,7 @@ status_t SurfaceFlinger::setSchedFifo(bool enabled) { return NO_ERROR; return NO_ERROR; } } const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) { sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) { const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack}); const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack}); if (displayToken) { if (displayToken) { return getDisplayDeviceLocked(displayToken); return getDisplayDeviceLocked(displayToken); Loading @@ -5414,7 +5424,7 @@ const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t disp return getDisplayByLayerStack(displayOrLayerStack); return getDisplayByLayerStack(displayOrLayerStack); } } const sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) { sp<DisplayDevice> SurfaceFlinger::getDisplayByLayerStack(uint64_t layerStack) { for (const auto& [token, display] : mDisplays) { for (const auto& [token, display] : mDisplays) { if (display->getLayerStack() == layerStack) { if (display->getLayerStack() == layerStack) { return display; return display; Loading Loading @@ -5989,7 +5999,7 @@ status_t SurfaceFlinger::setDesiredDisplayConfigSpecs(const sp<IBinder>& display } } auto future = schedule([=]() -> status_t { auto future = schedule([=]() -> status_t { const auto display = getDisplayDeviceLocked(displayToken); const auto display = ON_MAIN_THREAD(getDisplayDeviceLocked(displayToken)); if (!display) { if (!display) { ALOGE("Attempt to set desired display configs for invalid display token %p", ALOGE("Attempt to set desired display configs for invalid display token %p", displayToken.get()); displayToken.get()); Loading Loading @@ -6144,7 +6154,7 @@ status_t SurfaceFlinger::setFrameRate(const sp<IGraphicBufferProducer>& surface, return BAD_VALUE; return BAD_VALUE; } } static_cast<void>(schedule([=]() NO_THREAD_SAFETY_ANALYSIS { static_cast<void>(schedule([=] { Mutex::Autolock lock(mStateLock); Mutex::Autolock lock(mStateLock); if (authenticateSurfaceTextureLocked(surface)) { if (authenticateSurfaceTextureLocked(surface)) { sp<Layer> layer = (static_cast<MonitoredProducer*>(surface.get()))->getLayer(); sp<Layer> layer = (static_cast<MonitoredProducer*>(surface.get()))->getLayer(); Loading Loading @@ -6173,8 +6183,7 @@ status_t SurfaceFlinger::acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) sp<IBinder> token; sp<IBinder> token; if (mFrameRateFlexibilityTokenCount == 0) { if (mFrameRateFlexibilityTokenCount == 0) { // |mStateLock| not needed as we are on the main thread const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); const auto display = getDefaultDisplayDeviceLocked(); // This is a little racy, but not in a way that hurts anything. As we grab the // This is a little racy, but not in a way that hurts anything. As we grab the // defaultConfig from the display manager policy, we could be setting a new display // defaultConfig from the display manager policy, we could be setting a new display Loading Loading @@ -6224,8 +6233,7 @@ void SurfaceFlinger::onFrameRateFlexibilityTokenReleased() { mFrameRateFlexibilityTokenCount--; mFrameRateFlexibilityTokenCount--; ALOGD("Frame rate flexibility token released. count=%d", mFrameRateFlexibilityTokenCount); ALOGD("Frame rate flexibility token released. count=%d", mFrameRateFlexibilityTokenCount); if (mFrameRateFlexibilityTokenCount == 0) { if (mFrameRateFlexibilityTokenCount == 0) { // |mStateLock| not needed as we are on the main thread const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked()); const auto display = getDefaultDisplayDeviceLocked(); constexpr bool kOverridePolicy = true; constexpr bool kOverridePolicy = true; status_t result = setDesiredDisplayConfigSpecsInternal(display, {}, kOverridePolicy); status_t result = setDesiredDisplayConfigSpecsInternal(display, {}, kOverridePolicy); LOG_ALWAYS_FATAL_IF(result < 0, "Failed releasing frame rate flexibility token"); LOG_ALWAYS_FATAL_IF(result < 0, "Failed releasing frame rate flexibility token"); Loading
services/surfaceflinger/SurfaceFlinger.h +29 −31 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +2 −2 Original line number Original line Diff line number Diff line Loading @@ -289,14 +289,14 @@ public: return mFlinger->destroyDisplay(displayToken); return mFlinger->destroyDisplay(displayToken); } } auto resetDisplayState() { return mFlinger->resetDisplayState(); } auto resetDisplayState() NO_THREAD_SAFETY_ANALYSIS { return mFlinger->resetDisplayState(); } auto setupNewDisplayDeviceInternal( auto setupNewDisplayDeviceInternal( const wp<IBinder>& displayToken, const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay, std::shared_ptr<compositionengine::Display> compositionDisplay, const DisplayDeviceState& state, const DisplayDeviceState& state, const sp<compositionengine::DisplaySurface>& dispSurface, const sp<compositionengine::DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) { const sp<IGraphicBufferProducer>& producer) NO_THREAD_SAFETY_ANALYSIS { return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, return mFlinger->setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state, dispSurface, producer); dispSurface, producer); } } Loading