From 23780be14df464f815d3fab7466d216cfbb2eae3 Mon Sep 17 00:00:00 2001 From: Pablo Gamito Date: Tue, 18 Apr 2023 08:30:00 +0000 Subject: Track transaction merges through transaction trace Bug: 233371599 Bug: 278663063 Test: dump a transaction trace and ensure transactions have the list of merged transaction ids in the proto Change-Id: I3edf8f1443a2573ef2086f221ceeef57172ecdbe --- libs/gui/SurfaceComposerClient.cpp | 41 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 1b13ec1c06..08a1a058e1 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -827,6 +827,15 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel SAFE_PARCEL(parcel->readUint64, &uncacheBuffers[i].id); } + count = static_cast(parcel->readUint32()); + if (count > parcel->dataSize()) { + return BAD_VALUE; + } + std::vector mergedTransactionIds(count); + for (size_t i = 0; i < count; i++) { + SAFE_PARCEL(parcel->readUint64, &mergedTransactionIds[i]); + } + // Parsing was successful. Update the object. mId = transactionId; mTransactionNestCount = transactionNestCount; @@ -842,6 +851,7 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel mInputWindowCommands = inputWindowCommands; mApplyToken = applyToken; mUncacheBuffers = std::move(uncacheBuffers); + mMergedTransactionIds = std::move(mergedTransactionIds); return NO_ERROR; } @@ -900,6 +910,11 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id); } + SAFE_PARCEL(parcel->writeUint32, static_cast(mMergedTransactionIds.size())); + for (auto mergedTransactionId : mMergedTransactionIds) { + SAFE_PARCEL(parcel->writeUint64, mergedTransactionId); + } + return NO_ERROR; } @@ -924,6 +939,22 @@ void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_ } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { + while (mMergedTransactionIds.size() + other.mMergedTransactionIds.size() > + MAX_MERGE_HISTORY_LENGTH - 1 && + mMergedTransactionIds.size() > 0) { + mMergedTransactionIds.pop_back(); + } + if (other.mMergedTransactionIds.size() == MAX_MERGE_HISTORY_LENGTH) { + mMergedTransactionIds.insert(mMergedTransactionIds.begin(), + other.mMergedTransactionIds.begin(), + other.mMergedTransactionIds.end() - 1); + } else if (other.mMergedTransactionIds.size() > 0u) { + mMergedTransactionIds.insert(mMergedTransactionIds.begin(), + other.mMergedTransactionIds.begin(), + other.mMergedTransactionIds.end()); + } + mMergedTransactionIds.insert(mMergedTransactionIds.begin(), other.mId); + for (auto const& [handle, composerState] : other.mComposerStates) { if (mComposerStates.count(handle) == 0) { mComposerStates[handle] = composerState; @@ -998,12 +1029,17 @@ void SurfaceComposerClient::Transaction::clear() { mIsAutoTimestamp = true; clearFrameTimelineInfo(mFrameTimelineInfo); mApplyToken = nullptr; + mMergedTransactionIds.clear(); } uint64_t SurfaceComposerClient::Transaction::getId() { return mId; } +std::vector SurfaceComposerClient::Transaction::getMergedTransactionIds() { + return mMergedTransactionIds; +} + void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { sp sf(ComposerService::getComposerService()); @@ -1014,7 +1050,7 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { status_t status = sf->setTransactionState(FrameTimelineInfo{}, composerStates, {}, ISurfaceComposer::eOneWay, Transaction::getDefaultApplyToken(), {}, systemTime(), - true, {uncacheBuffer}, false, {}, generateId()); + true, {uncacheBuffer}, false, {}, generateId(), {}); if (status != NO_ERROR) { ALOGE_AND_TRACE("SurfaceComposerClient::doUncacheBufferTransaction - %s", strerror(-status)); @@ -1189,7 +1225,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay sp sf(ComposerService::getComposerService()); sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken, mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp, - mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId); + mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId, + mMergedTransactionIds); mId = generateId(); // Clear the current states and flags -- cgit v1.2.3-59-g8ed1b