Start removing Current state
Now that we only write to current state from the main thread
we can actually just write directly in to drawing state and
avoid copying current to drawing state on each frame. simpleperf
on bouncing ball indicates this was saving around 8% CPU or so
per frame. As a next target we will eliminate the remaining work
in doTransaction and eliminate the doTransaction pass.
Test: Existing tests pass. simpleperf
Bug: 186200583
Change-Id: I59b75747d7371b3ffe870129c8be100c7daa6c4e
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index f8af908..a3b7b13 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -65,7 +65,7 @@
BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
: BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) {
- mCurrentState.dataspace = ui::Dataspace::V0_SRGB;
+ mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
}
BufferStateLayer::~BufferStateLayer() {
@@ -257,8 +257,8 @@
bool BufferStateLayer::willPresentCurrentTransaction() const {
// Returns true if the most recent Transaction applied to CurrentState will be presented.
return (getSidebandStreamChanged() || getAutoRefresh() ||
- (mCurrentState.modified &&
- (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr)));
+ (mDrawingState.modified &&
+ (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr)));
}
Rect BufferStateLayer::getCrop(const Layer::State& s) const {
@@ -266,65 +266,72 @@
}
bool BufferStateLayer::setTransform(uint32_t transform) {
- if (mCurrentState.bufferTransform == transform) return false;
- mCurrentState.bufferTransform = transform;
- mCurrentState.modified = true;
+ if (mDrawingState.bufferTransform == transform) return false;
+ mDrawingState.bufferTransform = transform;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
- if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
- mCurrentState.sequence++;
- mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
- mCurrentState.modified = true;
+ if (mDrawingState.transformToDisplayInverse == transformToDisplayInverse) return false;
+ mDrawingState.sequence++;
+ mDrawingState.transformToDisplayInverse = transformToDisplayInverse;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setCrop(const Rect& crop) {
- if (mCurrentState.crop == crop) return false;
- mCurrentState.sequence++;
- mCurrentState.crop = crop;
+ if (mDrawingState.crop == crop) return false;
+ mDrawingState.sequence++;
+ mDrawingState.crop = crop;
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) {
- if (mCurrentState.bufferCrop == bufferCrop) return false;
+ if (mDrawingState.bufferCrop == bufferCrop) return false;
- mCurrentState.sequence++;
- mCurrentState.bufferCrop = bufferCrop;
+ mDrawingState.sequence++;
+ mDrawingState.bufferCrop = bufferCrop;
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setDestinationFrame(const Rect& destinationFrame) {
- if (mCurrentState.destinationFrame == destinationFrame) return false;
+ if (mDrawingState.destinationFrame == destinationFrame) return false;
- mCurrentState.sequence++;
- mCurrentState.destinationFrame = destinationFrame;
+ mDrawingState.sequence++;
+ mDrawingState.destinationFrame = destinationFrame;
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
+static bool assignTransform(ui::Transform* dst, ui::Transform& from) {
+ if (*dst == from) {
+ return false;
+ }
+ *dst = from;
+ return true;
+}
+
// Translate destination frame into scale and position. If a destination frame is not set, use the
// provided scale and position
-void BufferStateLayer::updateGeometry() {
- if (mCurrentState.destinationFrame.isEmpty()) {
+bool BufferStateLayer::updateGeometry() {
+ if (mDrawingState.destinationFrame.isEmpty()) {
// If destination frame is not set, use the requested transform set via
// BufferStateLayer::setPosition and BufferStateLayer::setMatrix.
- mCurrentState.transform = mRequestedTransform;
- return;
+ return assignTransform(&mDrawingState.transform, mRequestedTransform);
}
- Rect destRect = mCurrentState.destinationFrame;
+ Rect destRect = mDrawingState.destinationFrame;
int32_t destW = destRect.width();
int32_t destH = destRect.height();
if (destRect.left < 0) {
@@ -336,21 +343,20 @@
destRect.bottom = destH;
}
- if (!mCurrentState.buffer) {
+ if (!mDrawingState.buffer) {
ui::Transform t;
t.set(destRect.left, destRect.top);
- mCurrentState.transform = t;
- return;
+ return assignTransform(&mDrawingState.transform, t);
}
- uint32_t bufferWidth = mCurrentState.buffer->getBuffer()->getWidth();
- uint32_t bufferHeight = mCurrentState.buffer->getBuffer()->getHeight();
+ uint32_t bufferWidth = mDrawingState.buffer->getBuffer()->getWidth();
+ uint32_t bufferHeight = mDrawingState.buffer->getBuffer()->getHeight();
// Undo any transformations on the buffer.
- if (mCurrentState.bufferTransform & ui::Transform::ROT_90) {
+ if (mDrawingState.bufferTransform & ui::Transform::ROT_90) {
std::swap(bufferWidth, bufferHeight);
}
uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
- if (mCurrentState.transformToDisplayInverse) {
+ if (mDrawingState.transformToDisplayInverse) {
if (invTransform & ui::Transform::ROT_90) {
std::swap(bufferWidth, bufferHeight);
}
@@ -361,8 +367,7 @@
ui::Transform t;
t.set(sx, 0, 0, sy);
t.set(destRect.left, destRect.top);
- mCurrentState.transform = t;
- return;
+ return assignTransform(&mDrawingState.transform, t);
}
bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix,
@@ -383,8 +388,8 @@
mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -397,8 +402,8 @@
mRequestedTransform.set(x, y);
- mCurrentState.sequence++;
- mCurrentState.modified = true;
+ mDrawingState.sequence++;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -410,7 +415,7 @@
mAcquireTimeline.updateSignalTimes();
std::shared_ptr<FenceTime> acquireFenceTime =
std::make_shared<FenceTime>((acquireFence ? acquireFence : Fence::NO_FENCE));
- NewFrameEventsEntry newTimestamps = {mCurrentState.frameNumber, postedTime, desiredPresentTime,
+ NewFrameEventsEntry newTimestamps = {mDrawingState.frameNumber, postedTime, desiredPresentTime,
acquireFenceTime};
mFrameEventHistory.setProducerWantsEvents();
mFrameEventHistory.addQueue(newTimestamps);
@@ -425,38 +430,39 @@
const sp<ITransactionCompletedListener>& releaseBufferListener) {
ATRACE_CALL();
- if (mCurrentState.buffer) {
+ if (mDrawingState.buffer) {
mReleasePreviousBuffer = true;
- if (!mDrawingState.buffer ||
- mCurrentState.buffer->getBuffer() != mDrawingState.buffer->getBuffer()) {
- // If mCurrentState has a buffer, and we are about to update again
+ if (mDrawingState.buffer != mBufferInfo.mBuffer) {
+ // If mDrawingState has a buffer, and we are about to update again
// before swapping to drawing state, then the first buffer will be
// dropped and we should decrement the pending buffer count and
// call any release buffer callbacks if set.
- callReleaseBufferCallback(mCurrentState.releaseBufferListener,
- mCurrentState.buffer->getBuffer(), mCurrentState.acquireFence,
+ callReleaseBufferCallback(mDrawingState.releaseBufferListener,
+ mDrawingState.buffer->getBuffer(), mDrawingState.acquireFence,
mTransformHint,
mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
mOwnerUid));
decrementPendingBufferCount();
- if (mCurrentState.bufferSurfaceFrameTX != nullptr) {
- addSurfaceFrameDroppedForBuffer(mCurrentState.bufferSurfaceFrameTX);
- mCurrentState.bufferSurfaceFrameTX.reset();
+ if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
+ mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
+ addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX);
+ mDrawingState.bufferSurfaceFrameTX.reset();
}
}
}
- mCurrentState.frameNumber = frameNumber;
- mCurrentState.releaseBufferListener = releaseBufferListener;
- mCurrentState.buffer = buffer;
- mCurrentState.clientCacheId = clientCacheId;
- mCurrentState.modified = true;
+
+ mDrawingState.frameNumber = frameNumber;
+ mDrawingState.releaseBufferListener = releaseBufferListener;
+ mDrawingState.buffer = buffer;
+ mDrawingState.clientCacheId = clientCacheId;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
const int32_t layerId = getSequence();
- mFlinger->mTimeStats->setPostTime(layerId, mCurrentState.frameNumber, getName().c_str(),
+ mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
mOwnerUid, postTime, getGameMode());
- mCurrentState.desiredPresentTime = desiredPresentTime;
- mCurrentState.isAutoTimestamp = isAutoTimestamp;
+ mDrawingState.desiredPresentTime = desiredPresentTime;
+ mDrawingState.isAutoTimestamp = isAutoTimestamp;
const nsecs_t presentTime = [&] {
if (!isAutoTimestamp) return desiredPresentTime;
@@ -483,59 +489,59 @@
FrameTracer::FrameEvent::QUEUE);
}
- mCurrentState.width = mCurrentState.buffer->getBuffer()->getWidth();
- mCurrentState.height = mCurrentState.buffer->getBuffer()->getHeight();
+ mDrawingState.width = mDrawingState.buffer->getBuffer()->getWidth();
+ mDrawingState.height = mDrawingState.buffer->getBuffer()->getHeight();
return true;
}
bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
- mCurrentState.acquireFence = fence;
- mCurrentState.acquireFenceTime = std::make_unique<FenceTime>(fence);
+ mDrawingState.acquireFence = fence;
+ mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(fence);
// The acquire fences of BufferStateLayers have already signaled before they are set
- mCallbackHandleAcquireTime = mCurrentState.acquireFenceTime->getSignalTime();
+ mCallbackHandleAcquireTime = mDrawingState.acquireFenceTime->getSignalTime();
- mCurrentState.modified = true;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
- if (mCurrentState.dataspace == dataspace) return false;
- mCurrentState.dataspace = dataspace;
- mCurrentState.modified = true;
+ if (mDrawingState.dataspace == dataspace) return false;
+ mDrawingState.dataspace = dataspace;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
- if (mCurrentState.hdrMetadata == hdrMetadata) return false;
- mCurrentState.hdrMetadata = hdrMetadata;
- mCurrentState.modified = true;
+ if (mDrawingState.hdrMetadata == hdrMetadata) return false;
+ mDrawingState.hdrMetadata = hdrMetadata;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
- mCurrentState.surfaceDamageRegion = surfaceDamage;
- mCurrentState.modified = true;
+ mDrawingState.surfaceDamageRegion = surfaceDamage;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setApi(int32_t api) {
- if (mCurrentState.api == api) return false;
- mCurrentState.api = api;
- mCurrentState.modified = true;
+ if (mDrawingState.api == api) return false;
+ mDrawingState.api = api;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
- if (mCurrentState.sidebandStream == sidebandStream) return false;
- mCurrentState.sidebandStream = sidebandStream;
- mCurrentState.modified = true;
+ if (mDrawingState.sidebandStream == sidebandStream) return false;
+ mDrawingState.sidebandStream = sidebandStream;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
if (!mSidebandStreamChanged.exchange(true)) {
@@ -563,14 +569,14 @@
if (willPresent) {
// If this transaction set an acquire fence on this layer, set its acquire time
handle->acquireTime = mCallbackHandleAcquireTime;
- handle->frameNumber = mCurrentState.frameNumber;
+ handle->frameNumber = mDrawingState.frameNumber;
// Notify the transaction completed thread that there is a pending latched callback
// handle
mFlinger->getTransactionCallbackInvoker().registerPendingCallbackHandle(handle);
// Store so latched time and release fence can be set
- mCurrentState.callbackHandles.push_back(handle);
+ mDrawingState.callbackHandles.push_back(handle);
} else { // If this layer will NOT need to be relatched and presented this frame
// Notify the transaction completed thread this handle is done
@@ -585,8 +591,8 @@
}
bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
- mCurrentState.transparentRegionHint = transparent;
- mCurrentState.modified = true;
+ mDrawingState.transparentRegionHint = transparent;
+ mDrawingState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -645,7 +651,7 @@
return true;
}
- return mCurrentState.isAutoTimestamp || mCurrentState.desiredPresentTime <= expectedPresentTime;
+ return mDrawingState.isAutoTimestamp || mDrawingState.desiredPresentTime <= expectedPresentTime;
}
bool BufferStateLayer::onPreComposition(nsecs_t refreshStartTime) {
@@ -674,7 +680,7 @@
* }
* Now imagine getHeadFrameNumber returned mDrawingState.mFrameNumber (or mCurrentFrameNumber).
* Prior to doTransaction SurfaceFlinger will call notifyAvailableFrames, but because we
- * haven't swapped mCurrentState to mDrawingState yet we will think the sync point
+ * haven't swapped mDrawingState to mDrawingState yet we will think the sync point
* is not ready. So we will return false from applyPendingState and not swap
* current state to drawing state. But because we don't swap current state
* to drawing state the number will never update and we will be stuck. This way
@@ -682,7 +688,7 @@
* to apply.
*/
uint64_t BufferStateLayer::getHeadFrameNumber(nsecs_t /* expectedPresentTime */) const {
- return mCurrentState.frameNumber;
+ return mDrawingState.frameNumber;
}
void BufferStateLayer::setAutoRefresh(bool autoRefresh) {
@@ -712,8 +718,8 @@
}
bool BufferStateLayer::hasFrameUpdate() const {
- const State& c(getCurrentState());
- return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr);
+ const State& c(getDrawingState());
+ return mDrawingStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr);
}
status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
@@ -756,6 +762,7 @@
addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
mDrawingState.acquireFenceTime->getSignalTime(),
latchTime);
+ mDrawingState.bufferSurfaceFrameTX.reset();
}
std::deque<sp<CallbackHandle>> remainingHandles;
@@ -763,7 +770,7 @@
.finalizeOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
mDrawingState.callbackHandles = remainingHandles;
- mCurrentStateModified = false;
+ mDrawingStateModified = false;
return NO_ERROR;
}