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

Commit 44880877 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Send multiple scheduler frame timelines.""

parents f8bd1ffa caaa47d6
Loading
Loading
Loading
Loading
+0 −16
Original line number Original line Diff line number Diff line
@@ -130,19 +130,6 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) {
    return 1; // keep the callback
    return 1; // keep the callback
}
}


void DisplayEventDispatcher::populateFrameTimelines(const DisplayEventReceiver::Event& event,
                                                    VsyncEventData* outVsyncEventData) const {
    for (size_t i = 0; i < DisplayEventReceiver::kFrameTimelinesLength; i++) {
        DisplayEventReceiver::Event::VSync::FrameTimeline receiverTimeline =
                event.vsync.frameTimelines[i];
        outVsyncEventData->frameTimelines[i] = {.id = receiverTimeline.vsyncId,
                                                .deadlineTimestamp =
                                                        receiverTimeline.deadlineTimestamp,
                                                .expectedPresentTime =
                                                        receiverTimeline.expectedVSyncTimestamp};
    }
}

bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                                                  PhysicalDisplayId* outDisplayId,
                                                  PhysicalDisplayId* outDisplayId,
                                                  uint32_t* outCount,
                                                  uint32_t* outCount,
@@ -167,9 +154,6 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                    outVsyncEventData->deadlineTimestamp = ev.vsync.deadlineTimestamp;
                    outVsyncEventData->deadlineTimestamp = ev.vsync.deadlineTimestamp;
                    outVsyncEventData->frameInterval = ev.vsync.frameInterval;
                    outVsyncEventData->frameInterval = ev.vsync.frameInterval;
                    outVsyncEventData->expectedPresentTime = ev.vsync.expectedVSyncTimestamp;
                    outVsyncEventData->expectedPresentTime = ev.vsync.expectedVSyncTimestamp;
                    outVsyncEventData->preferredFrameTimelineIndex =
                            ev.vsync.preferredFrameTimelineIndex;
                    populateFrameTimelines(ev, outVsyncEventData);
                    break;
                    break;
                case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                    dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
                    dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
+0 −24
Original line number Original line Diff line number Diff line
@@ -17,7 +17,6 @@
#include <gui/DisplayEventReceiver.h>
#include <gui/DisplayEventReceiver.h>
#include <utils/Log.h>
#include <utils/Log.h>
#include <utils/Looper.h>
#include <utils/Looper.h>
#include <array>


namespace android {
namespace android {
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
@@ -37,26 +36,6 @@ struct VsyncEventData {


    // The anticipated Vsync present time.
    // The anticipated Vsync present time.
    int64_t expectedPresentTime = 0;
    int64_t expectedPresentTime = 0;

    struct FrameTimeline {
        // The Vsync Id corresponsing to this vsync event. This will be used to
        // populate ISurfaceComposer::setFrameTimelineVsync and
        // SurfaceComposerClient::setFrameTimelineVsync
        int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID;

        // The deadline in CLOCK_MONOTONIC that the app needs to complete its
        // frame by (both on the CPU and the GPU)
        int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max();

        // The anticipated Vsync present time.
        int64_t expectedPresentTime = 0;
    };

    // Sorted possible frame timelines.
    std::array<FrameTimeline, DisplayEventReceiver::kFrameTimelinesLength> frameTimelines;

    // Index into the frameTimelines that represents the platform's preferred frame timeline.
    size_t preferredFrameTimelineIndex = std::numeric_limits<size_t>::max();
};
};


class DisplayEventDispatcher : public LooperCallback {
class DisplayEventDispatcher : public LooperCallback {
@@ -98,8 +77,5 @@ private:


    bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
    bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
                              uint32_t* outCount, VsyncEventData* outVsyncEventData);
                              uint32_t* outCount, VsyncEventData* outVsyncEventData);

    void populateFrameTimelines(const DisplayEventReceiver::Event& event,
                                VsyncEventData* outVsyncEventData) const;
};
};
} // namespace android
} // namespace android
+0 −9
Original line number Original line Diff line number Diff line
@@ -49,9 +49,6 @@ static inline constexpr uint32_t fourcc(char c1, char c2, char c3, char c4) {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
class DisplayEventReceiver {
class DisplayEventReceiver {
public:
public:
    // Max amount of frame timelines is arbitrarily set to be reasonable.
    static constexpr int64_t kFrameTimelinesLength = 7;

    enum {
    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'),
@@ -80,12 +77,6 @@ public:
            nsecs_t deadlineTimestamp __attribute__((aligned(8)));
            nsecs_t deadlineTimestamp __attribute__((aligned(8)));
            nsecs_t frameInterval __attribute__((aligned(8)));
            nsecs_t frameInterval __attribute__((aligned(8)));
            int64_t vsyncId;
            int64_t vsyncId;
            size_t preferredFrameTimelineIndex __attribute__((aligned(8)));
            struct FrameTimeline {
                nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
                nsecs_t deadlineTimestamp __attribute__((aligned(8)));
                int64_t vsyncId;
            } frameTimelines[kFrameTimelinesLength];
        };
        };


        struct Hotplug {
        struct Hotplug {
+23 −11
Original line number Original line Diff line number Diff line
@@ -100,10 +100,17 @@ class Choreographer;
 * Implementation of AChoreographerFrameCallbackData.
 * Implementation of AChoreographerFrameCallbackData.
 */
 */
struct ChoreographerFrameCallbackDataImpl {
struct ChoreographerFrameCallbackDataImpl {
    struct FrameTimeline {
        int64_t vsyncId{0};
        int64_t expectedPresentTimeNanos{0};
        int64_t deadlineNanos{0};
    };

    int64_t frameTimeNanos{0};
    int64_t frameTimeNanos{0};


    std::array<VsyncEventData::FrameTimeline, DisplayEventReceiver::kFrameTimelinesLength>
    size_t frameTimelinesLength;
            frameTimelines;

    std::vector<FrameTimeline> frameTimelines;


    size_t preferredFrameTimelineIndex;
    size_t preferredFrameTimelineIndex;


@@ -449,9 +456,14 @@ bool Choreographer::inCallback() const {
}
}


ChoreographerFrameCallbackDataImpl Choreographer::createFrameCallbackData(nsecs_t timestamp) const {
ChoreographerFrameCallbackDataImpl Choreographer::createFrameCallbackData(nsecs_t timestamp) const {
    std::vector<ChoreographerFrameCallbackDataImpl::FrameTimeline> frameTimelines;
    frameTimelines.push_back({.vsyncId = mLastVsyncEventData.id,
                              .expectedPresentTimeNanos = mLastVsyncEventData.expectedPresentTime,
                              .deadlineNanos = mLastVsyncEventData.deadlineTimestamp});
    return {.frameTimeNanos = timestamp,
    return {.frameTimeNanos = timestamp,
            .preferredFrameTimelineIndex = mLastVsyncEventData.preferredFrameTimelineIndex,
            .frameTimelinesLength = 1,
            .frameTimelines = mLastVsyncEventData.frameTimelines,
            .preferredFrameTimelineIndex = 0,
            .frameTimelines = frameTimelines,
            .choreographer = this};
            .choreographer = this};
}
}


@@ -634,7 +646,7 @@ size_t AChoreographerFrameCallbackData_getFrameTimelinesLength(
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
                        "Data is only valid in callback");
                        "Data is only valid in callback");
    return frameCallbackData->frameTimelines.size();
    return frameCallbackData->frameTimelinesLength;
}
}
size_t AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(
size_t AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(
        const AChoreographerFrameCallbackData* data) {
        const AChoreographerFrameCallbackData* data) {
@@ -650,8 +662,8 @@ int64_t AChoreographerFrameCallbackData_getFrameTimelineVsyncId(
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
                        "Data is only valid in callback");
                        "Data is only valid in callback");
    LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
    LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelinesLength, "Index out of bounds");
    return frameCallbackData->frameTimelines[index].id;
    return frameCallbackData->frameTimelines[index].vsyncId;
}
}
int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentTime(
int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentTime(
        const AChoreographerFrameCallbackData* data, size_t index) {
        const AChoreographerFrameCallbackData* data, size_t index) {
@@ -659,8 +671,8 @@ int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentTime(
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
                        "Data is only valid in callback");
                        "Data is only valid in callback");
    LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
    LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelinesLength, "Index out of bounds");
    return frameCallbackData->frameTimelines[index].expectedPresentTime;
    return frameCallbackData->frameTimelines[index].expectedPresentTimeNanos;
}
}
int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadline(
int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadline(
        const AChoreographerFrameCallbackData* data, size_t index) {
        const AChoreographerFrameCallbackData* data, size_t index) {
@@ -668,8 +680,8 @@ int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadline(
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
                        "Data is only valid in callback");
                        "Data is only valid in callback");
    LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
    LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelinesLength, "Index out of bounds");
    return frameCallbackData->frameTimelines[index].deadlineTimestamp;
    return frameCallbackData->frameTimelines[index].deadlineNanos;
}
}


AChoreographer* AChoreographer_create() {
AChoreographer* AChoreographer_create() {
+8 −37
Original line number Original line Diff line number Diff line
@@ -355,7 +355,14 @@ void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);


    LOG_FATAL_IF(!mVSyncState);
    LOG_FATAL_IF(!mVSyncState);
    const int64_t vsyncId = generateToken(timestamp, deadlineTimestamp, expectedVSyncTimestamp);
    const int64_t vsyncId = [&] {
        if (mTokenManager != nullptr) {
            return mTokenManager->generateTokenForPredictions(
                    {timestamp, deadlineTimestamp, expectedVSyncTimestamp});
        }
        return FrameTimelineInfo::INVALID_VSYNC_ID;
    }();

    mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
    mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
                                       expectedVSyncTimestamp, deadlineTimestamp, vsyncId));
                                       expectedVSyncTimestamp, deadlineTimestamp, vsyncId));
    mCondition.notify_all();
    mCondition.notify_all();
@@ -560,48 +567,12 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
    }
    }
}
}


int64_t EventThread::generateToken(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp,
                                   nsecs_t deadlineTimestamp) const {
    if (mTokenManager != nullptr) {
        return mTokenManager->generateTokenForPredictions(
                {timestamp, deadlineTimestamp, expectedVSyncTimestamp});
    }
    return FrameTimelineInfo::INVALID_VSYNC_ID;
}

void EventThread::generateFrameTimeline(DisplayEventReceiver::Event& event) const {
    // Add 1 to ensure the preferredFrameTimelineIndex entry (when multiplier == 0) is included.
    for (int multiplier = -DisplayEventReceiver::kFrameTimelinesLength + 1, currentIndex = 0;
         currentIndex < DisplayEventReceiver::kFrameTimelinesLength; multiplier++) {
        nsecs_t deadline = event.vsync.deadlineTimestamp + multiplier * event.vsync.frameInterval;
        // Valid possible frame timelines must have future values.
        if (deadline > event.header.timestamp) {
            if (multiplier == 0) {
                event.vsync.preferredFrameTimelineIndex = currentIndex;
                event.vsync.frameTimelines[currentIndex] =
                        {.vsyncId = event.vsync.vsyncId,
                         .deadlineTimestamp = event.vsync.deadlineTimestamp,
                         .expectedVSyncTimestamp = event.vsync.expectedVSyncTimestamp};
            } else {
                nsecs_t expectedVSync =
                        event.vsync.expectedVSyncTimestamp + multiplier * event.vsync.frameInterval;
                event.vsync.frameTimelines[currentIndex] =
                        {.vsyncId = generateToken(event.header.timestamp, expectedVSync, deadline),
                         .deadlineTimestamp = deadline,
                         .expectedVSyncTimestamp = expectedVSync};
            }
            currentIndex++;
        }
    }
}

void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
                                const DisplayEventConsumers& consumers) {
                                const DisplayEventConsumers& consumers) {
    for (const auto& consumer : consumers) {
    for (const auto& consumer : consumers) {
        DisplayEventReceiver::Event copy = event;
        DisplayEventReceiver::Event copy = event;
        if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
        if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
            copy.vsync.frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
            copy.vsync.frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
            generateFrameTimeline(copy);
        }
        }
        switch (consumer->postEvent(copy)) {
        switch (consumer->postEvent(copy)) {
            case NO_ERROR:
            case NO_ERROR:
Loading