diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 45488ff8d..e22679e49 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -807,7 +807,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); @@ -835,37 +835,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 - // 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. - // - // To be safe, we don't refuse to acquire the buffer if presentWhen 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; - 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 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 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 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 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 (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; + } + + ST_LOGV("pts accept: 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); } + int buf = front->mBuf; *buffer = *front; ATRACE_BUFFER_INDEX(buf); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 998ea8ac8..e2ec6434c 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -261,9 +261,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; } diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 6c285d37b..6dfd30604 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -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); } // ----------------------------------------------------------------------------