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

Commit 60aee1c4 authored by Alec Mouri's avatar Alec Mouri
Browse files

[AChoreographer] Add refresh rate callback.

This will augment the NDK to respond to display events where the display
refresh rate changes. Consumers of this api will include:
* HWUI, for implementing a policy for determining whether to use
render-ahead,
* Swappy, to potentially replace jumping into Java from native code to
respond to display evnets there.
* Any other native app that would rely on the up-to-date display refresh
rate.

Currently however this is not yet exposed to NDK as CTS is not yet
written. Once CTS is written then this will be formally exposed to NDK.
For now we'll leave these as APEX apis to represent incremental
progress.

Bug: 136262896
Test: builds
Change-Id: I66d393f93eb5d681547411e330ef1b8950a35c5d
parent 516de508
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -36,7 +36,10 @@ static const size_t EVENT_BUFFER_SIZE = 100;
DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
                                               ISurfaceComposer::VsyncSource vsyncSource,
                                               ISurfaceComposer::ConfigChanged configChanged)
      : mLooper(looper), mReceiver(vsyncSource, configChanged), mWaitingForVsync(false) {
      : mLooper(looper),
        mReceiver(vsyncSource, configChanged),
        mWaitingForVsync(false),
        mConfigChangeFlag(configChanged) {
    ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
}

@@ -86,6 +89,18 @@ status_t DisplayEventDispatcher::scheduleVsync() {
    return OK;
}

void DisplayEventDispatcher::toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag) {
    if (mConfigChangeFlag == configChangeFlag) {
        return;
    }
    status_t status = mReceiver.toggleConfigEvents(configChangeFlag);
    if (status) {
        ALOGW("Failed enable config events, status=%d", status);
        return;
    }
    mConfigChangeFlag = configChangeFlag;
}

int DisplayEventDispatcher::handleEvent(int, int events, void*) {
    if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
        ALOGE("Display event receiver pipe was closed or an error occurred.  "
@@ -140,7 +155,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
                    dispatchConfigChanged(ev.header.timestamp, ev.header.displayId,
                                          ev.config.configId);
                                          ev.config.configId, ev.config.vsyncPeriod);
                    break;
                default:
                    ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
+8 −0
Original line number Diff line number Diff line
@@ -79,6 +79,14 @@ status_t DisplayEventReceiver::requestNextVsync() {
    return NO_INIT;
}

status_t DisplayEventReceiver::toggleConfigEvents(
        ISurfaceComposer::ConfigChanged configChangeFlag) {
    if (mEventConnection != nullptr) {
        mEventConnection->toggleConfigEvents(configChangeFlag);
        return NO_ERROR;
    }
    return NO_INIT;
}

ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
        size_t count) {
+10 −1
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ enum class Tag : uint32_t {
    STEAL_RECEIVE_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
    SET_VSYNC_RATE,
    REQUEST_NEXT_VSYNC,
    LAST = REQUEST_NEXT_VSYNC,
    TOGGLE_CONFIG_EVENTS,
    LAST = TOGGLE_CONFIG_EVENTS,
};

} // Anonymous namespace
@@ -53,6 +54,12 @@ public:
        callRemoteAsync<decltype(&IDisplayEventConnection::requestNextVsync)>(
                Tag::REQUEST_NEXT_VSYNC);
    }

    void toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag) override {
        callRemoteAsync<decltype(
                &IDisplayEventConnection::toggleConfigEvents)>(Tag::TOGGLE_CONFIG_EVENTS,
                                                               configChangeFlag);
    }
};

// Out-of-line virtual method definition to trigger vtable emission in this translation unit (see
@@ -74,6 +81,8 @@ status_t BnDisplayEventConnection::onTransact(uint32_t code, const Parcel& data,
            return callLocal(data, reply, &IDisplayEventConnection::setVsyncRate);
        case Tag::REQUEST_NEXT_VSYNC:
            return callLocalAsync(data, reply, &IDisplayEventConnection::requestNextVsync);
        case Tag::TOGGLE_CONFIG_EVENTS:
            return callLocalAsync(data, reply, &IDisplayEventConnection::toggleConfigEvents);
    }
}

+3 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ public:
    status_t initialize();
    void dispose();
    status_t scheduleVsync();
    void toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag);

protected:
    virtual ~DisplayEventDispatcher() = default;
@@ -39,12 +40,13 @@ private:
    sp<Looper> mLooper;
    DisplayEventReceiver mReceiver;
    bool mWaitingForVsync;
    ISurfaceComposer::ConfigChanged mConfigChangeFlag;

    virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0;
    virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
                                 bool connected) = 0;
    virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
                                       int32_t configId) = 0;
                                       int32_t configId, nsecs_t vsyncPeriod) = 0;

    virtual int handleEvent(int receiveFd, int events, void* data);
    bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
+6 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ public:

        struct Config {
            int32_t configId;
            nsecs_t vsyncPeriod;
        };

        Header header;
@@ -144,6 +145,11 @@ public:
     */
    status_t requestNextVsync();

    /*
     * toggleConfigEvents() toggles delivery of config change events.
     */
    status_t toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag);

private:
    sp<IDisplayEventConnection> mEventConnection;
    std::unique_ptr<gui::BitTube> mDataChannel;
Loading