Loading services/surfaceflinger/Layer.cpp +97 −75 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mCurrentTransform(0), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentOpacity(true), mCurrentOpacity(true), mCurrentFrameNumber(0), mRefreshPending(false), mRefreshPending(false), mFrameLatencyNeeded(false), mFrameLatencyNeeded(false), mFiltering(false), mFiltering(false), Loading Loading @@ -147,6 +148,9 @@ void Layer::onFirstRef() { } } Layer::~Layer() { Layer::~Layer() { for (auto& point : mRemoteSyncPoints) { point->setTransactionApplied(); } mFlinger->deleteTextureAsync(mTextureName); mFlinger->deleteTextureAsync(mTextureName); mFrameTracker.logAndResetStats(mName); mFrameTracker.logAndResetStats(mName); } } Loading @@ -163,20 +167,6 @@ void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, } } } } void Layer::markSyncPointsAvailable(const BufferItem& item) { auto pointIter = mLocalSyncPoints.begin(); while (pointIter != mLocalSyncPoints.end()) { if ((*pointIter)->getFrameNumber() == item.mFrameNumber) { auto syncPoint = *pointIter; pointIter = mLocalSyncPoints.erase(pointIter); Mutex::Autolock lock(mAvailableFrameMutex); mAvailableFrames.push_back(std::move(syncPoint)); } else { ++pointIter; } } } void Layer::onFrameAvailable(const BufferItem& item) { void Layer::onFrameAvailable(const BufferItem& item) { // Add this buffer from our internal queue tracker // Add this buffer from our internal queue tracker { // Autolock scope { // Autolock scope Loading Loading @@ -205,8 +195,6 @@ void Layer::onFrameAvailable(const BufferItem& item) { mQueueItemCondition.broadcast(); mQueueItemCondition.broadcast(); } } markSyncPointsAvailable(item); mFlinger->signalLayerUpdate(); mFlinger->signalLayerUpdate(); } } Loading @@ -233,8 +221,6 @@ void Layer::onFrameReplaced(const BufferItem& item) { mLastFrameNumberReceived = item.mFrameNumber; mLastFrameNumberReceived = item.mFrameNumber; mQueueItemCondition.broadcast(); mQueueItemCondition.broadcast(); } } markSyncPointsAvailable(item); } } void Layer::onSidebandStreamChanged() { void Layer::onSidebandStreamChanged() { Loading Loading @@ -803,22 +789,25 @@ uint32_t Layer::getProducerStickyTransform() const { return static_cast<uint32_t>(producerStickyTransform); return static_cast<uint32_t>(producerStickyTransform); } } void Layer::addSyncPoint(std::shared_ptr<SyncPoint> point) { uint64_t Layer::getHeadFrameNumber() const { uint64_t headFrameNumber = 0; { Mutex::Autolock lock(mQueueItemLock); Mutex::Autolock lock(mQueueItemLock); if (!mQueueItems.empty()) { if (!mQueueItems.empty()) { headFrameNumber = mQueueItems[0].mFrameNumber; return mQueueItems[0].mFrameNumber; } else { } else { headFrameNumber = mLastFrameNumberReceived; return mCurrentFrameNumber; } } } } if (point->getFrameNumber() <= headFrameNumber) { bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) { point->setFrameAvailable(); if (point->getFrameNumber() <= mCurrentFrameNumber) { } else { // Don't bother with a SyncPoint, since we've already latched the mLocalSyncPoints.push_back(std::move(point)); // relevant frame return false; } } Mutex::Autolock lock(mLocalSyncPointMutex); mLocalSyncPoints.push_back(point); return true; } } void Layer::setFiltering(bool filtering) { void Layer::setFiltering(bool filtering) { Loading Loading @@ -940,8 +929,6 @@ void Layer::pushPendingState() { return; return; } } Mutex::Autolock lock(mPendingStateMutex); // If this transaction is waiting on the receipt of a frame, generate a sync // If this transaction is waiting on the receipt of a frame, generate a sync // point and send it to the remote layer. // point and send it to the remote layer. if (mCurrentState.handle != nullptr) { if (mCurrentState.handle != nullptr) { Loading @@ -956,8 +943,13 @@ void Layer::pushPendingState() { } else { } else { auto syncPoint = std::make_shared<SyncPoint>( auto syncPoint = std::make_shared<SyncPoint>( mCurrentState.frameNumber); mCurrentState.frameNumber); handleLayer->addSyncPoint(syncPoint); if (handleLayer->addSyncPoint(syncPoint)) { mRemoteSyncPoints.push_back(std::move(syncPoint)); mRemoteSyncPoints.push_back(std::move(syncPoint)); } else { // We already missed the frame we're supposed to synchronize // on, so go ahead and apply the state update mCurrentState.handle = nullptr; } } } // Wake us up to check if the frame has been received // Wake us up to check if the frame has been received Loading @@ -976,8 +968,6 @@ void Layer::popPendingState() { } } bool Layer::applyPendingStates() { bool Layer::applyPendingStates() { Mutex::Autolock lock(mPendingStateMutex); bool stateUpdateAvailable = false; bool stateUpdateAvailable = false; while (!mPendingStates.empty()) { while (!mPendingStates.empty()) { if (mPendingStates[0].handle != nullptr) { if (mPendingStates[0].handle != nullptr) { Loading @@ -991,6 +981,17 @@ bool Layer::applyPendingStates() { continue; continue; } } if (mRemoteSyncPoints.front()->getFrameNumber() != mPendingStates[0].frameNumber) { ALOGE("[%s] Unexpected sync point frame number found", mName.string()); // Signal our end of the sync point and then dispose of it mRemoteSyncPoints.front()->setTransactionApplied(); mRemoteSyncPoints.pop_front(); continue; } if (mRemoteSyncPoints.front()->frameIsAvailable()) { if (mRemoteSyncPoints.front()->frameIsAvailable()) { // Apply the state update // Apply the state update popPendingState(); popPendingState(); Loading Loading @@ -1019,9 +1020,12 @@ bool Layer::applyPendingStates() { } } void Layer::notifyAvailableFrames() { void Layer::notifyAvailableFrames() { Mutex::Autolock lock(mAvailableFrameMutex); auto headFrameNumber = getHeadFrameNumber(); for (auto frame : mAvailableFrames) { Mutex::Autolock lock(mLocalSyncPointMutex); frame->setFrameAvailable(); for (auto& point : mLocalSyncPoints) { if (headFrameNumber >= point->getFrameNumber()) { point->setFrameAvailable(); } } } } } Loading Loading @@ -1462,37 +1466,40 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, getProducerStickyTransform() != 0); getProducerStickyTransform() != 0); uint64_t maxFrameNumber = 0; uint64_t headFrameNumber = 0; { Mutex::Autolock lock(mQueueItemLock); maxFrameNumber = mLastFrameNumberReceived; if (!mQueueItems.empty()) { headFrameNumber = mQueueItems[0].mFrameNumber; } } bool availableFramesEmpty = true; // Check all of our local sync points to ensure that all transactions { // which need to have been applied prior to the frame which is about to Mutex::Autolock lock(mAvailableFrameMutex); // be latched have signaled availableFramesEmpty = mAvailableFrames.empty(); } auto headFrameNumber = getHeadFrameNumber(); if (!availableFramesEmpty) { Mutex::Autolock lock(mAvailableFrameMutex); bool matchingFramesFound = false; bool matchingFramesFound = false; bool allTransactionsApplied = true; bool allTransactionsApplied = true; for (auto& frame : mAvailableFrames) { { if (headFrameNumber != frame->getFrameNumber()) { Mutex::Autolock lock(mLocalSyncPointMutex); for (auto& point : mLocalSyncPoints) { if (point->getFrameNumber() > headFrameNumber) { break; break; } } matchingFramesFound = true; matchingFramesFound = true; allTransactionsApplied &= frame->transactionIsApplied(); if (!point->frameIsAvailable()) { // We haven't notified the remote layer that the frame for // this point is available yet. Notify it now, and then // abort this attempt to latch. point->setFrameAvailable(); allTransactionsApplied = false; break; } } allTransactionsApplied &= point->transactionIsApplied(); } } if (matchingFramesFound && !allTransactionsApplied) { if (matchingFramesFound && !allTransactionsApplied) { mFlinger->signalLayerUpdate(); mFlinger->signalLayerUpdate(); return outDirtyRegion; return outDirtyRegion; } } } // This boolean is used to make sure that SurfaceFlinger's shadow copy // This boolean is used to make sure that SurfaceFlinger's shadow copy // of the buffer queue isn't modified when the buffer queue is returning // of the buffer queue isn't modified when the buffer queue is returning Loading @@ -1501,7 +1508,7 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) bool queuedBuffer = false; bool queuedBuffer = false; status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer, mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer, maxFrameNumber); mLastFrameNumberReceived); if (updateResult == BufferQueue::PRESENT_LATER) { if (updateResult == BufferQueue::PRESENT_LATER) { // Producer doesn't want buffer to be displayed yet. Signal a // Producer doesn't want buffer to be displayed yet. Signal a // layer update so we check again at the next opportunity. // layer update so we check again at the next opportunity. Loading Loading @@ -1560,15 +1567,6 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) mFlinger->signalLayerUpdate(); mFlinger->signalLayerUpdate(); } } if (!availableFramesEmpty) { Mutex::Autolock lock(mAvailableFrameMutex); auto frameNumber = mSurfaceFlingerConsumer->getFrameNumber(); while (!mAvailableFrames.empty() && frameNumber == mAvailableFrames.front()->getFrameNumber()) { mAvailableFrames.pop_front(); } } if (updateResult != NO_ERROR) { if (updateResult != NO_ERROR) { // something happened! // something happened! recomputeVisibleRegions = true; recomputeVisibleRegions = true; Loading Loading @@ -1617,6 +1615,30 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) recomputeVisibleRegions = true; recomputeVisibleRegions = true; } } mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber(); // Remove any sync points corresponding to the buffer which was just // latched { Mutex::Autolock lock(mLocalSyncPointMutex); auto point = mLocalSyncPoints.begin(); while (point != mLocalSyncPoints.end()) { if (!(*point)->frameIsAvailable() || !(*point)->transactionIsApplied()) { // This sync point must have been added since we started // latching. Don't drop it yet. ++point; continue; } if ((*point)->getFrameNumber() <= mCurrentFrameNumber) { point = mLocalSyncPoints.erase(point); } else { ++point; } } } // FIXME: postedRegion should be dirty & bounds // FIXME: postedRegion should be dirty & bounds Region dirtyRegion(Rect(s.active.w, s.active.h)); Region dirtyRegion(Rect(s.active.w, s.active.h)); Loading services/surfaceflinger/Layer.h +12 −10 Original line number Original line Diff line number Diff line Loading @@ -356,10 +356,6 @@ private: virtual void onFrameReplaced(const BufferItem& item) override; virtual void onFrameReplaced(const BufferItem& item) override; virtual void onSidebandStreamChanged() override; virtual void onSidebandStreamChanged() override; // Move frames made available by item in to a list which will // be signalled at the beginning of the next transaction virtual void markSyncPointsAvailable(const BufferItem& item); void commitTransaction(); void commitTransaction(); // needsLinearFiltering - true if this surface's state requires filtering // needsLinearFiltering - true if this surface's state requires filtering Loading Loading @@ -413,19 +409,24 @@ private: std::atomic<bool> mTransactionIsApplied; std::atomic<bool> mTransactionIsApplied; }; }; // SyncPoints which will be signaled when the correct frame is at the head // of the queue and dropped after the frame has been latched. Protected by // mLocalSyncPointMutex. Mutex mLocalSyncPointMutex; std::list<std::shared_ptr<SyncPoint>> mLocalSyncPoints; std::list<std::shared_ptr<SyncPoint>> mLocalSyncPoints; // Guarded by mPendingStateMutex // SyncPoints which will be signaled and then dropped when the transaction // is applied std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints; std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints; void addSyncPoint(std::shared_ptr<SyncPoint> point); uint64_t getHeadFrameNumber() const; // Returns false if the relevant frame has already been latched bool addSyncPoint(const std::shared_ptr<SyncPoint>& point); void pushPendingState(); void pushPendingState(); void popPendingState(); void popPendingState(); bool applyPendingStates(); bool applyPendingStates(); Mutex mAvailableFrameMutex; std::list<std::shared_ptr<SyncPoint>> mAvailableFrames; public: public: void notifyAvailableFrames(); void notifyAvailableFrames(); private: private: Loading Loading @@ -461,6 +462,7 @@ private: uint32_t mCurrentTransform; uint32_t mCurrentTransform; uint32_t mCurrentScalingMode; uint32_t mCurrentScalingMode; bool mCurrentOpacity; bool mCurrentOpacity; std::atomic<uint64_t> mCurrentFrameNumber; bool mRefreshPending; bool mRefreshPending; bool mFrameLatencyNeeded; bool mFrameLatencyNeeded; // Whether filtering is forced on or not // Whether filtering is forced on or not Loading Loading @@ -488,7 +490,7 @@ private: mutable Mutex mQueueItemLock; mutable Mutex mQueueItemLock; Condition mQueueItemCondition; Condition mQueueItemCondition; Vector<BufferItem> mQueueItems; Vector<BufferItem> mQueueItems; uint64_t mLastFrameNumberReceived; std::atomic<uint64_t> mLastFrameNumberReceived; bool mUpdateTexImageFailed; // This is only modified from the main thread bool mUpdateTexImageFailed; // This is only modified from the main thread bool mSingleBufferMode; bool mSingleBufferMode; Loading Loading
services/surfaceflinger/Layer.cpp +97 −75 Original line number Original line Diff line number Diff line Loading @@ -73,6 +73,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mCurrentTransform(0), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentOpacity(true), mCurrentOpacity(true), mCurrentFrameNumber(0), mRefreshPending(false), mRefreshPending(false), mFrameLatencyNeeded(false), mFrameLatencyNeeded(false), mFiltering(false), mFiltering(false), Loading Loading @@ -147,6 +148,9 @@ void Layer::onFirstRef() { } } Layer::~Layer() { Layer::~Layer() { for (auto& point : mRemoteSyncPoints) { point->setTransactionApplied(); } mFlinger->deleteTextureAsync(mTextureName); mFlinger->deleteTextureAsync(mTextureName); mFrameTracker.logAndResetStats(mName); mFrameTracker.logAndResetStats(mName); } } Loading @@ -163,20 +167,6 @@ void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, } } } } void Layer::markSyncPointsAvailable(const BufferItem& item) { auto pointIter = mLocalSyncPoints.begin(); while (pointIter != mLocalSyncPoints.end()) { if ((*pointIter)->getFrameNumber() == item.mFrameNumber) { auto syncPoint = *pointIter; pointIter = mLocalSyncPoints.erase(pointIter); Mutex::Autolock lock(mAvailableFrameMutex); mAvailableFrames.push_back(std::move(syncPoint)); } else { ++pointIter; } } } void Layer::onFrameAvailable(const BufferItem& item) { void Layer::onFrameAvailable(const BufferItem& item) { // Add this buffer from our internal queue tracker // Add this buffer from our internal queue tracker { // Autolock scope { // Autolock scope Loading Loading @@ -205,8 +195,6 @@ void Layer::onFrameAvailable(const BufferItem& item) { mQueueItemCondition.broadcast(); mQueueItemCondition.broadcast(); } } markSyncPointsAvailable(item); mFlinger->signalLayerUpdate(); mFlinger->signalLayerUpdate(); } } Loading @@ -233,8 +221,6 @@ void Layer::onFrameReplaced(const BufferItem& item) { mLastFrameNumberReceived = item.mFrameNumber; mLastFrameNumberReceived = item.mFrameNumber; mQueueItemCondition.broadcast(); mQueueItemCondition.broadcast(); } } markSyncPointsAvailable(item); } } void Layer::onSidebandStreamChanged() { void Layer::onSidebandStreamChanged() { Loading Loading @@ -803,22 +789,25 @@ uint32_t Layer::getProducerStickyTransform() const { return static_cast<uint32_t>(producerStickyTransform); return static_cast<uint32_t>(producerStickyTransform); } } void Layer::addSyncPoint(std::shared_ptr<SyncPoint> point) { uint64_t Layer::getHeadFrameNumber() const { uint64_t headFrameNumber = 0; { Mutex::Autolock lock(mQueueItemLock); Mutex::Autolock lock(mQueueItemLock); if (!mQueueItems.empty()) { if (!mQueueItems.empty()) { headFrameNumber = mQueueItems[0].mFrameNumber; return mQueueItems[0].mFrameNumber; } else { } else { headFrameNumber = mLastFrameNumberReceived; return mCurrentFrameNumber; } } } } if (point->getFrameNumber() <= headFrameNumber) { bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) { point->setFrameAvailable(); if (point->getFrameNumber() <= mCurrentFrameNumber) { } else { // Don't bother with a SyncPoint, since we've already latched the mLocalSyncPoints.push_back(std::move(point)); // relevant frame return false; } } Mutex::Autolock lock(mLocalSyncPointMutex); mLocalSyncPoints.push_back(point); return true; } } void Layer::setFiltering(bool filtering) { void Layer::setFiltering(bool filtering) { Loading Loading @@ -940,8 +929,6 @@ void Layer::pushPendingState() { return; return; } } Mutex::Autolock lock(mPendingStateMutex); // If this transaction is waiting on the receipt of a frame, generate a sync // If this transaction is waiting on the receipt of a frame, generate a sync // point and send it to the remote layer. // point and send it to the remote layer. if (mCurrentState.handle != nullptr) { if (mCurrentState.handle != nullptr) { Loading @@ -956,8 +943,13 @@ void Layer::pushPendingState() { } else { } else { auto syncPoint = std::make_shared<SyncPoint>( auto syncPoint = std::make_shared<SyncPoint>( mCurrentState.frameNumber); mCurrentState.frameNumber); handleLayer->addSyncPoint(syncPoint); if (handleLayer->addSyncPoint(syncPoint)) { mRemoteSyncPoints.push_back(std::move(syncPoint)); mRemoteSyncPoints.push_back(std::move(syncPoint)); } else { // We already missed the frame we're supposed to synchronize // on, so go ahead and apply the state update mCurrentState.handle = nullptr; } } } // Wake us up to check if the frame has been received // Wake us up to check if the frame has been received Loading @@ -976,8 +968,6 @@ void Layer::popPendingState() { } } bool Layer::applyPendingStates() { bool Layer::applyPendingStates() { Mutex::Autolock lock(mPendingStateMutex); bool stateUpdateAvailable = false; bool stateUpdateAvailable = false; while (!mPendingStates.empty()) { while (!mPendingStates.empty()) { if (mPendingStates[0].handle != nullptr) { if (mPendingStates[0].handle != nullptr) { Loading @@ -991,6 +981,17 @@ bool Layer::applyPendingStates() { continue; continue; } } if (mRemoteSyncPoints.front()->getFrameNumber() != mPendingStates[0].frameNumber) { ALOGE("[%s] Unexpected sync point frame number found", mName.string()); // Signal our end of the sync point and then dispose of it mRemoteSyncPoints.front()->setTransactionApplied(); mRemoteSyncPoints.pop_front(); continue; } if (mRemoteSyncPoints.front()->frameIsAvailable()) { if (mRemoteSyncPoints.front()->frameIsAvailable()) { // Apply the state update // Apply the state update popPendingState(); popPendingState(); Loading Loading @@ -1019,9 +1020,12 @@ bool Layer::applyPendingStates() { } } void Layer::notifyAvailableFrames() { void Layer::notifyAvailableFrames() { Mutex::Autolock lock(mAvailableFrameMutex); auto headFrameNumber = getHeadFrameNumber(); for (auto frame : mAvailableFrames) { Mutex::Autolock lock(mLocalSyncPointMutex); frame->setFrameAvailable(); for (auto& point : mLocalSyncPoints) { if (headFrameNumber >= point->getFrameNumber()) { point->setFrameAvailable(); } } } } } Loading Loading @@ -1462,37 +1466,40 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, getProducerStickyTransform() != 0); getProducerStickyTransform() != 0); uint64_t maxFrameNumber = 0; uint64_t headFrameNumber = 0; { Mutex::Autolock lock(mQueueItemLock); maxFrameNumber = mLastFrameNumberReceived; if (!mQueueItems.empty()) { headFrameNumber = mQueueItems[0].mFrameNumber; } } bool availableFramesEmpty = true; // Check all of our local sync points to ensure that all transactions { // which need to have been applied prior to the frame which is about to Mutex::Autolock lock(mAvailableFrameMutex); // be latched have signaled availableFramesEmpty = mAvailableFrames.empty(); } auto headFrameNumber = getHeadFrameNumber(); if (!availableFramesEmpty) { Mutex::Autolock lock(mAvailableFrameMutex); bool matchingFramesFound = false; bool matchingFramesFound = false; bool allTransactionsApplied = true; bool allTransactionsApplied = true; for (auto& frame : mAvailableFrames) { { if (headFrameNumber != frame->getFrameNumber()) { Mutex::Autolock lock(mLocalSyncPointMutex); for (auto& point : mLocalSyncPoints) { if (point->getFrameNumber() > headFrameNumber) { break; break; } } matchingFramesFound = true; matchingFramesFound = true; allTransactionsApplied &= frame->transactionIsApplied(); if (!point->frameIsAvailable()) { // We haven't notified the remote layer that the frame for // this point is available yet. Notify it now, and then // abort this attempt to latch. point->setFrameAvailable(); allTransactionsApplied = false; break; } } allTransactionsApplied &= point->transactionIsApplied(); } } if (matchingFramesFound && !allTransactionsApplied) { if (matchingFramesFound && !allTransactionsApplied) { mFlinger->signalLayerUpdate(); mFlinger->signalLayerUpdate(); return outDirtyRegion; return outDirtyRegion; } } } // This boolean is used to make sure that SurfaceFlinger's shadow copy // This boolean is used to make sure that SurfaceFlinger's shadow copy // of the buffer queue isn't modified when the buffer queue is returning // of the buffer queue isn't modified when the buffer queue is returning Loading @@ -1501,7 +1508,7 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) bool queuedBuffer = false; bool queuedBuffer = false; status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer, mFlinger->mPrimaryDispSync, &mSingleBufferMode, &queuedBuffer, maxFrameNumber); mLastFrameNumberReceived); if (updateResult == BufferQueue::PRESENT_LATER) { if (updateResult == BufferQueue::PRESENT_LATER) { // Producer doesn't want buffer to be displayed yet. Signal a // Producer doesn't want buffer to be displayed yet. Signal a // layer update so we check again at the next opportunity. // layer update so we check again at the next opportunity. Loading Loading @@ -1560,15 +1567,6 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) mFlinger->signalLayerUpdate(); mFlinger->signalLayerUpdate(); } } if (!availableFramesEmpty) { Mutex::Autolock lock(mAvailableFrameMutex); auto frameNumber = mSurfaceFlingerConsumer->getFrameNumber(); while (!mAvailableFrames.empty() && frameNumber == mAvailableFrames.front()->getFrameNumber()) { mAvailableFrames.pop_front(); } } if (updateResult != NO_ERROR) { if (updateResult != NO_ERROR) { // something happened! // something happened! recomputeVisibleRegions = true; recomputeVisibleRegions = true; Loading Loading @@ -1617,6 +1615,30 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) recomputeVisibleRegions = true; recomputeVisibleRegions = true; } } mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber(); // Remove any sync points corresponding to the buffer which was just // latched { Mutex::Autolock lock(mLocalSyncPointMutex); auto point = mLocalSyncPoints.begin(); while (point != mLocalSyncPoints.end()) { if (!(*point)->frameIsAvailable() || !(*point)->transactionIsApplied()) { // This sync point must have been added since we started // latching. Don't drop it yet. ++point; continue; } if ((*point)->getFrameNumber() <= mCurrentFrameNumber) { point = mLocalSyncPoints.erase(point); } else { ++point; } } } // FIXME: postedRegion should be dirty & bounds // FIXME: postedRegion should be dirty & bounds Region dirtyRegion(Rect(s.active.w, s.active.h)); Region dirtyRegion(Rect(s.active.w, s.active.h)); Loading
services/surfaceflinger/Layer.h +12 −10 Original line number Original line Diff line number Diff line Loading @@ -356,10 +356,6 @@ private: virtual void onFrameReplaced(const BufferItem& item) override; virtual void onFrameReplaced(const BufferItem& item) override; virtual void onSidebandStreamChanged() override; virtual void onSidebandStreamChanged() override; // Move frames made available by item in to a list which will // be signalled at the beginning of the next transaction virtual void markSyncPointsAvailable(const BufferItem& item); void commitTransaction(); void commitTransaction(); // needsLinearFiltering - true if this surface's state requires filtering // needsLinearFiltering - true if this surface's state requires filtering Loading Loading @@ -413,19 +409,24 @@ private: std::atomic<bool> mTransactionIsApplied; std::atomic<bool> mTransactionIsApplied; }; }; // SyncPoints which will be signaled when the correct frame is at the head // of the queue and dropped after the frame has been latched. Protected by // mLocalSyncPointMutex. Mutex mLocalSyncPointMutex; std::list<std::shared_ptr<SyncPoint>> mLocalSyncPoints; std::list<std::shared_ptr<SyncPoint>> mLocalSyncPoints; // Guarded by mPendingStateMutex // SyncPoints which will be signaled and then dropped when the transaction // is applied std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints; std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints; void addSyncPoint(std::shared_ptr<SyncPoint> point); uint64_t getHeadFrameNumber() const; // Returns false if the relevant frame has already been latched bool addSyncPoint(const std::shared_ptr<SyncPoint>& point); void pushPendingState(); void pushPendingState(); void popPendingState(); void popPendingState(); bool applyPendingStates(); bool applyPendingStates(); Mutex mAvailableFrameMutex; std::list<std::shared_ptr<SyncPoint>> mAvailableFrames; public: public: void notifyAvailableFrames(); void notifyAvailableFrames(); private: private: Loading Loading @@ -461,6 +462,7 @@ private: uint32_t mCurrentTransform; uint32_t mCurrentTransform; uint32_t mCurrentScalingMode; uint32_t mCurrentScalingMode; bool mCurrentOpacity; bool mCurrentOpacity; std::atomic<uint64_t> mCurrentFrameNumber; bool mRefreshPending; bool mRefreshPending; bool mFrameLatencyNeeded; bool mFrameLatencyNeeded; // Whether filtering is forced on or not // Whether filtering is forced on or not Loading Loading @@ -488,7 +490,7 @@ private: mutable Mutex mQueueItemLock; mutable Mutex mQueueItemLock; Condition mQueueItemCondition; Condition mQueueItemCondition; Vector<BufferItem> mQueueItems; Vector<BufferItem> mQueueItems; uint64_t mLastFrameNumberReceived; std::atomic<uint64_t> mLastFrameNumberReceived; bool mUpdateTexImageFailed; // This is only modified from the main thread bool mUpdateTexImageFailed; // This is only modified from the main thread bool mSingleBufferMode; bool mSingleBufferMode; Loading