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

Commit 4759f605 authored by Manasi Navare's avatar Manasi Navare
Browse files

SF: Fix dispatch of DISPLAY_EVENT_MODE_REJECTION



The onModeRejected() callback was not getting dispatched
correctly from SF to DM because of the missing case for this display
event in EventThread.cpp, so add that.
While at it, make the Display Event Types enum an enum class
so that the compiler will complain for any missing cases.
Do the necessary refactor in other files for this.

Bug: 393133868
Test: m surfaceflinger, End to End testing forcing Display config
failure in DRM HWC and checking that the correct failure and
is propagated from DRM HWC to SF and received in DM
Flag: com.android.graphics.surfaceflinger.flags.display_config_error_hal

Change-Id: I63914a3555466bc6c382ab1bf9ed57eb5eef7cd0
Signed-off-by: default avatarManasi Navare <navaremanasi@google.com>
parent 6cd42cbd
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -238,7 +238,7 @@ void Choreographer::scheduleLatestConfigRequest() {
        // socket should be atomic across processes.
        // socket should be atomic across processes.
        DisplayEventReceiver::Event event;
        DisplayEventReceiver::Event event;
        event.header =
        event.header =
                DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
                DisplayEventReceiver::Event::Header{DisplayEventType::DISPLAY_EVENT_NULL,
                                                    PhysicalDisplayId::fromPort(0), systemTime()};
                                                    PhysicalDisplayId::fromPort(0), systemTime()};
        injectEvent(event);
        injectEvent(event);
    }
    }
+8 −11
Original line number Original line Diff line number Diff line
@@ -167,7 +167,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
        for (ssize_t i = 0; i < n; i++) {
        for (ssize_t i = 0; i < n; i++) {
            const DisplayEventReceiver::Event& ev = buf[i];
            const DisplayEventReceiver::Event& ev = buf[i];
            switch (ev.header.type) {
            switch (ev.header.type) {
                case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                case DisplayEventType::DISPLAY_EVENT_VSYNC:
                    // Later vsync events will just overwrite the info from earlier
                    // Later vsync events will just overwrite the info from earlier
                    // ones. That's fine, we only care about the most recent.
                    // ones. That's fine, we only care about the most recent.
                    gotVsync = true;
                    gotVsync = true;
@@ -183,7 +183,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                        ATRACE_INT("RenderRate", fps);
                        ATRACE_INT("RenderRate", fps);
                    }
                    }
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                case DisplayEventType::DISPLAY_EVENT_HOTPLUG:
                    if (ev.hotplug.connectionError == 0) {
                    if (ev.hotplug.connectionError == 0) {
                        dispatchHotplug(ev.header.timestamp, ev.header.displayId,
                        dispatchHotplug(ev.header.timestamp, ev.header.displayId,
                                        ev.hotplug.connected);
                                        ev.hotplug.connected);
@@ -192,31 +192,28 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                                                       ev.hotplug.connectionError);
                                                       ev.hotplug.connectionError);
                    }
                    }
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
                case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE:
                    dispatchModeChanged(ev.header.timestamp, ev.header.displayId,
                    dispatchModeChanged(ev.header.timestamp, ev.header.displayId,
                                        ev.modeChange.modeId, ev.modeChange.vsyncPeriod);
                                        ev.modeChange.modeId, ev.modeChange.vsyncPeriod);
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_NULL:
                case DisplayEventType::DISPLAY_EVENT_NULL:
                    dispatchNullEvent(ev.header.timestamp, ev.header.displayId);
                    dispatchNullEvent(ev.header.timestamp, ev.header.displayId);
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
                case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
                    mFrameRateOverrides.emplace_back(ev.frameRateOverride);
                    mFrameRateOverrides.emplace_back(ev.frameRateOverride);
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
                case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
                    dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId,
                    dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId,
                                               std::move(mFrameRateOverrides));
                                               std::move(mFrameRateOverrides));
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
                case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
                    dispatchHdcpLevelsChanged(ev.header.displayId,
                    dispatchHdcpLevelsChanged(ev.header.displayId,
                                              ev.hdcpLevelsChange.connectedLevel,
                                              ev.hdcpLevelsChange.connectedLevel,
                                              ev.hdcpLevelsChange.maxLevel);
                                              ev.hdcpLevelsChange.maxLevel);
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION:
                case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION:
                    dispatchModeRejected(ev.header.displayId, ev.modeRejection.modeId);
                    dispatchModeRejected(ev.header.displayId, ev.modeRejection.modeId);
                    break;
                    break;
                default:
                    ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
                    break;
            }
            }
        }
        }
    }
    }
+12 −12
Original line number Original line Diff line number Diff line
@@ -55,10 +55,7 @@ static inline constexpr uint32_t fourcc(char c1, char c2, char c3, char c4) {
        static_cast<uint32_t>(c4);
        static_cast<uint32_t>(c4);
}
}


// ----------------------------------------------------------------------------
enum class DisplayEventType : uint32_t {
class DisplayEventReceiver {
public:
    enum {
    DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
    DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
    DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
    DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
    DISPLAY_EVENT_MODE_CHANGE = fourcc('m', 'o', 'd', 'e'),
    DISPLAY_EVENT_MODE_CHANGE = fourcc('m', 'o', 'd', 'e'),
@@ -69,6 +66,9 @@ public:
    DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'),
    DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'),
};
};


// ----------------------------------------------------------------------------
class DisplayEventReceiver {
public:
    struct Event {
    struct Event {
        // We add __attribute__((aligned(8))) for nsecs_t fields because
        // We add __attribute__((aligned(8))) for nsecs_t fields because
        // we need to make sure all fields are aligned the same with x86
        // we need to make sure all fields are aligned the same with x86
@@ -77,7 +77,7 @@ public:
        // https://en.wikipedia.org/wiki/Data_structure_alignment
        // https://en.wikipedia.org/wiki/Data_structure_alignment


        struct Header {
        struct Header {
            uint32_t type;
            DisplayEventType type;
            PhysicalDisplayId displayId __attribute__((aligned(8)));
            PhysicalDisplayId displayId __attribute__((aligned(8)));
            nsecs_t timestamp __attribute__((aligned(8)));
            nsecs_t timestamp __attribute__((aligned(8)));
        };
        };
+1 −1
Original line number Original line Diff line number Diff line
@@ -40,7 +40,7 @@ struct ChoreographerSync {
        std::unique_lock<decltype(mutex_)> lk(mutex_);
        std::unique_lock<decltype(mutex_)> lk(mutex_);


        auto check_event = [](auto const& ev) -> bool {
        auto check_event = [](auto const& ev) -> bool {
            return ev.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
            return ev.header.type == DisplayEventType::DISPLAY_EVENT_VSYNC;
        };
        };
        DisplayEventReceiver::Event ev_;
        DisplayEventReceiver::Event ev_;
        int evs = receiver_.getEvents(&ev_, 1);
        int evs = receiver_.getEvents(&ev_, 1);
+6 −4
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@
#include <android/frameworks/displayservice/1.0/BpHwEventCallback.h>
#include <android/frameworks/displayservice/1.0/BpHwEventCallback.h>


#include <thread>
#include <thread>
#include <ftl/enum.h>


namespace android {
namespace android {
namespace frameworks {
namespace frameworks {
@@ -97,11 +98,11 @@ int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* /
        for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
        for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
            const FwkReceiver::Event &event = buf[i];
            const FwkReceiver::Event &event = buf[i];


            uint32_t type = event.header.type;
            android::DisplayEventType type = event.header.type;
            uint64_t timestamp = event.header.timestamp;
            uint64_t timestamp = event.header.timestamp;


            switch(buf[i].header.type) {
            switch(buf[i].header.type) {
                case FwkReceiver::DISPLAY_EVENT_VSYNC: {
                case DisplayEventType::DISPLAY_EVENT_VSYNC: {
                    auto ret = mCallback->onVsync(timestamp, event.vsync.count);
                    auto ret = mCallback->onVsync(timestamp, event.vsync.count);
                    if (!ret.isOk()) {
                    if (!ret.isOk()) {
                        LOG(ERROR) << "AttachedEvent handleEvent fails on onVsync callback"
                        LOG(ERROR) << "AttachedEvent handleEvent fails on onVsync callback"
@@ -109,7 +110,7 @@ int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* /
                        return 0;  // remove the callback
                        return 0;  // remove the callback
                    }
                    }
                } break;
                } break;
                case FwkReceiver::DISPLAY_EVENT_HOTPLUG: {
                case DisplayEventType::DISPLAY_EVENT_HOTPLUG: {
                    auto ret = mCallback->onHotplug(timestamp, event.hotplug.connected);
                    auto ret = mCallback->onHotplug(timestamp, event.hotplug.connected);
                    if (!ret.isOk()) {
                    if (!ret.isOk()) {
                        LOG(ERROR) << "AttachedEvent handleEvent fails on onHotplug callback"
                        LOG(ERROR) << "AttachedEvent handleEvent fails on onHotplug callback"
@@ -118,7 +119,8 @@ int DisplayEventReceiver::AttachedEvent::handleEvent(int fd, int events, void* /
                    }
                    }
                } break;
                } break;
                default: {
                default: {
                    LOG(ERROR) << "AttachedEvent handleEvent unknown type: " << type;
                    LOG(ERROR) << "AttachedEvent handleEvent unknown type: "
                                << ftl::to_underlying(type);
                }
                }
            }
            }
        }
        }
Loading