summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/BufferQueueLayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/BufferQueueLayer.cpp')
-rw-r--r--services/surfaceflinger/BufferQueueLayer.cpp119
1 files changed, 65 insertions, 54 deletions
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 6e4235e409..6b6d43425d 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -17,6 +17,7 @@
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
+#pragma clang diagnostic ignored "-Wextra"
#undef LOG_TAG
#define LOG_TAG "BufferQueueLayer"
@@ -35,6 +36,7 @@
#include "TimeStats/TimeStats.h"
namespace android {
+using PresentState = frametimeline::SurfaceFrame::PresentState;
BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
@@ -98,18 +100,10 @@ int32_t BufferQueueLayer::getQueuedFrameCount() const {
return mQueuedFrames;
}
-bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const {
- if (getSidebandStreamChanged() || getAutoRefresh()) {
- return true;
- }
-
- if (!hasFrameUpdate()) {
- return false;
- }
-
+bool BufferQueueLayer::isBufferDue(nsecs_t expectedPresentTime) const {
Mutex::Autolock lock(mQueueItemLock);
- const int64_t addedTime = mQueueItems[0].mTimestamp;
+ const int64_t addedTime = mQueueItems[0].item.mTimestamp;
// Ignore timestamps more than a second in the future
const bool isPlausible = addedTime < (expectedPresentTime + s2ns(1));
@@ -131,7 +125,9 @@ bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const {
// -----------------------------------------------------------------------
bool BufferQueueLayer::fenceHasSignaled() const {
- if (latchUnsignaledBuffers()) {
+ Mutex::Autolock lock(mQueueItemLock);
+
+ if (SurfaceFlinger::enableLatchUnsignaled) {
return true;
}
@@ -139,8 +135,7 @@ bool BufferQueueLayer::fenceHasSignaled() const {
return true;
}
- Mutex::Autolock lock(mQueueItemLock);
- if (mQueueItems[0].mIsDroppable) {
+ if (mQueueItems[0].item.mIsDroppable) {
// Even though this buffer's fence may not have signaled yet, it could
// be replaced by another buffer before it has a chance to, which means
// that it's possible to get into a situation where a buffer is never
@@ -148,7 +143,7 @@ bool BufferQueueLayer::fenceHasSignaled() const {
return true;
}
const bool fenceSignaled =
- mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
+ mQueueItems[0].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
if (!fenceSignaled) {
mFlinger->mTimeStats->incrementLatchSkipped(getSequence(),
TimeStats::LatchSkipReason::LateAcquire);
@@ -163,12 +158,12 @@ bool BufferQueueLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) co
}
Mutex::Autolock lock(mQueueItemLock);
- return mQueueItems[0].mTimestamp <= expectedPresentTime;
+ return mQueueItems[0].item.mTimestamp <= expectedPresentTime;
}
uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const {
Mutex::Autolock lock(mQueueItemLock);
- uint64_t frameNumber = mQueueItems[0].mFrameNumber;
+ uint64_t frameNumber = mQueueItems[0].item.mFrameNumber;
// The head of the queue will be dropped if there are signaled and timely frames behind it
if (isRemovedFromCurrentState()) {
@@ -177,39 +172,35 @@ uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const {
for (int i = 1; i < mQueueItems.size(); i++) {
const bool fenceSignaled =
- mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
+ mQueueItems[i].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
if (!fenceSignaled) {
break;
}
// We don't drop frames without explicit timestamps
- if (mQueueItems[i].mIsAutoTimestamp) {
+ if (mQueueItems[i].item.mIsAutoTimestamp) {
break;
}
- const nsecs_t desiredPresent = mQueueItems[i].mTimestamp;
+ const nsecs_t desiredPresent = mQueueItems[i].item.mTimestamp;
if (desiredPresent < expectedPresentTime - BufferQueueConsumer::MAX_REASONABLE_NSEC ||
desiredPresent > expectedPresentTime) {
break;
}
- frameNumber = mQueueItems[i].mFrameNumber;
+ frameNumber = mQueueItems[i].item.mFrameNumber;
}
return frameNumber;
}
-bool BufferQueueLayer::getAutoRefresh() const {
- return mAutoRefresh;
-}
-
-bool BufferQueueLayer::getSidebandStreamChanged() const {
- return mSidebandStreamChanged;
-}
-
bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
+ // We need to update the sideband stream if the layer has both a buffer and a sideband stream.
+ const bool updateSidebandStream = hasFrameUpdate() && mSidebandStream.get();
+
bool sidebandStreamChanged = true;
- if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
+ if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false) ||
+ updateSidebandStream) {
// mSidebandStreamChanged was changed to false
mSidebandStream = mConsumer->getSidebandStream();
auto* layerCompositionState = editCompositionState();
@@ -229,10 +220,6 @@ bool BufferQueueLayer::hasFrameUpdate() const {
return mQueuedFrames > 0;
}
-status_t BufferQueueLayer::bindTextureImage() {
- return mConsumer->bindTextureImage();
-}
-
status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
nsecs_t expectedPresentTime) {
// This boolean is used to make sure that SurfaceFlinger's shadow copy
@@ -241,8 +228,8 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
// buffer mode.
bool queuedBuffer = false;
const int32_t layerId = getSequence();
- LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
- getProducerStickyTransform() != 0, mName, mOverrideScalingMode,
+ LayerRejecter r(mDrawingState, getDrawingState(), recomputeVisibleRegions,
+ getProducerStickyTransform() != 0, mName,
getTransformToDisplayInverse());
if (isRemovedFromCurrentState()) {
@@ -258,18 +245,20 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
Mutex::Autolock lock(mQueueItemLock);
for (int i = 0; i < mQueueItems.size(); i++) {
bool fenceSignaled =
- mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
+ mQueueItems[i].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
if (!fenceSignaled) {
break;
}
- lastSignaledFrameNumber = mQueueItems[i].mFrameNumber;
+ lastSignaledFrameNumber = mQueueItems[i].item.mFrameNumber;
}
}
const uint64_t maxFrameNumberToAcquire =
std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
- status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh,
+ bool autoRefresh;
+ status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &autoRefresh,
&queuedBuffer, maxFrameNumberToAcquire);
+ mAutoRefresh = autoRefresh;
if (updateResult == BufferQueue::PRESENT_LATER) {
// Producer doesn't want buffer to be displayed yet. Signal a
// layer update so we check again at the next opportunity.
@@ -280,9 +269,12 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
// and return early
if (queuedBuffer) {
Mutex::Autolock lock(mQueueItemLock);
- mConsumer->mergeSurfaceDamage(mQueueItems[0].mSurfaceDamage);
- mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].mFrameNumber);
- mQueueItems.removeAt(0);
+ mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
+ mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
+ if (mQueueItems[0].surfaceFrame) {
+ addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
+ }
+ mQueueItems.erase(mQueueItems.begin());
mQueuedFrames--;
}
return BAD_VALUE;
@@ -293,6 +285,11 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
// early.
if (queuedBuffer) {
Mutex::Autolock lock(mQueueItemLock);
+ for (auto& [item, surfaceFrame] : mQueueItems) {
+ if (surfaceFrame) {
+ addSurfaceFrameDroppedForBuffer(surfaceFrame);
+ }
+ }
mQueueItems.clear();
mQueuedFrames = 0;
mFlinger->mTimeStats->onDestroy(layerId);
@@ -316,19 +313,27 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
// Remove any stale buffers that have been dropped during
// updateTexImage
- while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
- mConsumer->mergeSurfaceDamage(mQueueItems[0].mSurfaceDamage);
- mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].mFrameNumber);
- mQueueItems.removeAt(0);
+ while (mQueueItems[0].item.mFrameNumber != currentFrameNumber) {
+ mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
+ mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
+ if (mQueueItems[0].surfaceFrame) {
+ addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
+ }
+ mQueueItems.erase(mQueueItems.begin());
mQueuedFrames--;
}
- uint64_t bufferID = mQueueItems[0].mGraphicBuffer->getId();
+ uint64_t bufferID = mQueueItems[0].item.mGraphicBuffer->getId();
mFlinger->mTimeStats->setLatchTime(layerId, currentFrameNumber, latchTime);
mFlinger->mFrameTracer->traceTimestamp(layerId, bufferID, currentFrameNumber, latchTime,
FrameTracer::FrameEvent::LATCH);
- mQueueItems.removeAt(0);
+ if (mQueueItems[0].surfaceFrame) {
+ addSurfaceFramePresentedForBuffer(mQueueItems[0].surfaceFrame,
+ mQueueItems[0].item.mFenceTime->getSignalTime(),
+ latchTime);
+ }
+ mQueueItems.erase(mQueueItems.begin());
}
// Decrement the queued-frames count. Signal another event if we
@@ -364,6 +369,10 @@ status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) {
return NO_ERROR;
}
+void BufferQueueLayer::setFrameTimelineInfoForBuffer(const FrameTimelineInfo& frameTimelineInfo) {
+ mFrameTimelineInfo = frameTimelineInfo;
+}
+
// -----------------------------------------------------------------------
// Interface implementation for BufferLayerConsumer::ContentsChangedListener
// -----------------------------------------------------------------------
@@ -420,7 +429,9 @@ void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
}
}
- mQueueItems.push_back(item);
+ auto surfaceFrame = createSurfaceFrameForBuffer(mFrameTimelineInfo, systemTime(), mName);
+
+ mQueueItems.push_back({item, surfaceFrame});
mQueuedFrames++;
// Wake up any pending callbacks
@@ -453,7 +464,10 @@ void BufferQueueLayer::onFrameReplaced(const BufferItem& item) {
ALOGE("Can't replace a frame on an empty queue");
return;
}
- mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
+
+ auto surfaceFrame = createSurfaceFrameForBuffer(mFrameTimelineInfo, systemTime(), mName);
+ mQueueItems[mQueueItems.size() - 1].item = item;
+ mQueueItems[mQueueItems.size() - 1].surfaceFrame = std::move(surfaceFrame);
// Wake up any pending callbacks
mLastFrameNumberReceived = item.mFrameNumber;
@@ -497,10 +511,7 @@ void BufferQueueLayer::onFirstRef() {
mConsumer->setContentsChangedListener(mContentsChangedListener);
mConsumer->setName(String8(mName.data(), mName.size()));
- // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
- if (!mFlinger->isLayerTripleBufferingDisabled()) {
- mProducer->setMaxDequeuedBufferCount(2);
- }
+ mProducer->setMaxDequeuedBufferCount(2);
}
status_t BufferQueueLayer::setDefaultBufferProperties(uint32_t w, uint32_t h, PixelFormat format) {
@@ -617,4 +628,4 @@ void BufferQueueLayer::ContentsChangedListener::abandon() {
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
+#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"