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

Commit 720e506f authored by Robert Carr's avatar Robert Carr
Browse files

Forward input windows from SurfaceFlinger to InputDispatcher.

We re-use values from visible region computation to fill in
the frames, ensuring input always reflects the most recent
state of the scene.

Test: Extensive manual testing. Existing tests pass.
Bug: 80101428
Bug: 113136004
Bug: 111440400
Change-Id: I9908a1bd6cba6abf16f2f6a43b6fe63f07a124a6
parent b49bb915
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ cc_defaults {
        "libsync",
        "libtimestats_proto",
        "libui",
        "libinput",
        "libutils",
    ],
    static_libs: [
@@ -183,6 +184,7 @@ cc_defaults {
        "libdisplayservicehidl",
        "libhidlbase",
        "libhidltransport",
        "libinput",
        "liblayers_proto",
        "liblog",
        "libsync",
+30 −0
Original line number Diff line number Diff line
@@ -1057,6 +1057,11 @@ uint32_t Layer::doTransaction(uint32_t flags) {
        clearSyncPoints();
    }

    if (mCurrentState.inputInfoChanged) {
        flags |= eInputInfoChanged;
        mCurrentState.inputInfoChanged = false;
    }

    // Commit the transaction
    commitTransaction(c);
    mCurrentState.callbackHandles = {};
@@ -1928,6 +1933,13 @@ void Layer::commitChildList() {
    mDrawingParent = mCurrentParent;
}

void Layer::setInputInfo(const InputWindowInfo& info) {
    mCurrentState.inputInfo = info;
    mCurrentState.modified = true;
    mCurrentState.inputInfoChanged = true;
    setTransactionFlags(eTransactionNeeded);
}

void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
    const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
    const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
@@ -2055,6 +2067,24 @@ bool Layer::isRemovedFromCurrentState() const {
    return mRemovedFromCurrentState;
}

InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
    InputWindowInfo info = mDrawingState.inputInfo;
    info.frameLeft = screenBounds.left;
    info.inputInfo.frameTop = screenBounds.top;
    info.inputInfo.frameRight = screenBounds.right;
    info.inputInfo.frameBottom = screenBounds.bottom;

    info.touchableRegion = mDrawingState.inputInfo.touchableRegion.translate(
            screenBounds.left,
            screenBounds.top);
    info.visible = isVisible();
    return info;
}

bool Layer::hasInput() const {
    return mDrawingState.inputInfo.inputChannel != nullptr;
}

// ---------------------------------------------------------------------------

}; // namespace android
+9 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <gui/BufferQueue.h>
#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
#include <input/InputWindow.h>
#include <layerproto/LayerProtoHeader.h>
#include <math/vec4.h>
#include <renderengine/Mesh.h>
@@ -109,6 +110,7 @@ public:
    enum { // flags for doTransaction()
        eDontUpdateGeometryState = 0x00000001,
        eVisibleRegion = 0x00000002,
        eInputInfoChanged = 0x00000004
    };

    struct Geometry {
@@ -166,6 +168,9 @@ public:

        half4 color;

        bool inputInfoChanged;
        InputWindowInfo inputInfo;

        // The fields below this point are only used by BufferStateLayer
        Geometry active;

@@ -708,6 +713,10 @@ public:
    bool getPremultipledAlpha() const;

    bool mPendingHWCDestroy{false};
    void setInputInfo(const InputWindowInfo& info);

    InputWindowInfo fillInputInfo(const Rect& screenBounds);
    bool hasInput() const;

protected:
    // -----------------------------------------------------------------------
+36 −1
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@

#include <dvr/vr_flinger.h>

#include <input/IInputFlinger.h>

#include <ui/ColorSpace.h>
#include <ui/DebugUtils.h>
#include <ui/DisplayInfo.h>
@@ -554,6 +556,13 @@ void SurfaceFlinger::bootFinished()
    if (window != 0) {
        window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
    }
    sp<IBinder> input(defaultServiceManager()->getService(
            String16("inputflinger")));
    if (input == nullptr) {
        ALOGE("Failed to link to input service");
    } else {
        mInputFlinger = interface_cast<IInputFlinger>(input);
    }

    if (mVrFlinger) {
      mVrFlinger->OnBootFinished();
@@ -2569,6 +2578,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
     * (perform the transaction for each of them if needed)
     */

    bool inputChanged = false;
    if (transactionFlags & eTraversalNeeded) {
        mCurrentState.traverseInZOrder([&](Layer* layer) {
            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
@@ -2577,6 +2587,10 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
            const uint32_t flags = layer->doTransaction(0);
            if (flags & Layer::eVisibleRegion)
                mVisibleRegionsDirty = true;

            if (flags & Layer::eInputInfoChanged) {
                inputChanged = true;
            }
        });
    }

@@ -2686,9 +2700,26 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)

    commitTransaction();

    if ((inputChanged || mVisibleRegionsDirty) && mInputFlinger) {
        updateInputWindows();
    }

    updateCursorAsync();
}

void SurfaceFlinger::updateInputWindows() {
    ATRACE_CALL();

    Vector<InputWindowInfo> inputHandles;

    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
        if (layer->hasInput()) {
            inputHandles.add(layer->fillInputInfo(layer->computeScreenBounds()));
        }
    });
    mInputFlinger->setInputWindows(inputHandles);
}

void SurfaceFlinger::updateCursorAsync()
{
    for (const auto& [token, display] : mDisplays) {
@@ -2796,6 +2827,7 @@ void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displa
        if (CC_LIKELY(layer->isVisible())) {
            const bool translucent = !layer->isOpaque(s);
            Rect bounds(layer->computeScreenBounds());

            visibleRegion.set(bounds);
            ui::Transform tr = layer->getTransform();
            if (!visibleRegion.isEmpty()) {
@@ -3611,7 +3643,10 @@ uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState
    if (what & layer_state_t::eSidebandStreamChanged) {
        if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded;
    }

    if (what & layer_state_t::eInputInfoChanged) {
        layer->setInputInfo(s.inputInfo);
        flags |= eTraversalNeeded;
    }
    std::vector<sp<CallbackHandle>> callbackHandles;
    if ((what & layer_state_t::eListenerCallbacksChanged) && (!s.listenerCallbacks.empty())) {
        mTransactionCompletedThread.run();
+4 −0
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ class EventControlThread;
class EventThread;
class IGraphicBufferConsumer;
class IGraphicBufferProducer;
class IInputFlinger;
class InjectVSyncSource;
class Layer;
class Surface;
@@ -531,6 +532,7 @@ private:
    void handleTransaction(uint32_t transactionFlags);
    void handleTransactionLocked(uint32_t transactionFlags);

    void updateInputWindows();
    void updateCursorAsync();

    /* handlePageFlip - latch a new buffer if available and compute the dirty
@@ -986,6 +988,8 @@ private:
    std::unique_ptr<Scheduler> mScheduler;
    sp<Scheduler::ConnectionHandle> mAppConnectionHandle;
    sp<Scheduler::ConnectionHandle> mSfConnectionHandle;

    sp<IInputFlinger> mInputFlinger;
};
}; // namespace android