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

Commit fd9c44fb authored by Patrick Williams's avatar Patrick Williams
Browse files

DO NOT MERGE Reverts WindowInfosListenerInvoker throttling

Revert "DO NOT MERGE: Force input window updates when layer visibility changes"
Revert "SF: throttle WindowInfosListener calls"

The reverted CLs may be causing input issues where InputDispatcher
doesn't seem to align with the windows currently displayed.

This reverts commit 243e2e9a.
This reverts commit f3213d2c.

Bug: 279649321
Bug: 270894765
Test: presubmits
Change-Id: I8eb46caced6f395460fabc1d6a529a88c1c4566b
parent 3fd3acc9
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -2391,7 +2391,16 @@ WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) {
        info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE;
    }

    info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !isVisibleForInput());
    // For compatibility reasons we let layers which can receive input
    // receive input before they have actually submitted a buffer. Because
    // of this we use canReceiveInput instead of isVisible to check the
    // policy-visibility, ignoring the buffer state. However for layers with
    // hasInputInfo()==false we can use the real visibility state.
    // We are just using these layers for occlusion detection in
    // InputDispatcher, and obviously if they aren't visible they can't occlude
    // anything.
    const bool visible = hasInputInfo() ? canReceiveInput() : isVisible();
    info.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !visible);

    info.alpha = getAlpha();
    fillTouchOcclusionMode(info);
+0 −15
Original line number Diff line number Diff line
@@ -470,21 +470,6 @@ public:
     */
    virtual bool canReceiveInput() const;

    /*
     * Whether or not the layer should be considered visible for input calculations.
     */
    virtual bool isVisibleForInput() const {
        // For compatibility reasons we let layers which can receive input
        // receive input before they have actually submitted a buffer. Because
        // of this we use canReceiveInput instead of isVisible to check the
        // policy-visibility, ignoring the buffer state. However for layers with
        // hasInputInfo()==false we can use the real visibility state.
        // We are just using these layers for occlusion detection in
        // InputDispatcher, and obviously if they aren't visible they can't occlude
        // anything.
        return hasInputInfo() ? canReceiveInput() : isVisible();
    }

    /*
     * isProtected - true if the layer may contain protected contents in the
     * GRALLOC_USAGE_PROTECTED sense.
+3 −21
Original line number Diff line number Diff line
@@ -3249,34 +3249,16 @@ void SurfaceFlinger::updateInputFlinger() {
    if (!updateWindowInfo && mInputWindowCommands.empty()) {
        return;
    }

    std::unordered_set<Layer*> visibleLayers;
    mDrawingState.traverse([&visibleLayers](Layer* layer) {
        if (layer->isVisibleForInput()) {
            visibleLayers.insert(layer);
        }
    });
    bool visibleLayersChanged = false;
    if (visibleLayers != mVisibleLayers) {
        visibleLayersChanged = true;
        mVisibleLayers = std::move(visibleLayers);
    }

    BackgroundExecutor::getInstance().sendCallbacks({[updateWindowInfo,
                                                      windowInfos = std::move(windowInfos),
                                                      displayInfos = std::move(displayInfos),
                                                      inputWindowCommands =
                                                              std::move(mInputWindowCommands),
                                                      inputFlinger = mInputFlinger, this,
                                                      visibleLayersChanged]() {
                                                      inputFlinger = mInputFlinger, this]() {
        ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
        if (updateWindowInfo) {
            mWindowInfosListenerInvoker
                    ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
                                         /* shouldSync= */ inputWindowCommands.syncInputWindows,
                                         /* forceImmediateCall= */
                                         visibleLayersChanged ||
                                                 !inputWindowCommands.focusRequests.empty());
            mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,
                                                            inputWindowCommands.syncInputWindows);
        } else if (inputWindowCommands.syncInputWindows) {
            // If the caller requested to sync input windows, but there are no
            // changes to input windows, notify immediately.
+0 −5
Original line number Diff line number Diff line
@@ -1449,11 +1449,6 @@ private:
    nsecs_t mAnimationTransactionTimeout = s2ns(5);

    friend class SurfaceComposerAIDL;

    // Layers visible during the last commit. This set should only be used for testing set equality
    // and membership. The pointers should not be dereferenced as it's possible the set contains
    // pointers to freed layers.
    std::unordered_set<Layer*> mVisibleLayers;
};

class SurfaceComposerAIDL : public gui::BnSurfaceComposer {
+20 −73
Original line number Diff line number Diff line
@@ -28,26 +28,19 @@ using gui::WindowInfo;

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

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

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

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

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

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 {
void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos,
                                                    const std::vector<DisplayInfo>& displayInfos,
                                                    bool shouldSync) {
    ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
    {
        std::scoped_lock lock(mListenersMutex);
@@ -84,63 +75,19 @@ void WindowInfosListenerInvoker::windowInfosChanged(std::vector<WindowInfo> wind
        }
    }

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

    for (const auto& listener : windowInfosListeners) {
            auto status =
                    listener->onWindowInfosChanged(windowInfos, displayInfos, reportedListener);
            if (!status.isOk()) {
                reportedListener->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);
            mShouldSyncDelayed |= shouldSync;
            return;
        }

        mWindowInfosChangedDelayed = nullptr;
        shouldSync |= mShouldSyncDelayed;
        mShouldSyncDelayed = false;
        mActiveMessageCount++;
        listener->onWindowInfosChanged(windowInfos, displayInfos,
                                       shouldSync ? mWindowInfosReportedListener : nullptr);
    }
    callListeners(shouldSync);
}

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