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

Commit b218143d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: throttle WindowInfosListener calls" into tm-qpr-dev

parents 18fa257e f3213d2c
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -3257,8 +3257,11 @@ void SurfaceFlinger::updateInputFlinger() {
                                                      inputFlinger = mInputFlinger, this]() {
        ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
        if (updateWindowInfo) {
            mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,
                                                            inputWindowCommands.syncInputWindows);
            mWindowInfosListenerInvoker
                    ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
                                         /* shouldSync= */ inputWindowCommands.syncInputWindows,
                                         /* forceImmediateCall= */
                                         !inputWindowCommands.focusRequests.empty());
        } else if (inputWindowCommands.syncInputWindows) {
            // If the caller requested to sync input windows, but there are no
            // changes to input windows, notify immediately.
+73 −20
Original line number Diff line number Diff line
@@ -28,19 +28,26 @@ using gui::WindowInfo;

struct WindowInfosListenerInvoker::WindowInfosReportedListener
      : gui::BnWindowInfosReportedListener {
    explicit WindowInfosReportedListener(WindowInfosListenerInvoker& invoker) : mInvoker(invoker) {}
    explicit WindowInfosReportedListener(WindowInfosListenerInvoker& invoker, size_t callbackCount,
                                         bool shouldSync)
          : mInvoker(invoker), mCallbacksPending(callbackCount), mShouldSync(shouldSync) {}

    binder::Status onWindowInfosReported() override {
        mInvoker.windowInfosReported();
        mCallbacksPending--;
        if (mCallbacksPending == 0) {
            mInvoker.windowInfosReported(mShouldSync);
        }
        return binder::Status::ok();
    }

private:
    WindowInfosListenerInvoker& mInvoker;
    std::atomic<size_t> mCallbacksPending;
    bool mShouldSync;
};

WindowInfosListenerInvoker::WindowInfosListenerInvoker(SurfaceFlinger& flinger)
      : mFlinger(flinger),
        mWindowInfosReportedListener(sp<WindowInfosReportedListener>::make(*this)) {}
      : mFlinger(flinger) {}

void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) {
    sp<IBinder> asBinder = IInterface::asBinder(listener);
@@ -64,9 +71,11 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
    mWindowInfosListeners.erase(who);
}

void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos,
                                                    const std::vector<DisplayInfo>& displayInfos,
                                                    bool shouldSync) {
void WindowInfosListenerInvoker::windowInfosChanged(std::vector<WindowInfo> windowInfos,
                                                    std::vector<DisplayInfo> displayInfos,
                                                    bool shouldSync, bool forceImmediateCall) {
    auto callListeners = [this, windowInfos = std::move(windowInfos),
                          displayInfos = std::move(displayInfos)](bool shouldSync) mutable {
        ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
        {
            std::scoped_lock lock(mListenersMutex);
@@ -75,19 +84,63 @@ void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo
            }
        }

    mCallbacksPending = windowInfosListeners.size();
        auto reportedListener =
                sp<WindowInfosReportedListener>::make(*this, windowInfosListeners.size(),
                                                      shouldSync);

        for (const auto& listener : windowInfosListeners) {
        listener->onWindowInfosChanged(windowInfos, displayInfos,
                                       shouldSync ? mWindowInfosReportedListener : nullptr);
            auto status =
                    listener->onWindowInfosChanged(windowInfos, displayInfos, reportedListener);
            if (!status.isOk()) {
                reportedListener->onWindowInfosReported();
            }
        }
    };

void WindowInfosListenerInvoker::windowInfosReported() {
    mCallbacksPending--;
    if (mCallbacksPending == 0) {
    {
        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);
            mShouldSyncDelayed |= shouldSync;
            return;
        }

        mWindowInfosChangedDelayed = nullptr;
        shouldSync |= mShouldSyncDelayed;
        mShouldSyncDelayed = false;
        mActiveMessageCount++;
    }
    callListeners(shouldSync);
}

void WindowInfosListenerInvoker::windowInfosReported(bool shouldSync) {
    if (shouldSync) {
        mFlinger.windowInfosReported();
    }

    std::function<void(bool)> callListeners;
    bool shouldSyncDelayed;
    {
        std::scoped_lock lock{mMessagesMutex};
        mActiveMessageCount--;
        if (!mWindowInfosChangedDelayed || mActiveMessageCount > 0) {
            return;
        }

        mActiveMessageCount++;
        callListeners = std::move(mWindowInfosChangedDelayed);
        mWindowInfosChangedDelayed = nullptr;
        shouldSyncDelayed = mShouldSyncDelayed;
        mShouldSyncDelayed = false;
    }

    callListeners(shouldSyncDelayed);
}

} // namespace android
+7 −5
Original line number Diff line number Diff line
@@ -34,15 +34,15 @@ public:
    void addWindowInfosListener(sp<gui::IWindowInfosListener>);
    void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);

    void windowInfosChanged(const std::vector<gui::WindowInfo>&,
                            const std::vector<gui::DisplayInfo>&, bool shouldSync);
    void windowInfosChanged(std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>,
                            bool shouldSync, bool forceImmediateCall);

protected:
    void binderDied(const wp<IBinder>& who) override;

private:
    struct WindowInfosReportedListener;
    void windowInfosReported();
    void windowInfosReported(bool shouldSync);

    SurfaceFlinger& mFlinger;
    std::mutex mListenersMutex;
@@ -51,8 +51,10 @@ private:
    ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity>
            mWindowInfosListeners GUARDED_BY(mListenersMutex);

    sp<gui::IWindowInfosReportedListener> mWindowInfosReportedListener;
    std::atomic<size_t> mCallbacksPending{0};
    std::mutex mMessagesMutex;
    uint32_t mActiveMessageCount GUARDED_BY(mMessagesMutex) = 0;
    std::function<void(bool)> mWindowInfosChangedDelayed GUARDED_BY(mMessagesMutex);
    bool mShouldSyncDelayed;
};

} // namespace android