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

Commit 50143b37 authored by Brian Anderson's avatar Brian Anderson
Browse files

Avoid sync calls for unsupported/non-existant times

* Make sure not to do sync calls for present or retire
  if they aren't supported.

* Don't do sync calls for retire or release if they
  can not possibly exist.

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

Change-Id: I580409f01cbf07e9a6e00fbb05d914654f12a4a2
parent ba4d92cc
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -389,7 +389,8 @@ private:


    Condition mQueueBufferCondition;
    Condition mQueueBufferCondition;


    uint64_t mNextFrameNumber;
    uint64_t mNextFrameNumber = 1;
    uint64_t mLastFrameNumber = 0;


    // Mutable because ANativeWindow::query needs this class const.
    // Mutable because ANativeWindow::query needs this class const.
    mutable bool mQueriedSupportedTimestamps;
    mutable bool mQueriedSupportedTimestamps;
+45 −20
Original line number Original line Diff line number Diff line
@@ -49,7 +49,6 @@ Surface::Surface(
      mAutoRefresh(false),
      mAutoRefresh(false),
      mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
      mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
      mSharedBufferHasBeenQueued(false),
      mSharedBufferHasBeenQueued(false),
      mNextFrameNumber(1),
      mQueriedSupportedTimestamps(false),
      mQueriedSupportedTimestamps(false),
      mFrameTimestampsSupportsPresent(false),
      mFrameTimestampsSupportsPresent(false),
      mFrameTimestampsSupportsRetire(false),
      mFrameTimestampsSupportsRetire(false),
@@ -144,6 +143,31 @@ void Surface::enableFrameTimestamps(bool enable) {
    mEnableFrameTimestamps = enable;
    mEnableFrameTimestamps = enable;
}
}


static bool checkConsumerForUpdates(
        const FrameEvents* e, const uint64_t lastFrameNumber,
        const nsecs_t* outRefreshStartTime,
        const nsecs_t* outGlCompositionDoneTime,
        const nsecs_t* outDisplayPresentTime,
        const nsecs_t* outDisplayRetireTime,
        const nsecs_t* outReleaseTime) {
    bool checkForRefreshStart = (outRefreshStartTime != nullptr) &&
            !e->hasFirstRefreshStartInfo();
    bool checkForGlCompositionDone = (outGlCompositionDoneTime != nullptr) &&
            !e->hasGpuCompositionDoneInfo();
    bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) &&
            !e->hasDisplayPresentInfo();

    // DisplayRetire and Release are never available for the last frame.
    bool checkForDisplayRetire = (outDisplayRetireTime != nullptr) &&
            !e->hasDisplayRetireInfo() && (e->frameNumber != lastFrameNumber);
    bool checkForRelease = (outReleaseTime != nullptr) &&
            !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber);

    // RequestedPresent and Acquire info are always available producer-side.
    return checkForRefreshStart || checkForGlCompositionDone ||
            checkForDisplayPresent || checkForDisplayRetire || checkForRelease;
}

static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) {
static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) {
    if (dst != nullptr) {
    if (dst != nullptr) {
        *dst = Fence::isValidTimestamp(src) ? src : 0;
        *dst = Fence::isValidTimestamp(src) ? src : 0;
@@ -180,24 +204,25 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber,
    }
    }


    FrameEvents* events = mFrameEventHistory.getFrame(frameNumber);
    FrameEvents* events = mFrameEventHistory.getFrame(frameNumber);
    if (events == nullptr) {
        // If the entry isn't available in the producer, it's definitely not
        // available in the consumer.
        return NAME_NOT_FOUND;
    }


    // Update our cache of events if the requested events are not available.
    // Update our cache of events if the requested events are not available.
    if (events == nullptr ||
    if (checkConsumerForUpdates(events, mLastFrameNumber,
        (outRequestedPresentTime && !events->hasRequestedPresentInfo()) ||
            outRefreshStartTime, outGlCompositionDoneTime,
        (outAcquireTime && !events->hasAcquireInfo()) ||
            outDisplayPresentTime, outDisplayRetireTime, outReleaseTime)) {
        (outRefreshStartTime && !events->hasFirstRefreshStartInfo()) ||
        (outGlCompositionDoneTime && !events->hasGpuCompositionDoneInfo()) ||
        (outDisplayPresentTime && !events->hasDisplayPresentInfo()) ||
        (outDisplayRetireTime && !events->hasDisplayRetireInfo()) ||
        (outReleaseTime && !events->hasReleaseInfo())) {
        FrameEventHistoryDelta delta;
        FrameEventHistoryDelta delta;
        mGraphicBufferProducer->getFrameTimestamps(&delta);
        mGraphicBufferProducer->getFrameTimestamps(&delta);
        mFrameEventHistory.applyDelta(delta);
        mFrameEventHistory.applyDelta(delta);
        events = mFrameEventHistory.getFrame(frameNumber);
        events = mFrameEventHistory.getFrame(frameNumber);
    }
    }


    // A record for the requested frame does not exist.
    if (events == nullptr) {
    if (events == nullptr) {
        // The entry was available before the update, but was overwritten
        // after the update. Make sure not to send the wrong frame's data.
        return NAME_NOT_FOUND;
        return NAME_NOT_FOUND;
    }
    }


@@ -347,11 +372,9 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    nsecs_t now = systemTime();
    nsecs_t now = systemTime();


    FrameEventHistoryDelta frameTimestamps;
    FrameEventHistoryDelta frameTimestamps;
    FrameEventHistoryDelta* frameTimestampsOrNull =
            enableFrameTimestamps ? &frameTimestamps : nullptr;

    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
            reqWidth, reqHeight, reqFormat, reqUsage, frameTimestampsOrNull);
            reqWidth, reqHeight, reqFormat, reqUsage,
            enableFrameTimestamps ? &frameTimestamps : nullptr);
    mLastDequeueDuration = systemTime() - now;
    mLastDequeueDuration = systemTime() - now;


    if (result < 0) {
    if (result < 0) {
@@ -579,6 +602,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
        mFrameEventHistory.updateSignalTimes();
        mFrameEventHistory.updateSignalTimes();
    }
    }


    mLastFrameNumber = mNextFrameNumber;

    mDefaultWidth = output.width;
    mDefaultWidth = output.width;
    mDefaultHeight = output.height;
    mDefaultHeight = output.height;
    mNextFrameNumber = output.nextFrameNumber;
    mNextFrameNumber = output.nextFrameNumber;