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

Commit 62af9551 authored by Jesse Hall's avatar Jesse Hall Committed by Gerrit Code Review
Browse files

Process all display events in order

Display events in each batch received from IPC were being processed in
reverse order, and stopped after the first vsync event (latest
chronologically) was handled. This makes perfect sense for vsync
events, but is broken for hotplug events.

Now we process them all in order, handling all except vsync as we see
them. For vsync events, only the last is reported.

Bug: 7491120
Change-Id: I448d139d21dc27128d75ca1d661de666fff51bcb
parent 190fd9ae
Loading
Loading
Loading
Loading
+23 −19
Original line number Original line Diff line number Diff line
@@ -62,7 +62,7 @@ private:
    bool mWaitingForVsync;
    bool mWaitingForVsync;


    virtual int handleEvent(int receiveFd, int events, void* data);
    virtual int handleEvent(int receiveFd, int events, void* data);
    bool readLastVsyncMessage(nsecs_t* outTimestamp, int32_t* id, uint32_t* outCount);
    bool processPendingEvents(nsecs_t* outTimestamp, int32_t* id, uint32_t* outCount);
    void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
    void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
    void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
    void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
};
};
@@ -111,7 +111,7 @@ status_t NativeDisplayEventReceiver::scheduleVsync() {
        nsecs_t vsyncTimestamp;
        nsecs_t vsyncTimestamp;
        int32_t vsyncDisplayId;
        int32_t vsyncDisplayId;
        uint32_t vsyncCount;
        uint32_t vsyncCount;
        readLastVsyncMessage(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount);
        processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount);


        status_t status = mReceiver.requestNextVsync();
        status_t status = mReceiver.requestNextVsync();
        if (status) {
        if (status) {
@@ -141,43 +141,47 @@ int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* dat
    nsecs_t vsyncTimestamp;
    nsecs_t vsyncTimestamp;
    int32_t vsyncDisplayId;
    int32_t vsyncDisplayId;
    uint32_t vsyncCount;
    uint32_t vsyncCount;
    if (!readLastVsyncMessage(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
        ALOGV("receiver %p ~ Woke up but there was no vsync pulse!", this);
        return 1; // keep the callback, did not obtain a vsync pulse
    }

        ALOGV("receiver %p ~ Vsync pulse: timestamp=%lld, id=%d, count=%d",
        ALOGV("receiver %p ~ Vsync pulse: timestamp=%lld, id=%d, count=%d",
                this, vsyncTimestamp, vsyncDisplayId, vsyncCount);
                this, vsyncTimestamp, vsyncDisplayId, vsyncCount);
        mWaitingForVsync = false;
        mWaitingForVsync = false;

        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
    }

    return 1; // keep the callback
    return 1; // keep the callback
}
}


bool NativeDisplayEventReceiver::readLastVsyncMessage(
bool NativeDisplayEventReceiver::processPendingEvents(
        nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) {
        nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) {
    bool gotVsync = false;
    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
    ssize_t n;
    ssize_t n;
    while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
    while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
        ALOGV("receiver %p ~ Read %d events.", this, int(n));
        ALOGV("receiver %p ~ Read %d events.", this, int(n));
        while (n-- > 0) {
        for (ssize_t i = 0; i < n; i++) {
            const DisplayEventReceiver::Event& ev = buf[n];
            const DisplayEventReceiver::Event& ev = buf[i];
            if (ev.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
            switch (ev.header.type) {
            case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                // Later vsync events will just overwrite the info from earlier
                // ones. That's fine, we only care about the most recent.
                gotVsync = true;
                *outTimestamp = ev.header.timestamp;
                *outTimestamp = ev.header.timestamp;
                *outId = ev.header.id;
                *outId = ev.header.id;
                *outCount = ev.vsync.count;
                *outCount = ev.vsync.count;
                return true; // stop at last vsync in the buffer
                break;
            }
            case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:

            if (ev.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG) {
                dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected);
                dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected);
                break;
            default:
                ALOGW("receiver %p ~ ignoring unknown event type %#x", this, ev.header.type);
                break;
            }
            }
        }
        }
    }
    }
    if (n < 0) {
    if (n < 0) {
        ALOGW("Failed to get events from display event receiver, status=%d", status_t(n));
        ALOGW("Failed to get events from display event receiver, status=%d", status_t(n));
    }
    }
    return false;
    return gotVsync;
}
}


void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {