diff options
-rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 21 | ||||
-rw-r--r-- | libs/gui/LayerState.cpp | 8 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 3 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 7 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 29 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 |
8 files changed, 55 insertions, 25 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 0a3d44d336..490495596b 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -146,6 +146,10 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceCont mTransformHint = mSurfaceControl->getTransformHint(); mBufferItemConsumer->setTransformHint(mTransformHint); + SurfaceComposerClient::Transaction() + .setFlags(surface, layer_state_t::eEnableBackpressure, + layer_state_t::eEnableBackpressure) + .apply(); mNumAcquired = 0; mNumFrameAvailable = 0; @@ -169,13 +173,20 @@ BLASTBufferQueue::~BLASTBufferQueue() { void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format) { std::unique_lock _lock{mMutex}; - mSurfaceControl = surface; - if (mFormat != format) { mFormat = format; mBufferItemConsumer->setDefaultBufferFormat(format); } + SurfaceComposerClient::Transaction t; + bool applyTransaction = false; + if (!SurfaceControl::isSameSurface(mSurfaceControl, surface)) { + mSurfaceControl = surface; + t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure, + layer_state_t::eEnableBackpressure); + applyTransaction = true; + } + ui::Size newSize(width, height); if (mRequestedSize != newSize) { mRequestedSize.set(newSize); @@ -184,13 +195,15 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, // If the buffer supports scaling, update the frame immediately since the client may // want to scale the existing buffer to the new size. mSize = mRequestedSize; - SurfaceComposerClient::Transaction t; t.setFrame(mSurfaceControl, {0, 0, static_cast<int32_t>(mSize.width), static_cast<int32_t>(mSize.height)}); - t.apply(); + applyTransaction = true; } } + if (applyTransaction) { + t.apply(); + } } static void transactionCallbackThunk(void* context, nsecs_t latchTime, diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e5e10a0014..2946aaed37 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -183,12 +183,9 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.readUint32, &layerStack); SAFE_PARCEL(input.readFloat, &alpha); - uint32_t tmpUint32 = 0; - SAFE_PARCEL(input.readUint32, &tmpUint32); - flags = static_cast<uint8_t>(tmpUint32); + SAFE_PARCEL(input.readUint32, &flags); - SAFE_PARCEL(input.readUint32, &tmpUint32); - mask = static_cast<uint8_t>(tmpUint32); + SAFE_PARCEL(input.readUint32, &mask); SAFE_PARCEL(matrix.read, input); SAFE_PARCEL(input.read, crop_legacy); @@ -229,6 +226,7 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.read, *acquireFence); } + uint32_t tmpUint32 = 0; SAFE_PARCEL(input.readUint32, &tmpUint32); dataspace = static_cast<ui::Dataspace>(tmpUint32); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 78f655a71b..96c099be23 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -934,7 +934,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags return *this; } if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) || - (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot)) { + (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) || + (mask & layer_state_t::eEnableBackpressure)) { s->what |= layer_state_t::eFlagsChanged; } s->flags &= ~mask; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 83a9d3356e..b1305c6607 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -82,6 +82,10 @@ struct layer_state_t { eLayerOpaque = 0x02, // SURFACE_OPAQUE eLayerSkipScreenshot = 0x40, // SKIP_SCREENSHOT eLayerSecure = 0x80, // SECURE + // Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is + // set. This blocks the client until all the buffers have been presented. If the buffers + // have presentation timestamps, then we may drop buffers. + eEnableBackpressure = 0x100, // ENABLE_BACKPRESSURE }; enum { @@ -157,8 +161,8 @@ struct layer_state_t { uint32_t h; uint32_t layerStack; float alpha; - uint8_t flags; - uint8_t mask; + uint32_t flags; + uint32_t mask; uint8_t reserved; matrix22_t matrix; Rect crop_legacy; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 66ce3f1a44..177a81a7bc 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1312,7 +1312,7 @@ bool Layer::setBlurRegions(const std::vector<BlurRegion>& blurRegions) { return true; } -bool Layer::setFlags(uint8_t flags, uint8_t mask) { +bool Layer::setFlags(uint32_t flags, uint32_t mask) { const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); if (mCurrentState.flags == newFlags) return false; mCurrentState.sequence++; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 359340eb64..357c4a4dee 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -207,7 +207,7 @@ public: // to achieve mirroring. uint32_t layerStack; - uint8_t flags; + uint32_t flags; uint8_t reserved[2]; int32_t sequence; // changes when visible regions can change bool modified; @@ -425,7 +425,7 @@ public: virtual bool setBackgroundBlurRadius(int backgroundBlurRadius); virtual bool setBlurRegions(const std::vector<BlurRegion>& effectRegions); virtual bool setTransparentRegionHint(const Region& transparent); - virtual bool setFlags(uint8_t flags, uint8_t mask); + virtual bool setFlags(uint32_t flags, uint32_t mask); virtual bool setLayerStack(uint32_t layerStack); virtual uint32_t getLayerStack() const; virtual void deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, @@ -906,6 +906,9 @@ public: bool mPendingHWCDestroy{false}; + bool backpressureEnabled() { return mDrawingState.flags & layer_state_t::eEnableBackpressure; } + bool hasPendingBuffer() { return mCurrentState.buffer != mDrawingState.buffer; }; + protected: class SyncPoint { public: diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index c1fabf8322..bf0c2d69f5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3258,7 +3258,8 @@ bool SurfaceFlinger::flushTransactionQueues() { while (!transactionQueue.empty()) { const auto& transaction = transactionQueue.front(); - if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime, + if (!transactionIsReadyToBeApplied(transaction.isAutoTimestamp, + transaction.desiredPresentTime, transaction.states)) { setTransactionFlags(eTransactionFlushNeeded); break; @@ -3291,16 +3292,14 @@ bool SurfaceFlinger::transactionFlushNeeded() { return !mTransactionQueues.empty(); } - -bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime, +bool SurfaceFlinger::transactionIsReadyToBeApplied(bool isAutoTimestamp, int64_t desiredPresentTime, const Vector<ComposerState>& states, bool updateTransactionCounters) { - const nsecs_t expectedPresentTime = mExpectedPresentTime.load(); bool ready = true; // Do not present if the desiredPresentTime has not passed unless it is more than one second // in the future. We ignore timestamps more than 1 second in the future for stability reasons. - if (desiredPresentTime > 0 && desiredPresentTime >= expectedPresentTime && + if (!isAutoTimestamp && desiredPresentTime >= expectedPresentTime && desiredPresentTime < expectedPresentTime + s2ns(1)) { ready = false; } @@ -3320,14 +3319,26 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime, ALOGW("Transaction with buffer, but no Layer?"); continue; } - if (layer && !mScheduler->isVsyncValid(expectedPresentTime, layer->getOwnerUid())) { + if (!layer) { + continue; + } + + if (!mScheduler->isVsyncValid(expectedPresentTime, layer->getOwnerUid())) { ATRACE_NAME("!isVsyncValidForUid"); ready = false; } if (updateTransactionCounters) { - // See BufferStateLayer::mPendingBufferTransactions - if (layer) layer->incrementPendingBufferCount(); + // See BufferStateLayer::mPendingBufferTransactions + layer->incrementPendingBufferCount(); + } + // If backpressure is enabled and we already have a buffer to commit, keep the transaction + // in the queue. + bool hasBuffer = s.what & layer_state_t::eBufferChanged || + s.what & layer_state_t::eCachedBufferChanged; + if (hasBuffer && layer->backpressureEnabled() && layer->hasPendingBuffer() && + isAutoTimestamp) { + ready = false; } } return ready; @@ -3385,7 +3396,7 @@ status_t SurfaceFlinger::setTransactionState( // Call transactionIsReadyToBeApplied first in case we need to incrementPendingBufferCount // if the transaction contains a buffer. - if (!transactionIsReadyToBeApplied(isAutoTimestamp ? 0 : desiredPresentTime, states, true) || + if (!transactionIsReadyToBeApplied(isAutoTimestamp, desiredPresentTime, states, true) || pendingTransactions) { mTransactionQueues[applyToken].emplace(frameTimelineVsyncId, states, displays, flags, desiredPresentTime, isAutoTimestamp, uncacheBuffer, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c90fb4aca3..194131db32 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -751,7 +751,7 @@ private: uint32_t setTransactionFlags(uint32_t flags, TransactionSchedule); void commitTransaction() REQUIRES(mStateLock); void commitOffscreenLayers(); - bool transactionIsReadyToBeApplied(int64_t desiredPresentTime, + bool transactionIsReadyToBeApplied(bool isAutoTimestamp, int64_t desiredPresentTime, const Vector<ComposerState>& states, bool updateTransactionCounters = false) REQUIRES(mStateLock); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); |