Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0104594 authored by Patrick Williams's avatar Patrick Williams Committed by Android (Google) Code Review
Browse files

Merge "Skip window infos updates if no listeners"

parents a6d68027 6681c023
Loading
Loading
Loading
Loading
+15 −29
Original line number Diff line number Diff line
@@ -2529,7 +2529,7 @@ bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expe
    }

    updateCursorAsync();
    updateInputFlinger(vsyncId);
    updateInputFlinger(vsyncId, frameTime);

    if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
        // This will block and tracing should only be enabled for debugging.
@@ -3723,7 +3723,7 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
    doCommitTransactions();
}

void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) {
void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) {
    if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) {
        return;
    }
@@ -3735,8 +3735,6 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) {
    if (mUpdateInputInfo) {
        mUpdateInputInfo = false;
        updateWindowInfo = true;
        mLastInputFlingerUpdateVsyncId = vsyncId;
        mLastInputFlingerUpdateTimestamp = systemTime();
        buildWindowInfos(windowInfos, displayInfos);
    }

@@ -3758,17 +3756,18 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId) {
                                                      inputWindowCommands =
                                                              std::move(mInputWindowCommands),
                                                      inputFlinger = mInputFlinger, this,
                                                      visibleWindowsChanged]() {
                                                      visibleWindowsChanged, vsyncId, frameTime]() {
        ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
        if (updateWindowInfo) {
            mWindowInfosListenerInvoker
                    ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
                    ->windowInfosChanged(gui::WindowInfosUpdate{std::move(windowInfos),
                                                                std::move(displayInfos),
                                                                ftl::to_underlying(vsyncId),
                                                                frameTime.ns()},
                                         std::move(
                                                 inputWindowCommands.windowInfosReportedListeners),
                                         /* forceImmediateCall= */ visibleWindowsChanged ||
                                                 !inputWindowCommands.focusRequests.empty(),
                                         mLastInputFlingerUpdateVsyncId,
                                         mLastInputFlingerUpdateTimestamp);
                                                 !inputWindowCommands.focusRequests.empty());
        } else {
            // If there are listeners but no changes to input windows, call the listeners
            // immediately.
@@ -6143,27 +6142,14 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, const std::string& comp
    result.append("\n");

    result.append("Window Infos:\n");
    StringAppendF(&result, "  input flinger update vsync id: %" PRId64 "\n",
                  ftl::to_underlying(mLastInputFlingerUpdateVsyncId));
    StringAppendF(&result, "  input flinger update timestamp (ns): %" PRId64 "\n",
                  mLastInputFlingerUpdateTimestamp);
    auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo();
    StringAppendF(&result, "  max send vsync id: %" PRId64 "\n",
                  ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId));
    StringAppendF(&result, "  max send delay (ns): %" PRId64 " ns\n",
                  windowInfosDebug.maxSendDelayDuration);
    StringAppendF(&result, "  unsent messages: %" PRIu32 "\n",
                  windowInfosDebug.pendingMessageCount);
    result.append("\n");

    if (VsyncId unsentVsyncId = mWindowInfosListenerInvoker->getUnsentMessageVsyncId();
        unsentVsyncId != VsyncId()) {
        StringAppendF(&result, "  unsent input flinger update vsync id: %" PRId64 "\n",
                      ftl::to_underlying(unsentVsyncId));
        StringAppendF(&result, "  unsent input flinger update timestamp (ns): %" PRId64 "\n",
                      mWindowInfosListenerInvoker->getUnsentMessageTimestamp());
        result.append("\n");
    }

    if (uint32_t pendingMessages = mWindowInfosListenerInvoker->getPendingMessageCount();
        pendingMessages != 0) {
        StringAppendF(&result, "  pending input flinger calls: %" PRIu32 "\n",
                      mWindowInfosListenerInvoker->getPendingMessageCount());
        result.append("\n");
    }
}

mat4 SurfaceFlinger::calculateColorMatrix(float saturation) {
+1 −4
Original line number Diff line number Diff line
@@ -718,7 +718,7 @@ private:
    void updateLayerHistory(const frontend::LayerSnapshot& snapshot);
    frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext);

    void updateInputFlinger(VsyncId);
    void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime);
    void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext);
    void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos,
                          std::vector<gui::DisplayInfo>& outDisplayInfos);
@@ -1250,9 +1250,6 @@ private:

    VsyncId mLastCommittedVsyncId;

    VsyncId mLastInputFlingerUpdateVsyncId;
    nsecs_t mLastInputFlingerUpdateTimestamp;

    // If blurs should be enabled on this device.
    bool mSupportsBlur = false;
    std::atomic<uint32_t> mFrameMissedCount = 0;
+84 −64
Original line number Diff line number Diff line
@@ -16,8 +16,11 @@

#include <ftl/small_vector.h>
#include <gui/ISurfaceComposer.h>
#include <gui/TraceUtils.h>
#include <gui/WindowInfosUpdate.h>
#include <scheduler/Time.h>

#include "BackgroundExecutor.h"
#include "WindowInfosListenerInvoker.h"

namespace android {
@@ -26,7 +29,7 @@ using gui::DisplayInfo;
using gui::IWindowInfosListener;
using gui::WindowInfo;

using WindowInfosListenerVector = ftl::SmallVector<const sp<IWindowInfosListener>, 3>;
using WindowInfosListenerVector = ftl::SmallVector<const sp<gui::IWindowInfosListener>, 3>;

struct WindowInfosReportedListenerInvoker : gui::BnWindowInfosReportedListener,
                                            IBinder::DeathRecipient {
@@ -86,29 +89,60 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
}

void WindowInfosListenerInvoker::windowInfosChanged(
        std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos,
        WindowInfosReportedListenerSet reportedListeners, bool forceImmediateCall, VsyncId vsyncId,
        nsecs_t timestamp) {
    reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this));
    auto callListeners = [this, windowInfos = std::move(windowInfos),
                          displayInfos = std::move(displayInfos), vsyncId,
                          timestamp](WindowInfosReportedListenerSet reportedListeners) mutable {
        WindowInfosListenerVector windowInfosListeners;
        gui::WindowInfosUpdate update, WindowInfosReportedListenerSet reportedListeners,
        bool forceImmediateCall) {
    WindowInfosListenerVector listeners;
    {
            std::scoped_lock lock(mListenersMutex);
        std::scoped_lock lock{mMessagesMutex};

        if (!mDelayInfo) {
            mDelayInfo = DelayInfo{
                    .vsyncId = update.vsyncId,
                    .frameTime = update.timestamp,
            };
        }

        // If there are unacked messages and this isn't a forced call, then return immediately.
        // If a forced window infos change doesn't happen first, the update will be sent after
        // the WindowInfosReportedListeners are called. If a forced window infos change happens or
        // if there are subsequent delayed messages before this update is sent, then this message
        // will be dropped and the listeners will only be called with the latest info. This is done
        // to reduce the amount of binder memory used.
        if (mActiveMessageCount > 0 && !forceImmediateCall) {
            mDelayedUpdate = std::move(update);
            mReportedListeners.merge(reportedListeners);
            return;
        }

        if (mDelayedUpdate) {
            mDelayedUpdate.reset();
        }

        {
            std::scoped_lock lock{mListenersMutex};
            for (const auto& [_, listener] : mWindowInfosListeners) {
                windowInfosListeners.push_back(listener);
                listeners.push_back(listener);
            }
        }
        if (CC_UNLIKELY(listeners.empty())) {
            mReportedListeners.merge(reportedListeners);
            mDelayInfo.reset();
            return;
        }

        auto reportedInvoker =
                sp<WindowInfosReportedListenerInvoker>::make(windowInfosListeners,
                                                             std::move(reportedListeners));
        reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this));
        reportedListeners.merge(mReportedListeners);
        mReportedListeners.clear();

        gui::WindowInfosUpdate update(std::move(windowInfos), std::move(displayInfos),
                                      ftl::to_underlying(vsyncId), timestamp);
        mActiveMessageCount++;
        updateMaxSendDelay();
        mDelayInfo.reset();
    }

        for (const auto& listener : windowInfosListeners) {
    auto reportedInvoker =
            sp<WindowInfosReportedListenerInvoker>::make(listeners, std::move(reportedListeners));

    for (const auto& listener : listeners) {
        sp<IBinder> asBinder = IInterface::asBinder(listener);

        // linkToDeath is used here to ensure that the windowInfosReportedListeners
@@ -121,55 +155,41 @@ void WindowInfosListenerInvoker::windowInfosChanged(
            reportedInvoker->onWindowInfosReported();
        }
    }
    };

    {
        std::scoped_lock lock(mMessagesMutex);
        // If there are unacked messages and this isn't a forced call, then return immediately.
        // If a forced window infos change doesn't happen first, the update will be sent after
        // the WindowInfosReportedListeners are called. If a forced window infos change happens or
        // if there are subsequent delayed messages before this update is sent, then this message
        // will be dropped and the listeners will only be called with the latest info. This is done
        // to reduce the amount of binder memory used.
        if (mActiveMessageCount > 0 && !forceImmediateCall) {
            mWindowInfosChangedDelayed = std::move(callListeners);
            mUnsentVsyncId = vsyncId;
            mUnsentTimestamp = timestamp;
            mReportedListenersDelayed.merge(reportedListeners);
            return;
        }

        mWindowInfosChangedDelayed = nullptr;
        mUnsentVsyncId = VsyncId();
        mUnsentTimestamp = -1;
        reportedListeners.merge(mReportedListenersDelayed);
        mActiveMessageCount++;
    }
    callListeners(std::move(reportedListeners));
}

binder::Status WindowInfosListenerInvoker::onWindowInfosReported() {
    std::function<void(WindowInfosReportedListenerSet)> callListeners;
    WindowInfosReportedListenerSet reportedListeners;

    BackgroundExecutor::getInstance().sendCallbacks({[this]() {
        gui::WindowInfosUpdate update;
        {
            std::scoped_lock lock{mMessagesMutex};
            mActiveMessageCount--;
        if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) {
            if (!mDelayedUpdate || mActiveMessageCount > 0) {
                return;
            }
            update = std::move(*mDelayedUpdate);
            mDelayedUpdate.reset();
        }
        windowInfosChanged(std::move(update), {}, false);
    }});
    return binder::Status::ok();
}

        mActiveMessageCount++;
        callListeners = std::move(mWindowInfosChangedDelayed);
        mWindowInfosChangedDelayed = nullptr;
        mUnsentVsyncId = VsyncId();
        mUnsentTimestamp = -1;
        reportedListeners = std::move(mReportedListenersDelayed);
        mReportedListenersDelayed.clear();
WindowInfosListenerInvoker::DebugInfo WindowInfosListenerInvoker::getDebugInfo() {
    std::scoped_lock lock{mMessagesMutex};
    updateMaxSendDelay();
    mDebugInfo.pendingMessageCount = mActiveMessageCount;
    return mDebugInfo;
}

    callListeners(std::move(reportedListeners));
    return binder::Status::ok();
void WindowInfosListenerInvoker::updateMaxSendDelay() {
    if (!mDelayInfo) {
        return;
    }
    nsecs_t delay = TimePoint::now().ns() - mDelayInfo->frameTime;
    if (delay > mDebugInfo.maxSendDelayDuration) {
        mDebugInfo.maxSendDelayDuration = delay;
        mDebugInfo.maxSendDelayVsyncId = VsyncId{mDelayInfo->vsyncId};
    }
}

} // namespace android
+19 −21
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#pragma once

#include <optional>
#include <unordered_set>

#include <android/gui/BnWindowInfosReportedListener.h>
@@ -40,26 +41,18 @@ public:
    void addWindowInfosListener(sp<gui::IWindowInfosListener>);
    void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);

    void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>,
    void windowInfosChanged(gui::WindowInfosUpdate update,
                            WindowInfosReportedListenerSet windowInfosReportedListeners,
                            bool forceImmediateCall, VsyncId vsyncId, nsecs_t timestamp);
                            bool forceImmediateCall);

    binder::Status onWindowInfosReported() override;

    VsyncId getUnsentMessageVsyncId() {
        std::scoped_lock lock(mMessagesMutex);
        return mUnsentVsyncId;
    }

    nsecs_t getUnsentMessageTimestamp() {
        std::scoped_lock lock(mMessagesMutex);
        return mUnsentTimestamp;
    }

    uint32_t getPendingMessageCount() {
        std::scoped_lock lock(mMessagesMutex);
        return mActiveMessageCount;
    }
    struct DebugInfo {
        VsyncId maxSendDelayVsyncId;
        nsecs_t maxSendDelayDuration;
        uint32_t pendingMessageCount;
    };
    DebugInfo getDebugInfo();

protected:
    void binderDied(const wp<IBinder>& who) override;
@@ -73,11 +66,16 @@ private:

    std::mutex mMessagesMutex;
    uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0;
    std::function<void(WindowInfosReportedListenerSet)> mWindowInfosChangedDelayed
            GUARDED_BY(mMessagesMutex);
    VsyncId mUnsentVsyncId GUARDED_BY(mMessagesMutex);
    nsecs_t mUnsentTimestamp GUARDED_BY(mMessagesMutex) = -1;
    WindowInfosReportedListenerSet mReportedListenersDelayed;
    std::optional<gui::WindowInfosUpdate> mDelayedUpdate GUARDED_BY(mMessagesMutex);
    WindowInfosReportedListenerSet mReportedListeners;

    DebugInfo mDebugInfo GUARDED_BY(mMessagesMutex);
    struct DelayInfo {
        int64_t vsyncId;
        nsecs_t frameTime;
    };
    std::optional<DelayInfo> mDelayInfo GUARDED_BY(mMessagesMutex);
    void updateMaxSendDelay() REQUIRES(mMessagesMutex);
};

} // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -590,7 +590,7 @@ public:
        mFlinger->binderDied(display);
        mFlinger->onFirstRef();

        mFlinger->updateInputFlinger(VsyncId{0});
        mFlinger->updateInputFlinger(VsyncId{}, TimePoint{});
        mFlinger->updateCursorAsync();

        mutableScheduler().setVsyncConfig({.sfOffset = mFdp.ConsumeIntegral<nsecs_t>(),
Loading