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

Commit dc96fdfa authored by Brian Anderson's avatar Brian Anderson
Browse files

egl: Differentiate pending vs invalid timestamps.

Test: adb shell /data/nativetest/libgui_test/libgui_test
    --gtest_filter=*GetFrameTimestamps*

Change-Id: Iaa418ff1753a4339bfefaa68a6b03e8c96366a87
parent 6b376713
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -54,8 +54,7 @@ struct FrameEvents {
    static constexpr auto EVENT_COUNT =
            static_cast<size_t>(FrameEvent::EVENT_COUNT);
    static_assert(EVENT_COUNT <= 32, "Event count sanity check failed.");
    static constexpr nsecs_t TIMESTAMP_PENDING =
            std::numeric_limits<nsecs_t>::max();
    static constexpr nsecs_t TIMESTAMP_PENDING = -2;

    static inline bool isValidTimestamp(nsecs_t time) {
        return time != TIMESTAMP_PENDING;
+24 −9
Original line number Diff line number Diff line
@@ -229,14 +229,26 @@ static bool checkConsumerForUpdates(

static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) {
    if (dst != nullptr) {
        *dst = FrameEvents::isValidTimestamp(src) ? src : 0;
        // We always get valid timestamps for these eventually.
        *dst = (src == FrameEvents::TIMESTAMP_PENDING) ?
                NATIVE_WINDOW_TIMESTAMP_PENDING : src;
    }
}

static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime>& src) {
static void getFrameTimestampFence(nsecs_t *dst,
        const std::shared_ptr<FenceTime>& src, bool fenceShouldBeKnown) {
    if (dst != nullptr) {
        if (!fenceShouldBeKnown) {
            *dst = NATIVE_WINDOW_TIMESTAMP_PENDING;
            return;
        }

        nsecs_t signalTime = src->getSignalTime();
        *dst = Fence::isValidTimestamp(signalTime) ? signalTime : 0;
        *dst = (signalTime == Fence::SIGNAL_TIME_PENDING) ?
                    NATIVE_WINDOW_TIMESTAMP_PENDING :
                (signalTime == Fence::SIGNAL_TIME_INVALID) ?
                    NATIVE_WINDOW_TIMESTAMP_INVALID :
                signalTime;
    }
}

@@ -290,12 +302,15 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber,
    getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime);
    getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime);

    getFrameTimestampFence(outAcquireTime, events->acquireFence);
    getFrameTimestampFence(
            outGpuCompositionDoneTime, events->gpuCompositionDoneFence);
    getFrameTimestampFence(
            outDisplayPresentTime, events->displayPresentFence);
    getFrameTimestampFence(outReleaseTime, events->releaseFence);
    getFrameTimestampFence(outAcquireTime, events->acquireFence,
            events->hasAcquireInfo());
    getFrameTimestampFence(outGpuCompositionDoneTime,
            events->gpuCompositionDoneFence,
            events->hasGpuCompositionDoneInfo());
    getFrameTimestampFence(outDisplayPresentTime, events->displayPresentFence,
            events->hasDisplayPresentInfo());
    getFrameTimestampFence(outReleaseTime, events->releaseFence,
            events->hasReleaseInfo());

    return NO_ERROR;
}
+20 −20
Original line number Diff line number Diff line
@@ -1184,8 +1184,8 @@ TEST_F(GetFrameTimestampsTest, TimestampsAssociatedWithCorrectFrame) {
    EXPECT_EQ(mFrames[1].mRefreshes[0].kGpuCompositionDoneTime,
            outGpuCompositionDoneTime);
    EXPECT_EQ(mFrames[1].mRefreshes[0].kPresentTime, outDisplayPresentTime);
    EXPECT_EQ(0, outDequeueReadyTime);
    EXPECT_EQ(0, outReleaseTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outDequeueReadyTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outReleaseTime);
}

// This test verifies the acquire fence recorded by the consumer is not sent
@@ -1208,7 +1208,7 @@ TEST_F(GetFrameTimestampsTest, QueueTimestampsNoSync) {
    EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
    EXPECT_EQ(NO_ERROR, result);
    EXPECT_EQ(mFrames[0].kRequestedPresentTime, outRequestedPresentTime);
    EXPECT_EQ(0, outAcquireTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outAcquireTime);

    // Signal acquire fences. Verify a sync call still isn't necessary.
    mFrames[0].signalQueueFences();
@@ -1237,7 +1237,7 @@ TEST_F(GetFrameTimestampsTest, QueueTimestampsNoSync) {
    EXPECT_EQ(oldCount, mFakeConsumer->mGetFrameTimestampsCount);
    EXPECT_EQ(NO_ERROR, result);
    EXPECT_EQ(mFrames[1].kRequestedPresentTime, outRequestedPresentTime);
    EXPECT_EQ(0, outAcquireTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outAcquireTime);

    // Signal acquire fences. Verify a sync call still isn't necessary.
    mFrames[1].signalQueueFences();
@@ -1310,10 +1310,10 @@ TEST_F(GetFrameTimestampsTest, FencesInProducerNoSync) {
    EXPECT_EQ(mFrames[0].kLatchTime, outLatchTime);
    EXPECT_EQ(mFrames[0].mRefreshes[0].kStartTime, outFirstRefreshStartTime);
    EXPECT_EQ(mFrames[0].mRefreshes[2].kStartTime, outLastRefreshStartTime);
    EXPECT_EQ(0, outGpuCompositionDoneTime);
    EXPECT_EQ(0, outDisplayPresentTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outGpuCompositionDoneTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outDisplayPresentTime);
    EXPECT_EQ(mFrames[0].kDequeueReadyTime, outDequeueReadyTime);
    EXPECT_EQ(0, outReleaseTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outReleaseTime);

    // Verify available timestamps are correct for frame 1 again, before any
    // fence has been signaled.
@@ -1328,10 +1328,10 @@ TEST_F(GetFrameTimestampsTest, FencesInProducerNoSync) {
    EXPECT_EQ(mFrames[0].kLatchTime, outLatchTime);
    EXPECT_EQ(mFrames[0].mRefreshes[0].kStartTime, outFirstRefreshStartTime);
    EXPECT_EQ(mFrames[0].mRefreshes[2].kStartTime, outLastRefreshStartTime);
    EXPECT_EQ(0, outGpuCompositionDoneTime);
    EXPECT_EQ(0, outDisplayPresentTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outGpuCompositionDoneTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outDisplayPresentTime);
    EXPECT_EQ(mFrames[0].kDequeueReadyTime, outDequeueReadyTime);
    EXPECT_EQ(0, outReleaseTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outReleaseTime);

    // Signal the fences for frame 1.
    mFrames[0].signalRefreshFences();
@@ -1387,10 +1387,10 @@ TEST_F(GetFrameTimestampsTest, NoGpuNoSync) {
    EXPECT_EQ(mFrames[0].kLatchTime, outLatchTime);
    EXPECT_EQ(mFrames[0].mRefreshes[0].kStartTime, outFirstRefreshStartTime);
    EXPECT_EQ(mFrames[0].mRefreshes[2].kStartTime, outLastRefreshStartTime);
    EXPECT_EQ(0, outGpuCompositionDoneTime);
    EXPECT_EQ(0, outDisplayPresentTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_INVALID, outGpuCompositionDoneTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outDisplayPresentTime);
    EXPECT_EQ(mFrames[0].kDequeueReadyTime, outDequeueReadyTime);
    EXPECT_EQ(0, outReleaseTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outReleaseTime);

    // Signal the fences for frame 1.
    mFrames[0].signalRefreshFences();
@@ -1408,7 +1408,7 @@ TEST_F(GetFrameTimestampsTest, NoGpuNoSync) {
    EXPECT_EQ(mFrames[0].kLatchTime, outLatchTime);
    EXPECT_EQ(mFrames[0].mRefreshes[0].kStartTime, outFirstRefreshStartTime);
    EXPECT_EQ(mFrames[0].mRefreshes[2].kStartTime, outLastRefreshStartTime);
    EXPECT_EQ(0, outGpuCompositionDoneTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_INVALID, outGpuCompositionDoneTime);
    EXPECT_EQ(mFrames[0].mRefreshes[0].kPresentTime, outDisplayPresentTime);
    EXPECT_EQ(mFrames[0].kDequeueReadyTime, outDequeueReadyTime);
    EXPECT_EQ(mFrames[0].kReleaseTime, outReleaseTime);
@@ -1446,10 +1446,10 @@ TEST_F(GetFrameTimestampsTest, NoReleaseNoSync) {
    EXPECT_EQ(mFrames[0].kLatchTime, outLatchTime);
    EXPECT_EQ(mFrames[0].mRefreshes[0].kStartTime, outFirstRefreshStartTime);
    EXPECT_EQ(mFrames[0].mRefreshes[2].kStartTime, outLastRefreshStartTime);
    EXPECT_EQ(0, outGpuCompositionDoneTime);
    EXPECT_EQ(0, outDisplayPresentTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_INVALID, outGpuCompositionDoneTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outDisplayPresentTime);
    EXPECT_EQ(mFrames[0].kDequeueReadyTime, outDequeueReadyTime);
    EXPECT_EQ(0, outReleaseTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outReleaseTime);

    mFrames[0].signalRefreshFences();
    mFrames[0].signalReleaseFences();
@@ -1470,10 +1470,10 @@ TEST_F(GetFrameTimestampsTest, NoReleaseNoSync) {
    EXPECT_EQ(mFrames[1].kLatchTime, outLatchTime);
    EXPECT_EQ(mFrames[1].mRefreshes[0].kStartTime, outFirstRefreshStartTime);
    EXPECT_EQ(mFrames[1].mRefreshes[1].kStartTime, outLastRefreshStartTime);
    EXPECT_EQ(0, outGpuCompositionDoneTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_INVALID, outGpuCompositionDoneTime);
    EXPECT_EQ(mFrames[1].mRefreshes[0].kPresentTime, outDisplayPresentTime);
    EXPECT_EQ(0, outDequeueReadyTime);
    EXPECT_EQ(0, outReleaseTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outDequeueReadyTime);
    EXPECT_EQ(NATIVE_WINDOW_TIMESTAMP_PENDING, outReleaseTime);
}

// This test verifies there are no sync calls for present times
+8 −0
Original line number Diff line number Diff line
@@ -311,6 +311,14 @@ enum {
 */
static const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1);

/* parameter for NATIVE_WINDOW_GET_FRAME_TIMESTAMPS
 *
 * Special timestamp value to indicate the timestamps aren't yet known or
 * that they are invalid.
 */
static const int64_t NATIVE_WINDOW_TIMESTAMP_PENDING = -2;
static const int64_t NATIVE_WINDOW_TIMESTAMP_INVALID = -1;

struct ANativeWindow
{
#ifdef __cplusplus
+2 −0
Original line number Diff line number Diff line
@@ -640,6 +640,8 @@ typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const
#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x3157
#define EGL_DEQUEUE_READY_TIME_ANDROID 0x3158
#define EGL_READS_DONE_TIME_ANDROID 0x3159
#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID, -2)
#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID, -1)
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean eglGetNextFrameIdANDROID(EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
EGLAPI EGLBoolean eglGetCompositorTimingANDROID(EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values);
Loading