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 Original line Diff line number Diff line
@@ -2529,7 +2529,7 @@ bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expe
    }
    }


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


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


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


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


    result.append("Window Infos:\n");
    result.append("Window Infos:\n");
    StringAppendF(&result, "  input flinger update vsync id: %" PRId64 "\n",
    auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo();
                  ftl::to_underlying(mLastInputFlingerUpdateVsyncId));
    StringAppendF(&result, "  max send vsync id: %" PRId64 "\n",
    StringAppendF(&result, "  input flinger update timestamp (ns): %" PRId64 "\n",
                  ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId));
                  mLastInputFlingerUpdateTimestamp);
    StringAppendF(&result, "  max send delay (ns): %" PRId64 " ns\n",
                  windowInfosDebug.maxSendDelayDuration);
    StringAppendF(&result, "  unsent messages: %" PRIu32 "\n",
                  windowInfosDebug.pendingMessageCount);
    result.append("\n");
    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) {
mat4 SurfaceFlinger::calculateColorMatrix(float saturation) {
+1 −4
Original line number Original line Diff line number Diff line
@@ -718,7 +718,7 @@ private:
    void updateLayerHistory(const frontend::LayerSnapshot& snapshot);
    void updateLayerHistory(const frontend::LayerSnapshot& snapshot);
    frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext);
    frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext);


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


    VsyncId mLastCommittedVsyncId;
    VsyncId mLastCommittedVsyncId;


    VsyncId mLastInputFlingerUpdateVsyncId;
    nsecs_t mLastInputFlingerUpdateTimestamp;

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


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


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


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


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


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


void WindowInfosListenerInvoker::windowInfosChanged(
void WindowInfosListenerInvoker::windowInfosChanged(
        std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos,
        gui::WindowInfosUpdate update, WindowInfosReportedListenerSet reportedListeners,
        WindowInfosReportedListenerSet reportedListeners, bool forceImmediateCall, VsyncId vsyncId,
        bool forceImmediateCall) {
        nsecs_t timestamp) {
    WindowInfosListenerVector listeners;
    reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this));
    auto callListeners = [this, windowInfos = std::move(windowInfos),
                          displayInfos = std::move(displayInfos), vsyncId,
                          timestamp](WindowInfosReportedListenerSet reportedListeners) mutable {
        WindowInfosListenerVector windowInfosListeners;
    {
    {
            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) {
            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 =
        reportedListeners.insert(sp<WindowInfosListenerInvoker>::fromExisting(this));
                sp<WindowInfosReportedListenerInvoker>::make(windowInfosListeners,
        reportedListeners.merge(mReportedListeners);
                                                             std::move(reportedListeners));
        mReportedListeners.clear();


        gui::WindowInfosUpdate update(std::move(windowInfos), std::move(displayInfos),
        mActiveMessageCount++;
                                      ftl::to_underlying(vsyncId), timestamp);
        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);
        sp<IBinder> asBinder = IInterface::asBinder(listener);


        // linkToDeath is used here to ensure that the windowInfosReportedListeners
        // linkToDeath is used here to ensure that the windowInfosReportedListeners
@@ -121,55 +155,41 @@ void WindowInfosListenerInvoker::windowInfosChanged(
            reportedInvoker->onWindowInfosReported();
            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() {
binder::Status WindowInfosListenerInvoker::onWindowInfosReported() {
    std::function<void(WindowInfosReportedListenerSet)> callListeners;
    BackgroundExecutor::getInstance().sendCallbacks({[this]() {
    WindowInfosReportedListenerSet reportedListeners;
        gui::WindowInfosUpdate update;

        {
        {
            std::scoped_lock lock{mMessagesMutex};
            std::scoped_lock lock{mMessagesMutex};
            mActiveMessageCount--;
            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();
    return binder::Status::ok();
}
}


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


    callListeners(std::move(reportedListeners));
void WindowInfosListenerInvoker::updateMaxSendDelay() {
    return binder::Status::ok();
    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
} // namespace android
+19 −21
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#pragma once
#pragma once


#include <optional>
#include <unordered_set>
#include <unordered_set>


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


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


    binder::Status onWindowInfosReported() override;
    binder::Status onWindowInfosReported() override;


    VsyncId getUnsentMessageVsyncId() {
    struct DebugInfo {
        std::scoped_lock lock(mMessagesMutex);
        VsyncId maxSendDelayVsyncId;
        return mUnsentVsyncId;
        nsecs_t maxSendDelayDuration;
    }
        uint32_t pendingMessageCount;

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

    uint32_t getPendingMessageCount() {
        std::scoped_lock lock(mMessagesMutex);
        return mActiveMessageCount;
    }


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


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

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


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


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


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