Merge "SurfaceFlinger: add transactions to FrameTimeline"
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 2f113ee..964195d 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -69,14 +69,15 @@
}
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 @@
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 @@
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);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index ca98843..2f6a34b 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -365,7 +365,8 @@
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 @@
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()) {
@@ -466,6 +468,7 @@
mExplicitEarlyWakeupEnd = explicitEarlyWakeupEnd;
mContainsBuffer = containsBuffer;
mDesiredPresentTime = desiredPresentTime;
+ mFrameTimelineVsyncId = frameTimelineVsyncId;
mDisplayStates = displayStates;
mListenerCallbacks = listenerCallbacks;
mComposerStates = composerStates;
@@ -495,6 +498,7 @@
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);
@@ -570,6 +574,15 @@
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;
}
@@ -587,6 +600,7 @@
mExplicitEarlyWakeupStart = false;
mExplicitEarlyWakeupEnd = false;
mDesiredPresentTime = -1;
+ mFrameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
}
void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
@@ -597,8 +611,8 @@
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() {
@@ -729,8 +743,8 @@
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();
@@ -1538,6 +1552,12 @@
return *this;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineVsync(
+ int64_t frameTimelineVsyncId) {
+ mFrameTimelineVsyncId = frameTimelineVsyncId;
+ return *this;
+}
+
// ---------------------------------------------------------------------------
DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 3e3570d..a416147 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -109,6 +109,9 @@
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 @@
/* 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;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index a04fbc1..cc82502 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -373,6 +373,9 @@
// 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;
@@ -537,6 +540,10 @@
// 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);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index b72c6b4..5a376da 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -695,7 +695,8 @@
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*/,
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 33126ab..a574549 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -381,6 +381,10 @@
return NO_ERROR;
}
+void BufferQueueLayer::setFrameTimelineVsyncForBuffer(int64_t frameTimelineVsyncId) {
+ mFrameTimelineVsyncId = frameTimelineVsyncId;
+}
+
// -----------------------------------------------------------------------
// Interface implementation for BufferLayerConsumer::ContentsChangedListener
// -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index fc992f7..fb8a0c2 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -103,6 +103,7 @@
status_t updateActiveBuffer() override;
status_t updateFrameNumber(nsecs_t latchTime) override;
+ void setFrameTimelineVsyncForBuffer(int64_t frameTimelineVsyncId) override;
sp<Layer> createClone() override;
@@ -146,6 +147,11 @@
std::atomic<bool> mSidebandStreamChanged{false};
sp<ContentsChangedListener> mContentsChangedListener;
+
+ // The last vsync id received on this layer. This will be used when we get
+ // a buffer to correlate the buffer with the vsync id. Can only be accessed
+ // with the SF state lock held.
+ std::optional<int64_t> mFrameTimelineVsyncId;
};
} // namespace android
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 9f99fee..2033f8e 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -161,6 +161,10 @@
bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
mCurrentStateModified = mCurrentState.modified;
bool stateUpdateAvailable = Layer::applyPendingStates(stateToCommit);
+ if (stateUpdateAvailable && mCallbackHandleAcquireTime != -1) {
+ // Update the actual end time if we have a buffer
+ mSurfaceFrame->setActualEndTime(mCallbackHandleAcquireTime);
+ }
mCurrentStateModified = stateUpdateAvailable && mCurrentStateModified;
mCurrentState.modified = false;
return stateUpdateAvailable;
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
index a42c32c..2ca1e23 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -19,6 +19,7 @@
#include <deque>
#include <mutex>
+#include <gui/ISurfaceComposer.h>
#include <ui/FenceTime.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
@@ -128,7 +129,7 @@
class TokenManager : public android::frametimeline::TokenManager {
public:
- TokenManager() : mCurrentToken(0) {}
+ TokenManager() : mCurrentToken(ISurfaceComposer::INVALID_VSYNC_ID + 1) {}
~TokenManager() = default;
int64_t generateTokenForPredictions(TimelineItem&& predictions) override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 58291d4..df2ef80 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -62,6 +62,7 @@
#include "DisplayDevice.h"
#include "DisplayHardware/HWComposer.h"
#include "EffectLayer.h"
+#include "FrameTimeline.h"
#include "FrameTracer/FrameTracer.h"
#include "LayerProtoHelper.h"
#include "LayerRejecter.h"
@@ -76,6 +77,7 @@
using base::StringAppendF;
using namespace android::flag_operators;
+using PresentState = frametimeline::SurfaceFrame::PresentState;
std::atomic<int32_t> Layer::sSequence{1};
@@ -124,6 +126,8 @@
mCurrentState.shadowRadius = 0.f;
mCurrentState.treeHasFrameRateVote = false;
mCurrentState.fixedTransformHint = ui::Transform::ROT_INVALID;
+ mCurrentState.frameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
+ mCurrentState.postTime = -1;
if (args.flags & ISurfaceComposerClient::eNoColorFill) {
// Set an invalid color so there is no color fill.
@@ -823,8 +827,8 @@
void Layer::popPendingState(State* stateToCommit) {
ATRACE_CALL();
- *stateToCommit = mPendingStates[0];
+ *stateToCommit = mPendingStates[0];
mPendingStates.removeAt(0);
ATRACE_INT(mTransactionName.c_str(), mPendingStates.size());
}
@@ -881,6 +885,20 @@
mFlinger->setTraversalNeeded();
}
+ if (stateUpdateAvailable) {
+ const auto vsyncId =
+ stateToCommit->frameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID
+ ? std::nullopt
+ : std::make_optional(stateToCommit->frameTimelineVsyncId);
+
+ auto surfaceFrame =
+ mFlinger->mFrameTimeline->createSurfaceFrameForToken(mTransactionName, vsyncId);
+ surfaceFrame->setActualQueueTime(stateToCommit->postTime);
+ surfaceFrame->setActualEndTime(stateToCommit->postTime);
+
+ mSurfaceFrame = std::move(surfaceFrame);
+ }
+
mCurrentState.modified = false;
return stateUpdateAvailable;
}
@@ -1018,6 +1036,7 @@
void Layer::commitTransaction(const State& stateToCommit) {
mDrawingState = stateToCommit;
+ mFlinger->mFrameTimeline->addSurfaceFrame(std::move(mSurfaceFrame), PresentState::Presented);
}
uint32_t Layer::getTransactionFlags(uint32_t flags) {
@@ -1434,8 +1453,12 @@
return true;
}
-void Layer::setFrameTimelineVsync(int64_t frameTimelineVsyncId) {
- mFrameTimelineVsyncId = frameTimelineVsyncId;
+void Layer::setFrameTimelineVsyncForTransaction(int64_t frameTimelineVsyncId, nsecs_t postTime) {
+ mCurrentState.sequence++;
+ mCurrentState.frameTimelineVsyncId = frameTimelineVsyncId;
+ mCurrentState.postTime = postTime;
+ mCurrentState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
}
Layer::FrameRate Layer::getFrameRateForLayerTree() const {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index bdc4f84..02593d5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -71,6 +71,10 @@
class SurfaceInterceptor;
}
+namespace frametimeline {
+class SurfaceFrame;
+} // namespace frametimeline
+
struct LayerCreationArgs {
LayerCreationArgs(SurfaceFlinger*, sp<Client>, std::string name, uint32_t w, uint32_t h,
uint32_t flags, LayerMetadata);
@@ -267,6 +271,12 @@
// a buffer of a different size. ui::Transform::ROT_INVALID means the
// a fixed transform hint is not set.
ui::Transform::RotationFlags fixedTransformHint;
+
+ // The vsync id that was used to start the transaction
+ int64_t frameTimelineVsyncId;
+
+ // When the transaction was posted
+ nsecs_t postTime;
};
/*
@@ -823,7 +833,8 @@
bool setFrameRate(FrameRate);
- void setFrameTimelineVsync(int64_t frameTimelineVsyncId);
+ virtual void setFrameTimelineVsyncForBuffer(int64_t /*frameTimelineVsyncId*/) {}
+ void setFrameTimelineVsyncForTransaction(int64_t frameTimelineVsyncId, nsecs_t postTime);
// Creates a new handle each time, so we only expect
// this to be called once.
@@ -1023,12 +1034,12 @@
// Can only be accessed with the SF state lock held.
bool mChildrenChanged{false};
- // Can only be accessed with the SF state lock held.
- std::optional<int64_t> mFrameTimelineVsyncId;
-
// Window types from WindowManager.LayoutParams
const InputWindowInfo::Type mWindowType;
+ // Can only be accessed with the SF state lock held.
+ std::unique_ptr<frametimeline::SurfaceFrame> mSurfaceFrame;
+
private:
virtual void setTransformHint(ui::Transform::RotationFlags) {}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 83fa8ec..152d872 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3195,7 +3195,8 @@
break;
}
transactions.push_back(transaction);
- applyTransactionState(transaction.states, transaction.displays, transaction.flags,
+ applyTransactionState(transaction.frameTimelineVsyncId, transaction.states,
+ transaction.displays, transaction.flags,
mPendingInputWindowCommands, transaction.desiredPresentTime,
transaction.buffer, transaction.postTime,
transaction.privileged, transaction.hasListenerCallbacks,
@@ -3245,9 +3246,10 @@
}
status_t SurfaceFlinger::setTransactionState(
- const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands,
- int64_t desiredPresentTime, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
+ int64_t frameTimelineVsyncId, const Vector<ComposerState>& states,
+ 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) {
ATRACE_CALL();
@@ -3285,22 +3287,24 @@
const int originUid = ipc->getCallingUid();
if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states)) {
- mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
- uncacheBuffer, postTime, privileged,
- hasListenerCallbacks, listenerCallbacks, originPid,
- originUid, transactionId);
+ mTransactionQueues[applyToken].emplace(frameTimelineVsyncId, states, displays, flags,
+ desiredPresentTime, uncacheBuffer, postTime,
+ privileged, hasListenerCallbacks, listenerCallbacks,
+ originPid, originUid, transactionId);
setTransactionFlags(eTransactionFlushNeeded);
return NO_ERROR;
}
- applyTransactionState(states, displays, flags, inputWindowCommands, desiredPresentTime,
- uncacheBuffer, postTime, privileged, hasListenerCallbacks,
- listenerCallbacks, originPid, originUid, /*isMainThread*/ false);
+ applyTransactionState(frameTimelineVsyncId, states, displays, flags, inputWindowCommands,
+ desiredPresentTime, uncacheBuffer, postTime, privileged,
+ hasListenerCallbacks, listenerCallbacks, originPid, originUid,
+ /*isMainThread*/ false);
return NO_ERROR;
}
void SurfaceFlinger::applyTransactionState(
- const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags,
+ int64_t frameTimelineVsyncId, const Vector<ComposerState>& states,
+ const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
const client_cache_t& uncacheBuffer, const int64_t postTime, bool privileged,
bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
@@ -3338,8 +3342,9 @@
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash> listenerCallbacksWithSurfaces;
uint32_t clientStateFlags = 0;
for (const ComposerState& state : states) {
- clientStateFlags |= setClientStateLocked(state, desiredPresentTime, postTime, privileged,
- listenerCallbacksWithSurfaces);
+ clientStateFlags |=
+ setClientStateLocked(frameTimelineVsyncId, state, desiredPresentTime, postTime,
+ privileged, listenerCallbacksWithSurfaces);
if ((flags & eAnimation) && state.state.surface) {
if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) {
mScheduler->recordLayerHistory(layer.get(), desiredPresentTime,
@@ -3516,8 +3521,8 @@
}
uint32_t SurfaceFlinger::setClientStateLocked(
- const ComposerState& composerState, int64_t desiredPresentTime, int64_t postTime,
- bool privileged,
+ int64_t frameTimelineVsyncId, const ComposerState& composerState,
+ int64_t desiredPresentTime, int64_t postTime, bool privileged,
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks) {
const layer_state_t& s = composerState.state;
@@ -3828,6 +3833,9 @@
flags |= eTraversalNeeded;
}
}
+
+ layer->setFrameTimelineVsyncForTransaction(frameTimelineVsyncId, postTime);
+
if (layer->setTransactionCompletedListeners(callbackHandles)) flags |= eTraversalNeeded;
// Do not put anything that updates layer state or modifies flags after
// setTransactionCompletedListener
@@ -4094,7 +4102,8 @@
d.width = 0;
d.height = 0;
displays.add(d);
- setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1, {}, false, {},
+ setTransactionState(ISurfaceComposer::INVALID_VSYNC_ID, state, displays, 0, nullptr,
+ mPendingInputWindowCommands, -1, {}, false, {},
0 /* Undefined transactionId */);
setPowerModeInternal(display, hal::PowerMode::ON);
@@ -6200,7 +6209,7 @@
return BAD_VALUE;
}
- layer->setFrameTimelineVsync(frameTimelineVsyncId);
+ layer->setFrameTimelineVsyncForBuffer(frameTimelineVsyncId);
return NO_ERROR;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b991b61..9a552d8 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -339,8 +339,8 @@
virtual ~SurfaceFlinger();
virtual uint32_t setClientStateLocked(
- const ComposerState& composerState, int64_t desiredPresentTime, int64_t postTime,
- bool privileged,
+ int64_t frameTimelineVsyncId, const ComposerState& composerState,
+ int64_t desiredPresentTime, int64_t postTime, bool privileged,
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks)
REQUIRES(mStateLock);
virtual void commitTransactionLocked();
@@ -431,13 +431,14 @@
};
struct TransactionState {
- TransactionState(const Vector<ComposerState>& composerStates,
+ TransactionState(int64_t frameTimelineVsyncId, const Vector<ComposerState>& composerStates,
const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
int64_t desiredPresentTime, const client_cache_t& uncacheBuffer,
int64_t postTime, bool privileged, bool hasListenerCallbacks,
std::vector<ListenerCallbacks> listenerCallbacks, int originPid,
int originUid, uint64_t transactionId)
- : states(composerStates),
+ : frameTimelineVsyncId(frameTimelineVsyncId),
+ states(composerStates),
displays(displayStates),
flags(transactionFlags),
desiredPresentTime(desiredPresentTime),
@@ -450,6 +451,7 @@
originUid(originUid),
id(transactionId) {}
+ int64_t frameTimelineVsyncId;
Vector<ComposerState> states;
Vector<DisplayState> displays;
uint32_t flags;
@@ -510,7 +512,7 @@
void destroyDisplay(const sp<IBinder>& displayToken) override;
std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override;
sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override;
- 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,
@@ -710,7 +712,7 @@
/*
* Transactions
*/
- void applyTransactionState(const Vector<ComposerState>& state,
+ void applyTransactionState(int64_t frameTimelineVsyncId, const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime,
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
index 409f90d..2c8178e 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -118,7 +118,11 @@
}
void RefreshRateSelectionTest::commitTransaction(Layer* layer) {
- layer->commitTransaction(layer->getCurrentState());
+ layer->pushPendingState();
+ auto c = layer->getCurrentState();
+ if (layer->applyPendingStates(&c)) {
+ layer->commitTransaction(c);
+ }
}
void RefreshRateSelectionTest::setupScheduler() {
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index d4591fc..efee826 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -157,7 +157,11 @@
void SetFrameRateTest::commitTransaction() {
for (auto layer : mLayers) {
- layer.get()->commitTransaction(layer.get()->getCurrentState());
+ layer->pushPendingState();
+ auto c = layer->getCurrentState();
+ if (layer->applyPendingStates(&c)) {
+ layer->commitTransaction(c);
+ }
}
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 37f159c..8c12e94 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -348,7 +348,7 @@
auto& getTransactionQueue() { return mFlinger->mTransactionQueues; }
- auto setTransactionState(const Vector<ComposerState>& states,
+ auto setTransactionState(int64_t frameTimelineVsyncId, const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands,
@@ -356,9 +356,9 @@
bool hasListenerCallbacks,
std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) {
- return mFlinger->setTransactionState(states, displays, flags, applyToken,
- inputWindowCommands, desiredPresentTime, uncacheBuffer,
- hasListenerCallbacks, listenerCallbacks,
+ return mFlinger->setTransactionState(frameTimelineVsyncId, states, displays, flags,
+ applyToken, inputWindowCommands, desiredPresentTime,
+ uncacheBuffer, hasListenerCallbacks, listenerCallbacks,
transactionId);
}
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 7151a52..760bf65 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -100,6 +100,7 @@
sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
InputWindowCommands inputWindowCommands;
int64_t desiredPresentTime = -1;
+ int64_t frameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
client_cache_t uncacheBuffer;
int64_t id = -1;
};
@@ -115,11 +116,12 @@
}
void setupSingle(TransactionInfo& transaction, uint32_t flags, bool syncInputWindows,
- int64_t desiredPresentTime) {
+ int64_t desiredPresentTime, int64_t frameTimelineVsyncId) {
mTransactionNumber++;
transaction.flags |= flags; // ISurfaceComposer::eSynchronous;
transaction.inputWindowCommands.syncInputWindows = syncInputWindows;
transaction.desiredPresentTime = desiredPresentTime;
+ transaction.frameTimelineVsyncId = frameTimelineVsyncId;
}
void NotPlacedOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
@@ -129,9 +131,10 @@
EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillOnce(Return(systemTime()));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
- /*desiredPresentTime*/ -1);
+ /*desiredPresentTime*/ -1, ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationTime = systemTime();
- mFlinger.setTransactionState(transaction.states, transaction.displays, transaction.flags,
+ mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states,
+ transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
transaction.desiredPresentTime, transaction.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transaction.id);
@@ -163,9 +166,10 @@
.WillOnce(Return(time + nsecs_t(5 * 1e8)));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
- /*desiredPresentTime*/ time + s2ns(1));
+ /*desiredPresentTime*/ time + s2ns(1), ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationSentTime = systemTime();
- mFlinger.setTransactionState(transaction.states, transaction.displays, transaction.flags,
+ mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states,
+ transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
transaction.desiredPresentTime, transaction.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transaction.id);
@@ -187,16 +191,17 @@
// transaction that should go on the pending thread
TransactionInfo transactionA;
setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
- /*desiredPresentTime*/ time + s2ns(1));
+ /*desiredPresentTime*/ time + s2ns(1), ISurfaceComposer::INVALID_VSYNC_ID);
// transaction that would not have gone on the pending thread if not
// blocked
TransactionInfo transactionB;
setupSingle(transactionB, flags, syncInputWindows,
- /*desiredPresentTime*/ -1);
+ /*desiredPresentTime*/ -1, ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationSentTime = systemTime();
- mFlinger.setTransactionState(transactionA.states, transactionA.displays, transactionA.flags,
+ mFlinger.setTransactionState(transactionA.frameTimelineVsyncId, transactionA.states,
+ transactionA.displays, transactionA.flags,
transactionA.applyToken, transactionA.inputWindowCommands,
transactionA.desiredPresentTime, transactionA.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transactionA.id);
@@ -207,7 +212,8 @@
EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
applicationSentTime = systemTime();
- mFlinger.setTransactionState(transactionB.states, transactionB.displays, transactionB.flags,
+ mFlinger.setTransactionState(transactionB.frameTimelineVsyncId, transactionB.states,
+ transactionB.displays, transactionB.flags,
transactionB.applyToken, transactionB.inputWindowCommands,
transactionB.desiredPresentTime, transactionB.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transactionB.id);
@@ -252,11 +258,12 @@
.WillOnce(Return(s2ns(2)));
TransactionInfo transactionA; // transaction to go on pending queue
setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
- /*desiredPresentTime*/ s2ns(1));
- mFlinger.setTransactionState(transactionA.states, transactionA.displays, transactionA.flags,
- transactionA.applyToken, transactionA.inputWindowCommands,
- transactionA.desiredPresentTime, transactionA.uncacheBuffer,
- mHasListenerCallbacks, mCallbacks, transactionA.id);
+ /*desiredPresentTime*/ s2ns(1), ISurfaceComposer::INVALID_VSYNC_ID);
+ mFlinger.setTransactionState(transactionA.frameTimelineVsyncId, transactionA.states,
+ transactionA.displays, transactionA.flags, transactionA.applyToken,
+ transactionA.inputWindowCommands, transactionA.desiredPresentTime,
+ transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transactionA.id);
auto& transactionQueue = mFlinger.getTransactionQueue();
ASSERT_EQ(1, transactionQueue.size());
@@ -272,9 +279,10 @@
// different process) to re-query and reset the cached expected present time
TransactionInfo empty;
empty.applyToken = sp<IBinder>();
- mFlinger.setTransactionState(empty.states, empty.displays, empty.flags, empty.applyToken,
- empty.inputWindowCommands, empty.desiredPresentTime,
- empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
+ mFlinger.setTransactionState(empty.frameTimelineVsyncId, empty.states, empty.displays,
+ empty.flags, empty.applyToken, empty.inputWindowCommands,
+ empty.desiredPresentTime, empty.uncacheBuffer,
+ mHasListenerCallbacks, mCallbacks, empty.id);
// flush transaction queue should flush as desiredPresentTime has
// passed