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

Commit 86cd09d3 authored by Andy McFadden's avatar Andy McFadden Committed by Android (Google) Code Review
Browse files

Merge "Drop frames based on presentation timestamp"

parents ba93b3f8 14fab7dd
Loading
Loading
Loading
Loading
+68 −28
Original line number Diff line number Diff line
@@ -812,7 +812,7 @@ void BufferQueue::freeAllBuffersLocked() {
    }
}

status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t expectedPresent) {
    ATRACE_CALL();
    Mutex::Autolock _l(mMutex);

@@ -840,37 +840,77 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
    }

    Fifo::iterator front(mQueue.begin());
    int buf = front->mBuf;

    // Compare the buffer's desired presentation time to the predicted
    // actual display time.
    //
    // The "presentWhen" argument indicates when the buffer is expected
    // If expectedPresent is specified, we may not want to return a buffer yet.
    // If it's specified and there's more than one buffer queued, we may
    // want to drop a buffer.
    if (expectedPresent != 0) {
        const int MAX_REASONABLE_NSEC = 1000000000ULL;  // 1 second

        // The "expectedPresent" argument indicates when the buffer is expected
        // to be presented on-screen.  If the buffer's desired-present time
    // is earlier (less) than presentWhen, meaning it'll be displayed
    // on time or possibly late, we acquire and return it.  If we don't want
    // to display it until after the presentWhen time, we return PRESENT_LATER
    // without acquiring it.
        // is earlier (less) than expectedPresent, meaning it'll be displayed
        // on time or possibly late if we show it ASAP, we acquire and return
        // it.  If we don't want to display it until after the expectedPresent
        // time, we return PRESENT_LATER without acquiring it.
        //
    // To be safe, we don't refuse to acquire the buffer if presentWhen is
        // To be safe, we don't defer acquisition if expectedPresent is
        // more than one second in the future beyond the desired present time
    // (i.e. we'd be holding the buffer for a really long time).
    const int MAX_FUTURE_NSEC = 1000000000ULL;
        // (i.e. we'd be holding the buffer for a long time).
        //
        // NOTE: code assumes monotonic time values from the system clock are
        // positive.
        while (mQueue.size() > 1) {
            // If entry[1] is timely, drop entry[0] (and repeat).  We apply
            // an additional criteria here: we only drop the earlier buffer if
            // our desiredPresent falls within +/- 1 second of the expected
            // present.  Otherwise, bogus desiredPresent times (e.g. 0 or
            // a small relative timestamp), which normally mean "ignore the
            // timestamp and acquire immediately", would cause us to drop
            // frames.
            //
            // We may want to add an additional criteria: don't drop the
            // earlier buffer if entry[1]'s fence hasn't signaled yet.
            //
            // (Vector front is [0], back is [size()-1])
            const BufferItem& bi(mQueue[1]);
            nsecs_t desiredPresent = bi.mTimestamp;
            if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
                    desiredPresent > expectedPresent) {
                // This buffer is set to display in the near future, or
                // desiredPresent is garbage.  Either way we don't want to
                // drop the previous buffer just to get this on screen sooner.
                ST_LOGV("pts nodrop: des=%lld expect=%lld (%lld) now=%lld",
                        desiredPresent, expectedPresent, desiredPresent - expectedPresent,
                        systemTime(CLOCK_MONOTONIC));
                break;
            }
            ST_LOGV("pts drop: queue1des=%lld expect=%lld size=%d",
                    desiredPresent, expectedPresent, mQueue.size());
            if (stillTracking(front)) {
                // front buffer is still in mSlots, so mark the slot as free
                mSlots[front->mBuf].mBufferState = BufferSlot::FREE;
            }
            mQueue.erase(front);
            front = mQueue.begin();
        }

        // See if the front buffer is due.
        nsecs_t desiredPresent = front->mTimestamp;
    if (presentWhen != 0 && desiredPresent > presentWhen &&
            desiredPresent - presentWhen < MAX_FUTURE_NSEC)
    {
        ST_LOGV("pts defer: des=%lld when=%lld (%lld) now=%lld",
                desiredPresent, presentWhen, desiredPresent - presentWhen,
        if (desiredPresent > expectedPresent &&
                desiredPresent < expectedPresent + MAX_REASONABLE_NSEC) {
            ST_LOGV("pts defer: des=%lld expect=%lld (%lld) now=%lld",
                    desiredPresent, expectedPresent, desiredPresent - expectedPresent,
                    systemTime(CLOCK_MONOTONIC));
            return PRESENT_LATER;
        }
    if (presentWhen != 0) {
        ST_LOGV("pts accept: %p[%d] sig=%lld des=%lld when=%lld (%lld)",
                mSlots, buf, mSlots[buf].mFence->getSignalTime(),
                desiredPresent, presentWhen, desiredPresent - presentWhen);

        ST_LOGV("pts accept: des=%lld expect=%lld (%lld) now=%lld",
                desiredPresent, expectedPresent, desiredPresent - expectedPresent,
                systemTime(CLOCK_MONOTONIC));
    }

    int buf = front->mBuf;
    *buffer = *front;
    ATRACE_BUFFER_INDEX(buf);

+1 −3
Original line number Diff line number Diff line
@@ -263,9 +263,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    Mutex::Autolock lock(mMutex);
    int64_t timestamp;
    if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
        timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
        ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
             timestamp / 1000000.f);
        timestamp = 0;
    } else {
        timestamp = mTimestamp;
    }
+0 −5
Original line number Diff line number Diff line
@@ -499,11 +499,6 @@ void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
        setError(EGL_BAD_SURFACE, EGL_FALSE);
        return;
    }

    int64_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC);

    egl_surface_t const * const s = get_surface(surface);
    native_window_set_buffers_timestamp(s->win.get(), timestamp);
}

// ----------------------------------------------------------------------------