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

Commit 069b3651 authored by Brian Anderson's avatar Brian Anderson
Browse files

Add displayPresentTime to getFrameTimestamps

Makes HWC1 use displayRetireTime and HWC2 use
displayPresentTime.

Properly takes into account if HWC2On1Adapter is used.

Returns whether present or retire is supported via
eglQueryTimestampSupportedANDROID, which uses a
cached answer in Surface.

Surface::getFrameTimestamps returns with an error
if the caller requests an unsupported timestamp.

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

Change-Id: Ib91c2d05d7fb5cbf307e2dec1e20e79bcc19d90b
parent baaad32c
Loading
Loading
Loading
Loading
+18 −16
Original line number Diff line number Diff line
@@ -22,23 +22,25 @@

namespace android {

struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> {
    FrameTimestamps() :
        frameNumber(0),
        requestedPresentTime(0),
        acquireTime(0),
        refreshStartTime(0),
        glCompositionDoneTime(0),
        displayRetireTime(0),
        releaseTime(0) {}
enum class SupportableFrameTimestamps {
    REQUESTED_PRESENT,
    ACQUIRE,
    REFRESH_START,
    GL_COMPOSITION_DONE_TIME,
    DISPLAY_PRESENT_TIME,
    DISPLAY_RETIRE_TIME,
    RELEASE_TIME,
};

    uint64_t frameNumber;
    nsecs_t requestedPresentTime;
    nsecs_t acquireTime;
    nsecs_t refreshStartTime;
    nsecs_t glCompositionDoneTime;
    nsecs_t displayRetireTime;
    nsecs_t releaseTime;
struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> {
    uint64_t frameNumber{0};
    nsecs_t requestedPresentTime{0};
    nsecs_t acquireTime{0};
    nsecs_t refreshStartTime{0};
    nsecs_t glCompositionDoneTime{0};
    nsecs_t displayPresentTime{0};
    nsecs_t displayRetireTime{0};
    nsecs_t releaseTime{0};
};

} // namespace android
+9 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#include <gui/IGraphicBufferAlloc.h>
#include <gui/ISurfaceComposerClient.h>

#include <vector>

namespace android {
// ----------------------------------------------------------------------------

@@ -43,6 +45,7 @@ class HdrCapabilities;
class IDisplayEventConnection;
class IMemoryHeap;
class Rect;
enum class SupportableFrameTimestamps;

/*
 * This class defines the Binder IPC interface for accessing various
@@ -112,6 +115,11 @@ public:
    virtual bool authenticateSurfaceTexture(
            const sp<IGraphicBufferProducer>& surface) const = 0;

    /* Returns the frame timestamps supported by SurfaceFlinger.
     */
    virtual status_t getSupportedFrameTimestamps(
            std::vector<SupportableFrameTimestamps>* outSupported) const = 0;

    /* set display power mode. depending on the mode, it can either trigger
     * screen on, off or low power mode and wait for it to complete.
     * requires ACCESS_SURFACE_FLINGER permission.
@@ -193,6 +201,7 @@ public:
        GET_BUILT_IN_DISPLAY,
        SET_TRANSACTION_STATE,
        AUTHENTICATE_SURFACE,
        GET_SUPPORTED_FRAME_TIMESTAMPS,
        GET_DISPLAY_CONFIGS,
        GET_ACTIVE_CONFIG,
        SET_ACTIVE_CONFIG,
+10 −2
Original line number Diff line number Diff line
@@ -135,10 +135,11 @@ public:
            sp<Fence>* outFence, float outTransformMatrix[16]);

    // See IGraphicBufferProducer::getFrameTimestamps
    bool getFrameTimestamps(uint64_t frameNumber,
    status_t getFrameTimestamps(uint64_t frameNumber,
            nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime,
            nsecs_t* outRefreshStartTime, nsecs_t* outGlCompositionDoneTime,
            nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime);
            nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime,
            nsecs_t* outReleaseTime);

    status_t getUniqueId(uint64_t* outId) const;

@@ -238,6 +239,8 @@ protected:
    enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };

private:
    void querySupportedTimestampsLocked() const;

    void freeAllBuffers();
    int getSlotFromBufferLocked(android_native_buffer_t* buffer) const;

@@ -380,6 +383,11 @@ private:
    Condition mQueueBufferCondition;

    uint64_t mNextFrameNumber;

    // Mutable because ANativeWindow::query needs this class const.
    mutable bool mQueriedSupportedTimestamps;
    mutable bool mFrameTimestampsSupportsPresent;
    mutable bool mFrameTimestampsSupportsRetire;
};

namespace view {
+63 −0
Original line number Diff line number Diff line
@@ -158,6 +158,50 @@ public:
        return result != 0;
    }

    virtual status_t getSupportedFrameTimestamps(
            std::vector<SupportableFrameTimestamps>* outSupported) const {
        if (!outSupported) {
            return UNEXPECTED_NULL;
        }
        outSupported->clear();

        Parcel data, reply;

        status_t err = data.writeInterfaceToken(
                ISurfaceComposer::getInterfaceDescriptor());
        if (err != NO_ERROR) {
            return err;
        }

        err = remote()->transact(
                BnSurfaceComposer::GET_SUPPORTED_FRAME_TIMESTAMPS,
                data, &reply);
        if (err != NO_ERROR) {
            return err;
        }

        int32_t result = 0;
        err = reply.readInt32(&result);
        if (err != NO_ERROR) {
            return err;
        }
        if (result != NO_ERROR) {
            return result;
        }

        std::vector<int32_t> supported;
        err = reply.readInt32Vector(&supported);
        if (err != NO_ERROR) {
            return err;
        }

        outSupported->reserve(supported.size());
        for (int32_t s : supported) {
            outSupported->push_back(static_cast<SupportableFrameTimestamps>(s));
        }
        return NO_ERROR;
    }

    virtual sp<IDisplayEventConnection> createDisplayEventConnection()
    {
        Parcel data, reply;
@@ -520,6 +564,25 @@ status_t BnSurfaceComposer::onTransact(
            reply->writeInt32(result);
            return NO_ERROR;
        }
        case GET_SUPPORTED_FRAME_TIMESTAMPS: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            std::vector<SupportableFrameTimestamps> supportedTimestamps;
            status_t result = getSupportedFrameTimestamps(&supportedTimestamps);
            status_t err = reply->writeInt32(result);
            if (err != NO_ERROR) {
                return err;
            }
            if (result != NO_ERROR) {
                return result;
            }

            std::vector<int32_t> supported;
            supported.reserve(supportedTimestamps.size());
            for (SupportableFrameTimestamps s : supportedTimestamps) {
                supported.push_back(static_cast<int32_t>(s));
            }
            return reply->writeInt32Vector(supported);
        }
        case CREATE_DISPLAY_EVENT_CONNECTION: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IDisplayEventConnection> connection(createDisplayEventConnection());
+87 −27
Original line number Diff line number Diff line
@@ -49,7 +49,10 @@ Surface::Surface(
      mAutoRefresh(false),
      mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
      mSharedBufferHasBeenQueued(false),
      mNextFrameNumber(1)
      mNextFrameNumber(1),
      mQueriedSupportedTimestamps(false),
      mFrameTimestampsSupportsPresent(false),
      mFrameTimestampsSupportsRetire(false)
{
    // Initialize the ANativeWindow function pointers.
    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
@@ -135,16 +138,34 @@ status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
            outTransformMatrix);
}

bool Surface::getFrameTimestamps(uint64_t frameNumber,
status_t Surface::getFrameTimestamps(uint64_t frameNumber,
        nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime,
        nsecs_t* outRefreshStartTime, nsecs_t* outGlCompositionDoneTime,
        nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime) {
        nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime,
        nsecs_t* outReleaseTime) {
    ATRACE_CALL();

    {
        Mutex::Autolock lock(mMutex);

        // Verify the requested timestamps are supported.
        querySupportedTimestampsLocked();
        if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) {
            return BAD_VALUE;
        }
        if (outDisplayRetireTime != nullptr && !mFrameTimestampsSupportsRetire) {
            return BAD_VALUE;
        }
    }

    FrameTimestamps timestamps;
    bool found = mGraphicBufferProducer->getFrameTimestamps(frameNumber,
            &timestamps);
    if (found) {

    if (!found) {
        return NAME_NOT_FOUND;
    }

    if (outRequestedPresentTime) {
        *outRequestedPresentTime = timestamps.requestedPresentTime;
    }
@@ -157,15 +178,17 @@ bool Surface::getFrameTimestamps(uint64_t frameNumber,
    if (outGlCompositionDoneTime) {
        *outGlCompositionDoneTime = timestamps.glCompositionDoneTime;
    }
    if (outDisplayPresentTime) {
        *outDisplayPresentTime = timestamps.displayPresentTime;
    }
    if (outDisplayRetireTime) {
        *outDisplayRetireTime = timestamps.displayRetireTime;
    }
    if (outReleaseTime) {
        *outReleaseTime = timestamps.releaseTime;
    }
        return true;
    }
    return false;

    return NO_ERROR;
}

int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
@@ -533,6 +556,32 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    return err;
}

void Surface::querySupportedTimestampsLocked() const {
    // mMutex must be locked when calling this method.

    if (mQueriedSupportedTimestamps) {
        return;
    }
    mQueriedSupportedTimestamps = true;

    std::vector<SupportableFrameTimestamps> supportedFrameTimestamps;
    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
    status_t err = composer->getSupportedFrameTimestamps(
            &supportedFrameTimestamps);

    if (err != NO_ERROR) {
        return;
    }

    for (auto sft : supportedFrameTimestamps) {
        if (sft == SupportableFrameTimestamps::DISPLAY_PRESENT_TIME) {
            mFrameTimestampsSupportsPresent = true;
        } else if (sft == SupportableFrameTimestamps::DISPLAY_RETIRE_TIME) {
            mFrameTimestampsSupportsRetire = true;
        }
    }
}

int Surface::query(int what, int* value) const {
    ATRACE_CALL();
    ALOGV("Surface::query");
@@ -595,6 +644,16 @@ int Surface::query(int what, int* value) const {
                        static_cast<int>(durationUs);
                return NO_ERROR;
            }
            case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: {
                querySupportedTimestampsLocked();
                *value = mFrameTimestampsSupportsPresent ? 1 : 0;
                return NO_ERROR;
            }
            case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_RETIRE: {
                querySupportedTimestampsLocked();
                *value = mFrameTimestampsSupportsRetire ? 1 : 0;
                return NO_ERROR;
            }
        }
    }
    return mGraphicBufferProducer->query(what, value);
@@ -799,12 +858,13 @@ int Surface::dispatchGetFrameTimestamps(va_list args) {
    nsecs_t* outAcquireTime = va_arg(args, int64_t*);
    nsecs_t* outRefreshStartTime = va_arg(args, int64_t*);
    nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*);
    nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*);
    nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*);
    nsecs_t* outReleaseTime = va_arg(args, int64_t*);
    bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo,
    return getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo,
            outRequestedPresentTime, outAcquireTime, outRefreshStartTime,
            outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime);
    return ret ? NO_ERROR : BAD_VALUE;
            outGlCompositionDoneTime, outDisplayPresentTime,
            outDisplayRetireTime, outReleaseTime);
}

int Surface::connect(int api) {
Loading