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

Commit 22c7b5c7 authored by Ady Abraham's avatar Ady Abraham
Browse files

SurfaceFlinger: add transactions to FrameTimeline

Allow transaction clients to specify the vsyncId that started the
transaction and plumb this data to FrameTimeline to be able
to track jank associated with transactions

Bug: 166302754
Test: manually see transactions in frame timeline

Change-Id: Id05e0d0a73039204943d93b666cb67e3e7515a69
parent 384914ae
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -69,14 +69,15 @@ public:
    }

    virtual status_t setTransactionState(
            const Vector<ComposerState>& state, const Vector<DisplayState>& displays,
            uint32_t flags, const sp<IBinder>& applyToken, const InputWindowCommands& commands,
            int64_t desiredPresentTime, const client_cache_t& uncacheBuffer,
            bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
            uint64_t transactionId) {
            int64_t frameTimelineVsyncId, const Vector<ComposerState>& state,
            const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
            const InputWindowCommands& commands, int64_t desiredPresentTime,
            const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
            const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());

        SAFE_PARCEL(data.writeInt64, frameTimelineVsyncId);
        SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(state.size()));
        for (const auto& s : state) {
            SAFE_PARCEL(s.write, data);
@@ -1234,6 +1235,8 @@ status_t BnSurfaceComposer::onTransact(
        case SET_TRANSACTION_STATE: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);

            int64_t frameTimelineVsyncId;
            SAFE_PARCEL(data.readInt64, &frameTimelineVsyncId);
            uint32_t count = 0;
            SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
            Vector<ComposerState> state;
@@ -1285,9 +1288,10 @@ status_t BnSurfaceComposer::onTransact(
            uint64_t transactionId = -1;
            SAFE_PARCEL(data.readUint64, &transactionId);

            return setTransactionState(state, displays, stateFlags, applyToken, inputWindowCommands,
                                       desiredPresentTime, uncachedBuffer, hasListenerCallbacks,
                                       listenerCallbacks, transactionId);
            return setTransactionState(frameTimelineVsyncId, state, displays, stateFlags,
                                       applyToken, inputWindowCommands, desiredPresentTime,
                                       uncachedBuffer, hasListenerCallbacks, listenerCallbacks,
                                       transactionId);
        }
        case BOOT_FINISHED: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+25 −5
Original line number Diff line number Diff line
@@ -365,7 +365,8 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other)
        mExplicitEarlyWakeupStart(other.mExplicitEarlyWakeupStart),
        mExplicitEarlyWakeupEnd(other.mExplicitEarlyWakeupEnd),
        mContainsBuffer(other.mContainsBuffer),
        mDesiredPresentTime(other.mDesiredPresentTime) {
        mDesiredPresentTime(other.mDesiredPresentTime),
        mFrameTimelineVsyncId(other.mFrameTimelineVsyncId) {
    mDisplayStates = other.mDisplayStates;
    mComposerStates = other.mComposerStates;
    mInputWindowCommands = other.mInputWindowCommands;
@@ -394,6 +395,7 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel
    const bool explicitEarlyWakeupEnd = parcel->readBool();
    const bool containsBuffer = parcel->readBool();
    const int64_t desiredPresentTime = parcel->readInt64();
    const int64_t frameTimelineVsyncId = parcel->readInt64();

    size_t count = static_cast<size_t>(parcel->readUint32());
    if (count > parcel->dataSize()) {
@@ -464,6 +466,7 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel
    mExplicitEarlyWakeupEnd = explicitEarlyWakeupEnd;
    mContainsBuffer = containsBuffer;
    mDesiredPresentTime = desiredPresentTime;
    mFrameTimelineVsyncId = frameTimelineVsyncId;
    mDisplayStates = displayStates;
    mListenerCallbacks = listenerCallbacks;
    mComposerStates = composerStates;
@@ -493,6 +496,7 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const
    parcel->writeBool(mExplicitEarlyWakeupEnd);
    parcel->writeBool(mContainsBuffer);
    parcel->writeInt64(mDesiredPresentTime);
    parcel->writeInt64(mFrameTimelineVsyncId);
    parcel->writeUint32(static_cast<uint32_t>(mDisplayStates.size()));
    for (auto const& displayState : mDisplayStates) {
        displayState.write(*parcel);
@@ -568,6 +572,15 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr
    mEarlyWakeup = mEarlyWakeup || other.mEarlyWakeup;
    mExplicitEarlyWakeupStart = mExplicitEarlyWakeupStart || other.mExplicitEarlyWakeupStart;
    mExplicitEarlyWakeupEnd = mExplicitEarlyWakeupEnd || other.mExplicitEarlyWakeupEnd;

    // When merging vsync Ids we take the oldest one
    if (mFrameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID &&
        other.mFrameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) {
        mFrameTimelineVsyncId = std::max(mFrameTimelineVsyncId, other.mFrameTimelineVsyncId);
    } else if (mFrameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID) {
        mFrameTimelineVsyncId = other.mFrameTimelineVsyncId;
    }

    other.clear();
    return *this;
}
@@ -585,6 +598,7 @@ void SurfaceComposerClient::Transaction::clear() {
    mExplicitEarlyWakeupStart = false;
    mExplicitEarlyWakeupEnd = false;
    mDesiredPresentTime = -1;
    mFrameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
}

void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
@@ -595,8 +609,8 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
    uncacheBuffer.id = cacheId;

    sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
    sf->setTransactionState({}, {}, 0, applyToken, {}, -1, uncacheBuffer, false, {},
                            0 /* Undefined transactionId */);
    sf->setTransactionState(ISurfaceComposer::INVALID_VSYNC_ID, {}, {}, 0, applyToken, {}, -1,
                            uncacheBuffer, false, {}, 0 /* Undefined transactionId */);
}

void SurfaceComposerClient::Transaction::cacheBuffers() {
@@ -727,8 +741,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
    mId = generateId();

    sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
    sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands,
                            mDesiredPresentTime,
    sf->setTransactionState(mFrameTimelineVsyncId, composerStates, displayStates, flags, applyToken,
                            mInputWindowCommands, mDesiredPresentTime,
                            {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
                            hasListenerCallbacks, listenerCallbacks, transactionId);
    mInputWindowCommands.clear();
@@ -1517,6 +1531,12 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed
    return *this;
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineVsync(
        int64_t frameTimelineVsyncId) {
    mFrameTimelineVsyncId = frameTimelineVsyncId;
    return *this;
}

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

DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
+5 −2
Original line number Diff line number Diff line
@@ -109,6 +109,9 @@ public:

    enum ConfigChanged { eConfigChangedSuppress = 0, eConfigChangedDispatch = 1 };

    // Needs to be in sync with android.graphics.FrameInfo.INVALID_VSYNC_ID in java
    static constexpr int64_t INVALID_VSYNC_ID = -1;

    /*
     * Create a connection with SurfaceFlinger.
     */
@@ -153,8 +156,8 @@ public:

    /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
    virtual status_t setTransactionState(
            const Vector<ComposerState>& state, const Vector<DisplayState>& displays,
            uint32_t flags, const sp<IBinder>& applyToken,
            int64_t frameTimelineVsyncId, const Vector<ComposerState>& state,
            const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
            const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
            const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
            const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) = 0;
+7 −0
Original line number Diff line number Diff line
@@ -373,6 +373,9 @@ public:
        // The desired present time does not affect this ordering.
        int64_t mDesiredPresentTime = -1;

        // The vsync Id provided by Choreographer.getVsyncId
        int64_t mFrameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;

        InputWindowCommands mInputWindowCommands;
        int mStatus = NO_ERROR;

@@ -538,6 +541,10 @@ public:
        // a buffer of a different size.
        Transaction& setFixedTransformHint(const sp<SurfaceControl>& sc, int32_t transformHint);

        // Sets the frame timeline vsync id received from choreographer that corresponds
        // to the transaction.
        Transaction& setFrameTimelineVsync(int64_t frameTimelineVsyncId);

        status_t setDisplaySurface(const sp<IBinder>& token,
                const sp<IGraphicBufferProducer>& bufferProducer);

+2 −1
Original line number Diff line number Diff line
@@ -695,7 +695,8 @@ public:
    void destroyDisplay(const sp<IBinder>& /*display */) override {}
    std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override { return {}; }
    sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId) const override { return nullptr; }
    status_t setTransactionState(const Vector<ComposerState>& /*state*/,
    status_t setTransactionState(int64_t /*frameTimelineVsyncId*/,
                                 const Vector<ComposerState>& /*state*/,
                                 const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
                                 const sp<IBinder>& /*applyToken*/,
                                 const InputWindowCommands& /*inputWindowCommands*/,
Loading