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

Commit 243e2e9a authored by Patrick Williams's avatar Patrick Williams
Browse files

DO NOT MERGE: Force input window updates when layer visibility changes

This should fix a latency regression introduced by delaying input window
visibility changes. See ag/22210759.

Bug: 270894765
Bug: 275562923
Test: v2/android-crystalball-eng/health/microbench/instr_metric/input_method
Change-Id: I0f64fa148eb4b02600eac9578d3d23ac00c78fa3
parent b218143d
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -2391,16 +2391,7 @@ WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) {
        info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE;
    }

    // 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.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, !isVisibleForInput());

    info.alpha = getAlpha();
    fillTouchOcclusionMode(info);
+15 −0
Original line number Diff line number Diff line
@@ -470,6 +470,21 @@ 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.
+17 −2
Original line number Diff line number Diff line
@@ -3249,18 +3249,33 @@ 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]() {
                                                      inputFlinger = mInputFlinger, this,
                                                      visibleLayersChanged]() {
        ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
        if (updateWindowInfo) {
            mWindowInfosListenerInvoker
                    ->windowInfosChanged(std::move(windowInfos), std::move(displayInfos),
                                         /* shouldSync= */ inputWindowCommands.syncInputWindows,
                                         /* forceImmediateCall= */
                                         visibleLayersChanged ||
                                                 !inputWindowCommands.focusRequests.empty());
        } else if (inputWindowCommands.syncInputWindows) {
            // If the caller requested to sync input windows, but there are no
+5 −0
Original line number Diff line number Diff line
@@ -1449,6 +1449,11 @@ 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 {