diff options
Diffstat (limited to 'services/surfaceflinger/Layer.cpp')
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 175 |
1 files changed, 155 insertions, 20 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 89e37b2f37..d13b6dbe19 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -51,6 +51,8 @@ #include "RenderEngine/RenderEngine.h" +#include <mutex> + #define DEBUG_RESIZE 0 namespace android { @@ -155,7 +157,8 @@ void Layer::onFirstRef() { sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); mProducer = new MonitoredProducer(producer, mFlinger); - mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName); + mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, + this); mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceFlingerConsumer->setContentsChangedListener(this); mSurfaceFlingerConsumer->setName(mName); @@ -554,7 +557,7 @@ void Layer::setGeometry( #endif activeCrop.clear(); } - activeCrop = s.active.transform.inverse().transform(activeCrop); + activeCrop = s.active.transform.inverse().transform(activeCrop, true); // This needs to be here as transform.transform(Rect) computes the // transformed rect and then takes the bounding box of the result before // returning. This means @@ -586,19 +589,25 @@ void Layer::setGeometry( const Transform& tr(displayDevice->getTransform()); Rect transformedFrame = tr.transform(frame); auto error = hwcLayer->setDisplayFrame(transformedFrame); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set display frame " - "[%d, %d, %d, %d]: %s (%d)", mName.string(), transformedFrame.left, - transformedFrame.top, transformedFrame.right, - transformedFrame.bottom, to_string(error).c_str(), - static_cast<int32_t>(error)); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", + mName.string(), transformedFrame.left, transformedFrame.top, + transformedFrame.right, transformedFrame.bottom, + to_string(error).c_str(), static_cast<int32_t>(error)); + } else { + hwcInfo.displayFrame = transformedFrame; + } FloatRect sourceCrop = computeCrop(displayDevice); error = hwcLayer->setSourceCrop(sourceCrop); - ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set source crop " - "[%.3f, %.3f, %.3f, %.3f]: %s (%d)", mName.string(), - sourceCrop.left, sourceCrop.top, sourceCrop.right, - sourceCrop.bottom, to_string(error).c_str(), - static_cast<int32_t>(error)); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: " + "%s (%d)", mName.string(), sourceCrop.left, sourceCrop.top, + sourceCrop.right, sourceCrop.bottom, to_string(error).c_str(), + static_cast<int32_t>(error)); + } else { + hwcInfo.sourceCrop = sourceCrop; + } error = hwcLayer->setPlaneAlpha(s.alpha); ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set plane alpha %.3f: " @@ -1113,6 +1122,20 @@ uint32_t Layer::getProducerStickyTransform() const { return static_cast<uint32_t>(producerStickyTransform); } +bool Layer::latchUnsignaledBuffers() { + static bool propertyLoaded = false; + static bool latch = false; + static std::mutex mutex; + std::lock_guard<std::mutex> lock(mutex); + if (!propertyLoaded) { + char value[PROPERTY_VALUE_MAX] = {}; + property_get("debug.sf.latch_unsignaled", value, "0"); + latch = atoi(value); + propertyLoaded = true; + } + return latch; +} + uint64_t Layer::getHeadFrameNumber() const { Mutex::Autolock lock(mQueueItemLock); if (!mQueueItems.empty()) { @@ -1122,6 +1145,29 @@ uint64_t Layer::getHeadFrameNumber() const { } } +bool Layer::headFenceHasSignaled() const { +#ifdef USE_HWC2 + if (latchUnsignaledBuffers()) { + return true; + } + + Mutex::Autolock lock(mQueueItemLock); + if (mQueueItems.empty()) { + return true; + } + if (mQueueItems[0].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 + // able to be latched. To avoid this, grab this buffer anyway. + return true; + } + return mQueueItems[0].mFence->getSignalTime() != INT64_MAX; +#else + return true; +#endif +} + bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) { if (point->getFrameNumber() <= mCurrentFrameNumber) { // Don't bother with a SyncPoint, since we've already latched the @@ -1384,9 +1430,10 @@ bool Layer::applyPendingStates(State* stateToCommit) { void Layer::notifyAvailableFrames() { auto headFrameNumber = getHeadFrameNumber(); + bool headFenceSignaled = headFenceHasSignaled(); Mutex::Autolock lock(mLocalSyncPointMutex); for (auto& point : mLocalSyncPoints) { - if (headFrameNumber >= point->getFrameNumber()) { + if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) { point->setFrameAvailable(); } } @@ -1596,11 +1643,15 @@ bool Layer::setFlags(uint8_t flags, uint8_t mask) { setTransactionFlags(eTransactionNeeded); return true; } -bool Layer::setCrop(const Rect& crop) { + +bool Layer::setCrop(const Rect& crop, bool immediate) { if (mCurrentState.crop == crop) return false; mCurrentState.sequence++; - mCurrentState.crop = crop; + mCurrentState.requestedCrop = crop; + if (immediate) { + mCurrentState.crop = crop; + } mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; @@ -1697,7 +1748,8 @@ bool Layer::onPreComposition() { return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; } -void Layer::onPostComposition() { +bool Layer::onPostComposition() { + bool frameLatencyNeeded = mFrameLatencyNeeded; if (mFrameLatencyNeeded) { nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); mFrameTracker.setDesiredPresentTime(desiredPresentTime); @@ -1729,6 +1781,7 @@ void Layer::onPostComposition() { mFrameTracker.advanceFrame(); mFrameLatencyNeeded = false; } + return frameLatencyNeeded; } #ifdef USE_HWC2 @@ -1777,6 +1830,13 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) return outDirtyRegion; } + // If the head buffer's acquire fence hasn't signaled yet, return and + // try again later + if (!headFenceHasSignaled()) { + mFlinger->signalLayerUpdate(); + return outDirtyRegion; + } + // Capture the old state of the layer for comparisons later const State& s(getDrawingState()); const bool oldOpacity = isOpaque(s); @@ -1789,16 +1849,19 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) bool stickyTransformSet; const char* name; int32_t overrideScalingMode; + bool& freezePositionUpdates; Reject(Layer::State& front, Layer::State& current, bool& recomputeVisibleRegions, bool stickySet, const char* name, - int32_t overrideScalingMode) + int32_t overrideScalingMode, + bool& freezePositionUpdates) : front(front), current(current), recomputeVisibleRegions(recomputeVisibleRegions), stickyTransformSet(stickySet), name(name), - overrideScalingMode(overrideScalingMode) { + overrideScalingMode(overrideScalingMode), + freezePositionUpdates(freezePositionUpdates) { } virtual bool reject(const sp<GraphicBuffer>& buf, @@ -1890,13 +1953,20 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) recomputeVisibleRegions = true; } + if (front.crop != front.requestedCrop) { + front.crop = front.requestedCrop; + current.crop = front.requestedCrop; + recomputeVisibleRegions = true; + } + freezePositionUpdates = false; + return false; } }; Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, getProducerStickyTransform() != 0, mName.string(), - mOverrideScalingMode); + mOverrideScalingMode, mFreezePositionUpdates); // Check all of our local sync points to ensure that all transactions @@ -2039,7 +2109,6 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) if (bufWidth != uint32_t(oldActiveBuffer->width) || bufHeight != uint32_t(oldActiveBuffer->height)) { recomputeVisibleRegions = true; - mFreezePositionUpdates = false; } } @@ -2170,6 +2239,54 @@ void Layer::dump(String8& result, Colorizer& colorizer) const } } +#ifdef USE_HWC2 +void Layer::miniDumpHeader(String8& result) { + result.append("----------------------------------------"); + result.append("---------------------------------------\n"); + result.append(" Layer name\n"); + result.append(" Z | "); + result.append(" Comp Type | "); + result.append(" Disp Frame (LTRB) | "); + result.append(" Source Crop (LTRB)\n"); + result.append("----------------------------------------"); + result.append("---------------------------------------\n"); +} + +void Layer::miniDump(String8& result, int32_t hwcId) const { + if (mHwcLayers.count(hwcId) == 0) { + return; + } + + String8 name; + if (mName.length() > 77) { + std::string shortened; + shortened.append(mName.string(), 36); + shortened.append("[...]"); + shortened.append(mName.string() + (mName.length() - 36), 36); + name = shortened.c_str(); + } else { + name = mName; + } + + result.appendFormat(" %s\n", name.string()); + + const Layer::State& layerState(getDrawingState()); + const HWCInfo& hwcInfo = mHwcLayers.at(hwcId); + result.appendFormat(" %10u | ", layerState.z); + result.appendFormat("%10s | ", + to_string(getCompositionType(hwcId)).c_str()); + const Rect& frame = hwcInfo.displayFrame; + result.appendFormat("%4d %4d %4d %4d | ", frame.left, frame.top, + frame.right, frame.bottom); + const FloatRect& crop = hwcInfo.sourceCrop; + result.appendFormat("%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, + crop.right, crop.bottom); + + result.append("- - - - - - - - - - - - - - - - - - - - "); + result.append("- - - - - - - - - - - - - - - - - - - -\n"); +} +#endif + void Layer::dumpFrameStats(String8& result) const { mFrameTracker.dumpStats(result); } @@ -2203,6 +2320,24 @@ void Layer::getFenceData(String8* outName, uint64_t* outFrameNumber, *outAcquireFence = mSurfaceFlingerConsumer->getCurrentFence(); *outPrevReleaseFence = mSurfaceFlingerConsumer->getPrevReleaseFence(); } + +std::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory( + bool forceFlush) { + std::vector<OccupancyTracker::Segment> history; + status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, + &history); + if (result != NO_ERROR) { + ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), + result); + return {}; + } + return history; +} + +bool Layer::getTransformToDisplayInverse() const { + return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); +} + // --------------------------------------------------------------------------- Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, |