diff options
Diffstat (limited to 'services/surfaceflinger/BufferStateLayer.cpp')
-rw-r--r-- | services/surfaceflinger/BufferStateLayer.cpp | 162 |
1 files changed, 94 insertions, 68 deletions
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index efc2c9f7b3..8091b941f8 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -70,30 +70,31 @@ bool BufferStateLayer::shouldPresentNow(nsecs_t /*expectedPresentTime*/) const { } bool BufferStateLayer::willPresentCurrentTransaction() const { + Mutex::Autolock lock(mStateMutex); // Returns true if the most recent Transaction applied to CurrentState will be presented. return getSidebandStreamChanged() || getAutoRefresh() || - (mCurrentState.modified && mCurrentState.buffer != nullptr); + (mState.current.modified && mState.current.buffer != nullptr); } -bool BufferStateLayer::getTransformToDisplayInverse() const { - return mCurrentState.transformToDisplayInverse; +bool BufferStateLayer::getTransformToDisplayInverseLocked() const { + return mState.current.transformToDisplayInverse; } -void BufferStateLayer::pushPendingState() { - if (!mCurrentState.modified) { +void BufferStateLayer::pushPendingStateLocked() { + if (!mState.current.modified) { return; } - mPendingStates.push_back(mCurrentState); - ATRACE_INT(mTransactionName.string(), mPendingStates.size()); + mState.pending.push_back(mState.current); + ATRACE_INT(mTransactionName.string(), mState.pending.size()); } bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { - const bool stateUpdateAvailable = !mPendingStates.empty(); - while (!mPendingStates.empty()) { + const bool stateUpdateAvailable = !mState.pending.empty(); + while (!mState.pending.empty()) { popPendingState(stateToCommit); } - mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified; - mCurrentState.modified = false; + mCurrentStateModified = stateUpdateAvailable && mState.current.modified; + mState.current.modified = false; return stateUpdateAvailable; } @@ -103,28 +104,31 @@ Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const { } bool BufferStateLayer::setTransform(uint32_t transform) { - if (mCurrentState.transform == transform) return false; - mCurrentState.sequence++; - mCurrentState.transform = transform; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.transform == transform) return false; + mState.current.sequence++; + mState.current.transform = transform; + mState.current.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; + Mutex::Autolock lock(mStateMutex); + if (mState.current.transformToDisplayInverse == transformToDisplayInverse) return false; + mState.current.sequence++; + mState.current.transformToDisplayInverse = transformToDisplayInverse; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setCrop(const Rect& crop) { - if (mCurrentState.crop == crop) return false; - mCurrentState.sequence++; - mCurrentState.crop = crop; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.crop == crop) return false; + mState.current.sequence++; + mState.current.crop = crop; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } @@ -135,86 +139,94 @@ bool BufferStateLayer::setFrame(const Rect& frame) { int w = frame.getWidth(); int h = frame.getHeight(); - if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y && - mCurrentState.active.w == w && mCurrentState.active.h == h) { + Mutex::Autolock lock(mStateMutex); + if (mState.current.active.transform.tx() == x && mState.current.active.transform.ty() == y && + mState.current.active.w == w && mState.current.active.h == h) { return false; } if (!frame.isValid()) { x = y = w = h = 0; } - mCurrentState.active.transform.set(x, y); - mCurrentState.active.w = w; - mCurrentState.active.h = h; + mState.current.active.transform.set(x, y); + mState.current.active.w = w; + mState.current.active.h = h; - mCurrentState.sequence++; - mCurrentState.modified = true; + mState.current.sequence++; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) { - if (mCurrentState.buffer) { + Mutex::Autolock lock(mStateMutex); + if (mState.current.buffer) { mReleasePreviousBuffer = true; } - mCurrentState.sequence++; - mCurrentState.buffer = buffer; - mCurrentState.modified = true; + mState.current.sequence++; + mState.current.buffer = buffer; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) { + Mutex::Autolock lock(mStateMutex); // The acquire fences of BufferStateLayers have already signaled before they are set mCallbackHandleAcquireTime = fence->getSignalTime(); - mCurrentState.acquireFence = fence; - mCurrentState.modified = true; + mState.current.acquireFence = fence; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) { - if (mCurrentState.dataspace == dataspace) return false; - mCurrentState.sequence++; - mCurrentState.dataspace = dataspace; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.dataspace == dataspace) return false; + mState.current.sequence++; + mState.current.dataspace = dataspace; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) { - if (mCurrentState.hdrMetadata == hdrMetadata) return false; - mCurrentState.sequence++; - mCurrentState.hdrMetadata = hdrMetadata; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.hdrMetadata == hdrMetadata) return false; + mState.current.sequence++; + mState.current.hdrMetadata = hdrMetadata; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) { - mCurrentState.sequence++; - mCurrentState.surfaceDamageRegion = surfaceDamage; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.sequence++; + mState.current.surfaceDamageRegion = surfaceDamage; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setApi(int32_t api) { - if (mCurrentState.api == api) return false; - mCurrentState.sequence++; - mCurrentState.api = api; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.api == api) return false; + mState.current.sequence++; + mState.current.api = api; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) { - if (mCurrentState.sidebandStream == sidebandStream) return false; - mCurrentState.sequence++; - mCurrentState.sidebandStream = sidebandStream; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + if (mState.current.sidebandStream == sidebandStream) return false; + mState.current.sequence++; + mState.current.sidebandStream = sidebandStream; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); if (!mSidebandStreamChanged.exchange(true)) { @@ -248,7 +260,10 @@ bool BufferStateLayer::setTransactionCompletedListeners( mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle); // Store so latched time and release fence can be set - mCurrentState.callbackHandles.push_back(handle); + { + Mutex::Autolock lock(mStateMutex); + mState.current.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 @@ -263,8 +278,9 @@ bool BufferStateLayer::setTransactionCompletedListeners( } bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) { - mCurrentState.transparentRegionHint = transparent; - mCurrentState.modified = true; + Mutex::Autolock lock(mStateMutex); + mState.current.transparentRegionHint = transparent; + mState.current.modified = true; setTransactionFlags(eTransactionNeeded); return true; } @@ -300,6 +316,7 @@ bool BufferStateLayer::fenceHasSignaled() const { return true; } + Mutex::Autolock lock(mStateMutex); return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled; } @@ -308,7 +325,7 @@ nsecs_t BufferStateLayer::getDesiredPresentTime() { return 0; } -std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const { +std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTimeLocked() const { return std::make_shared<FenceTime>(getDrawingState().acquireFence); } @@ -339,14 +356,17 @@ uint32_t BufferStateLayer::getDrawingScalingMode() const { } Region BufferStateLayer::getDrawingSurfaceDamage() const { + Mutex::Autolock lock(mStateMutex); return getDrawingState().surfaceDamageRegion; } const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const { + Mutex::Autolock lock(mStateMutex); return getDrawingState().hdrMetadata; } int BufferStateLayer::getDrawingApi() const { + Mutex::Autolock lock(mStateMutex); return getDrawingState().api; } @@ -371,6 +391,7 @@ bool BufferStateLayer::getSidebandStreamChanged() const { } std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) { + Mutex::Autolock lock(mStateMutex); if (mSidebandStreamChanged.exchange(false)) { const State& s(getDrawingState()); // mSidebandStreamChanged was true @@ -382,12 +403,12 @@ std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisib } recomputeVisibleRegions = true; - return getTransform().transform(Region(Rect(s.active.w, s.active.h))); + return getTransformLocked().transform(Region(Rect(s.active.w, s.active.h))); } return {}; } -bool BufferStateLayer::hasFrameUpdate() const { +bool BufferStateLayer::hasFrameUpdateLocked() const { return mCurrentStateModified && getCurrentState().buffer != nullptr; } @@ -397,6 +418,10 @@ void BufferStateLayer::setFilteringEnabled(bool enabled) { } status_t BufferStateLayer::bindTextureImage() { + Mutex::Autolock lock(mStateMutex); + return bindTextureImageLocked(); +} +status_t BufferStateLayer::bindTextureImageLocked() { const State& s(getDrawingState()); auto& engine(mFlinger->getRenderEngine()); @@ -501,7 +526,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse auto incomingStatus = releaseFence->getStatus(); if (incomingStatus == Fence::Status::Invalid) { ALOGE("New fence has invalid state"); - mDrawingState.acquireFence = releaseFence; + mState.drawing.acquireFence = releaseFence; mFlinger->mTimeStats->onDestroy(layerID); return BAD_VALUE; } @@ -512,16 +537,16 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse char fenceName[32] = {}; snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber); sp<Fence> mergedFence = - Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence); + Fence::merge(fenceName, mState.drawing.acquireFence, releaseFence); if (!mergedFence.get()) { ALOGE("failed to merge release fences"); // synchronization is broken, the best we can do is hope fences // signal in order so the new fence will act like a union - mDrawingState.acquireFence = releaseFence; + mState.drawing.acquireFence = releaseFence; mFlinger->mTimeStats->onDestroy(layerID); return BAD_VALUE; } - mDrawingState.acquireFence = mergedFence; + mState.drawing.acquireFence = mergedFence; } else if (incomingStatus == Fence::Status::Unsignaled) { // If one fence has signaled and the other hasn't, the unsignaled // fence will approximately correspond with the correct timestamp. @@ -530,7 +555,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse // by this point, they will have both signaled and only the timestamp // will be slightly off; any dependencies after this point will // already have been met. - mDrawingState.acquireFence = releaseFence; + mState.drawing.acquireFence = releaseFence; } } else { // Bind the new buffer to the GL texture. @@ -539,7 +564,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse // by glEGLImageTargetTexture2DOES, which this method calls. Newer // devices will either call this in Layer::onDraw, or (if it's not // a GL-composited layer) not at all. - status_t err = bindTextureImage(); + status_t err = bindTextureImageLocked(); if (err != NO_ERROR) { mFlinger->mTimeStats->onDestroy(layerID); return BAD_VALUE; @@ -548,7 +573,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse // TODO(marissaw): properly support mTimeStats mFlinger->mTimeStats->setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime); - mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime()); + mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTimeLocked()); mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime); return NO_ERROR; @@ -575,6 +600,7 @@ status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) { } void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) { + Mutex::Autolock lock(mStateMutex); auto& hwcInfo = getBE().mHwcLayers[displayId]; auto& hwcLayer = hwcInfo.layer; |