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 Diff line number Diff line
@@ -238,7 +238,7 @@ void Choreographer::scheduleLatestConfigRequest() {
        // socket should be atomic across processes.
        DisplayEventReceiver::Event event;
        event.header =
                DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
                DisplayEventReceiver::Event::Header{DisplayEventType::DISPLAY_EVENT_NULL,
                                                    PhysicalDisplayId::fromPort(0), systemTime()};
        injectEvent(event);
    }
+8 −11
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
        for (ssize_t i = 0; i < n; i++) {
            const DisplayEventReceiver::Event& ev = buf[i];
            switch (ev.header.type) {
                case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                case DisplayEventType::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;
@@ -183,7 +183,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                        ATRACE_INT("RenderRate", fps);
                    }
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                case DisplayEventType::DISPLAY_EVENT_HOTPLUG:
                    if (ev.hotplug.connectionError == 0) {
                        dispatchHotplug(ev.header.timestamp, ev.header.displayId,
                                        ev.hotplug.connected);
@@ -192,31 +192,28 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                                                       ev.hotplug.connectionError);
                    }
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
                case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE:
                    dispatchModeChanged(ev.header.timestamp, ev.header.displayId,
                                        ev.modeChange.modeId, ev.modeChange.vsyncPeriod);
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_NULL:
                case DisplayEventType::DISPLAY_EVENT_NULL:
                    dispatchNullEvent(ev.header.timestamp, ev.header.displayId);
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
                case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
                    mFrameRateOverrides.emplace_back(ev.frameRateOverride);
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
                case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
                    dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId,
                                               std::move(mFrameRateOverrides));
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
                case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
                    dispatchHdcpLevelsChanged(ev.header.displayId,
                                              ev.hdcpLevelsChange.connectedLevel,
                                              ev.hdcpLevelsChange.maxLevel);
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION:
                case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION:
                    dispatchModeRejected(ev.header.displayId, ev.modeRejection.modeId);
                    break;
                default:
                    ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
                    break;
            }
        }
    }
+12 −12
Original line number 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);
}

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

// ----------------------------------------------------------------------------
class DisplayEventReceiver {
public:
    struct Event {
        // We add __attribute__((aligned(8))) for nsecs_t fields because
        // 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

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

        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_;
        int evs = receiver_.getEvents(&ev_, 1);
+6 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <android/frameworks/displayservice/1.0/BpHwEventCallback.h>

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

namespace android {
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) {
            const FwkReceiver::Event &event = buf[i];

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

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