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

Commit 74e17562 authored by Ady Abraham's avatar Ady Abraham
Browse files

SurfaceFlinger: Shared timeline plumbing

Add plumbing to get shared timeline data from Surface Flinger to HWUI
and back.

Bug: 162890382
Bug: 162888881

Test: SF unit tests
Change-Id: Ifb76e6bf28d43c051e6c8ff568437ec9a106b865
parent 934e82a9
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -73,7 +73,8 @@ status_t DisplayEventDispatcher::scheduleVsync() {
        nsecs_t vsyncTimestamp;
        PhysicalDisplayId vsyncDisplayId;
        uint32_t vsyncCount;
        if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
        int64_t vsyncId;
        if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncId)) {
            ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", this,
                  ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
        }
@@ -116,11 +117,13 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) {
    nsecs_t vsyncTimestamp;
    PhysicalDisplayId vsyncDisplayId;
    uint32_t vsyncCount;
    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
        ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%s, count=%d", this,
              ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount);
    int64_t vsyncId;
    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncId)) {
        ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64
              ", displayId=%s, count=%d, vsyncId=%" PRId64,
              this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount, vsyncId);
        mWaitingForVsync = false;
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncId);
    }

    return 1; // keep the callback
@@ -128,10 +131,11 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) {

bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                                                  PhysicalDisplayId* outDisplayId,
                                                  uint32_t* outCount) {
                                                  uint32_t* outCount, int64_t* outVsyncId) {
    bool gotVsync = false;
    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
    ssize_t n;
    *outVsyncId = 0;
    while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
        ALOGV("dispatcher %p ~ Read %d events.", this, int(n));
        for (ssize_t i = 0; i < n; i++) {
@@ -144,6 +148,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                    *outTimestamp = ev.header.timestamp;
                    *outDisplayId = ev.header.displayId;
                    *outCount = ev.vsync.count;
                    *outVsyncId = ev.vsync.vsyncId;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                    dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
+59 −0
Original line number Diff line number Diff line
@@ -1150,6 +1150,38 @@ public:

        return NO_ERROR;
    }

    virtual status_t setFrameTimelineVsync(const sp<IGraphicBufferProducer>& surface,
                                           int64_t frameTimelineVsyncId) {
        Parcel data, reply;
        status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        if (err != NO_ERROR) {
            ALOGE("setFrameTimelineVsync: failed writing interface token: %s (%d)", strerror(-err),
                  -err);
            return err;
        }

        err = data.writeStrongBinder(IInterface::asBinder(surface));
        if (err != NO_ERROR) {
            ALOGE("setFrameTimelineVsync: failed writing strong binder: %s (%d)", strerror(-err),
                  -err);
            return err;
        }

        err = data.writeInt64(frameTimelineVsyncId);
        if (err != NO_ERROR) {
            ALOGE("setFrameTimelineVsync: failed writing int64_t: %s (%d)", strerror(-err), -err);
            return err;
        }

        err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_VSYNC, data, &reply);
        if (err != NO_ERROR) {
            ALOGE("setFrameTimelineVsync: failed to transact: %s (%d)", strerror(-err), err);
            return err;
        }

        return reply.readInt32();
    }
};

// Out-of-line virtual method definition to trigger vtable emission in this
@@ -1950,6 +1982,33 @@ status_t BnSurfaceComposer::onTransact(
            }
            return NO_ERROR;
        }
        case SET_FRAME_TIMELINE_VSYNC: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> binder;
            status_t err = data.readStrongBinder(&binder);
            if (err != NO_ERROR) {
                ALOGE("setFrameTimelineVsync: failed to read strong binder: %s (%d)",
                      strerror(-err), -err);
                return err;
            }
            sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(binder);
            if (!surface) {
                ALOGE("setFrameTimelineVsync: failed to cast to IGraphicBufferProducer: %s (%d)",
                      strerror(-err), -err);
                return err;
            }
            int64_t frameTimelineVsyncId;
            err = data.readInt64(&frameTimelineVsyncId);
            if (err != NO_ERROR) {
                ALOGE("setFrameTimelineVsync: failed to read int64_t: %s (%d)", strerror(-err),
                      -err);
                return err;
            }

            status_t result = setFrameTimelineVsync(surface, frameTimelineVsyncId);
            reply->writeInt32(result);
            return NO_ERROR;
        }
        default: {
            return BBinder::onTransact(code, data, reply, flags);
        }
+11 −0
Original line number Diff line number Diff line
@@ -1207,6 +1207,9 @@ int Surface::perform(int operation, va_list args)
    case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER:
        res = dispatchGetLastQueuedBuffer(args);
        break;
    case NATIVE_WINDOW_SET_FRAME_TIMELINE_VSYNC:
        res = dispatchSetFrameTimelineVsync(args);
        break;
    default:
        res = NAME_NOT_FOUND;
        break;
@@ -1513,6 +1516,14 @@ int Surface::dispatchGetLastQueuedBuffer(va_list args) {
    return result;
}

int Surface::dispatchSetFrameTimelineVsync(va_list args) {
    ATRACE_CALL();
    auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t));

    ALOGV("Surface::dispatchSetFrameTimelineVsync");
    return composerService()->setFrameTimelineVsync(mGraphicBufferProducer, frameTimelineVsyncId);
}

bool Surface::transformToDisplayInverse() {
    return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) ==
            NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
+3 −2
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ private:
    DisplayEventReceiver mReceiver;
    bool mWaitingForVsync;

    virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0;
    virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
                               int64_t vsyncId) = 0;
    virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
                                 bool connected) = 0;
    virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
@@ -53,6 +54,6 @@ private:
    virtual void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) = 0;

    bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
                              uint32_t* outCount);
                              uint32_t* outCount, int64_t* outVsyncId);
};
} // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ public:
            uint32_t count;
            nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
            nsecs_t deadlineTimestamp __attribute__((aligned(8)));
            int64_t vsyncId;
        };

        struct Hotplug {
Loading