diff options
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 175 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.h | 33 | ||||
| -rw-r--r-- | services/surfaceflinger/ColorLayer.cpp | 30 | ||||
| -rw-r--r-- | services/surfaceflinger/ColorLayer.h | 21 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 248 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 37 |
6 files changed, 249 insertions, 295 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 8f5dea2691..45093be1a3 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -53,6 +53,7 @@ namespace android { BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags), + mSurfaceFlingerConsumer(nullptr), mTextureName(-1U), mFormat(PIXEL_FORMAT_NONE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), @@ -99,6 +100,18 @@ BufferLayer::~BufferLayer() { #endif } +void BufferLayer::useSurfaceDamage() { + if (mFlinger->mForceFullDamage) { + surfaceDamageRegion = Region::INVALID_REGION; + } else { + surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); + } +} + +void BufferLayer::useEmptyDamage() { + surfaceDamageRegion.clear(); +} + bool BufferLayer::isProtected() const { const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); @@ -252,6 +265,54 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, engine.disableTexturing(); } +#ifdef USE_HWC2 +void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { + if (mHwcLayers.empty()) { + return; + } + mSurfaceFlingerConsumer->setReleaseFence(releaseFence); +} +#else +void BufferLayer::onLayerDisplayed(const sp<const DisplayDevice>& /*hw*/, + HWComposer::HWCLayerInterface* layer) { + if (layer) { + layer->onDisplayed(); + mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); + } +} +#endif + +void BufferLayer::abandon() { + mSurfaceFlingerConsumer->abandon(); +} + +bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const { + if (mSidebandStreamChanged || mAutoRefresh) { + return true; + } + + Mutex::Autolock lock(mQueueItemLock); + if (mQueueItems.empty()) { + return false; + } + auto timestamp = mQueueItems[0].mTimestamp; + nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); + + // Ignore timestamps more than a second in the future + bool isPlausible = timestamp < (expectedPresent + s2ns(1)); + ALOGW_IF(!isPlausible, + "[%s] Timestamp %" PRId64 " seems implausible " + "relative to expectedPresent %" PRId64, + mName.string(), timestamp, expectedPresent); + + bool isDue = timestamp < expectedPresent; + return isDue || !isPlausible; +} + +void BufferLayer::setTransformHint(uint32_t orientation) const { + mSurfaceFlingerConsumer->setTransformHint(orientation); +} + bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { if (mBufferLatched) { Mutex::Autolock lock(mFrameEventHistoryMutex); @@ -260,6 +321,60 @@ bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { mRefreshPending = false; return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; } +bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, + const std::shared_ptr<FenceTime>& presentFence, + const CompositorTiming& compositorTiming) { + // mFrameLatencyNeeded is true when a new frame was latched for the + // composition. + if (!mFrameLatencyNeeded) return false; + + // Update mFrameEventHistory. + { + Mutex::Autolock lock(mFrameEventHistoryMutex); + mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, + compositorTiming); + } + + // Update mFrameTracker. + nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); + mFrameTracker.setDesiredPresentTime(desiredPresentTime); + + std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); + if (frameReadyFence->isValid()) { + mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); + } else { + // There was no fence for this frame, so assume that it was ready + // to be presented at the desired present time. + mFrameTracker.setFrameReadyTime(desiredPresentTime); + } + + if (presentFence->isValid()) { + mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence)); + } else { + // The HWC doesn't support present fences, so use the refresh + // timestamp instead. + mFrameTracker.setActualPresentTime( + mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); + } + + mFrameTracker.advanceFrame(); + mFrameLatencyNeeded = false; + return true; +} + +std::vector<OccupancyTracker::Segment> BufferLayer::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 BufferLayer::getTransformToDisplayInverse() const { + return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); +} #ifdef USE_HWC2 void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { @@ -485,6 +600,10 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime return outDirtyRegion; } +void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) { + mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); +} + #ifdef USE_HWC2 void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { // Apply this display's projection's viewport to the visible region @@ -529,28 +648,6 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) return; } - // SolidColor layers - if (mActiveBuffer == nullptr) { - setCompositionType(hwcId, HWC2::Composition::SolidColor); - - // For now, we only support black for DimLayer - error = hwcLayer->setColor({0, 0, 0, 255}); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), - static_cast<int32_t>(error)); - } - - // Clear out the transform, because it doesn't make sense absent a - // source buffer - error = hwcLayer->setTransform(HWC2::Transform::None); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - } - - return; - } - // Device or Cursor layers if (mPotentialCursor) { ALOGV("[%s] Requesting Cursor composition", mName.string()); @@ -580,26 +677,24 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) } #else -void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& hw, +void BufferLayer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, HWComposer::HWCLayerInterface& layer) { - // we have to set the visible region on every frame because - // we currently free it during onLayerDisplayed(), which is called - // after HWComposer::commit() -- every frame. - // Apply this display's projection's viewport to the visible region - // before giving it to the HWC HAL. - const Transform& tr = hw->getTransform(); - Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); - layer.setVisibleRegionScreen(visible); - layer.setSurfaceDamage(surfaceDamageRegion); - mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER); - - if (mSidebandStream.get()) { - layer.setSidebandStream(mSidebandStream); - } else { - // NOTE: buffer can be NULL if the client never drew into this - // layer yet, or if we ran out of memory - layer.setBuffer(mActiveBuffer); + int fenceFd = -1; + + // TODO: there is a possible optimization here: we only need to set the + // acquire fence the first time a new buffer is acquired on EACH display. + + if (layer.getCompositionType() == HWC_OVERLAY || + layer.getCompositionType() == HWC_CURSOR_OVERLAY) { + sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); + if (fence->isValid()) { + fenceFd = fence->dup(); + if (fenceFd == -1) { + ALOGW("failed to dup layer fence, skipping sync: %d", errno); + } + } } + layer.setAcquireFenceFd(fenceFd); } #endif diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 882649ba70..418f032198 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -64,6 +64,12 @@ public: ~BufferLayer() override; + // If we have received a new buffer this frame, we will pass its surface + // damage down to hardware composer. Otherwise, we must send a region with + // one empty rect. + void useSurfaceDamage(); + void useEmptyDamage(); + // ----------------------------------------------------------------------- // Overriden from Layer // ----------------------------------------------------------------------- @@ -99,6 +105,23 @@ public: void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const override; +#ifdef USE_HWC2 + void onLayerDisplayed(const sp<Fence>& releaseFence) override; +#else + void onLayerDisplayed(const sp<const DisplayDevice>& hw, + HWComposer::HWCLayerInterface* layer) override; +#endif + + void abandon() override; + bool shouldPresentNow(const DispSync& dispSync) const override; + void setTransformHint(uint32_t orientation) const override; + bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, + const std::shared_ptr<FenceTime>& presentFence, + const CompositorTiming& compositorTiming) override; + std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override; + bool getTransformToDisplayInverse() const override; + +public: bool onPreComposition(nsecs_t refreshStartTime) override; #ifdef USE_HWC2 @@ -114,13 +137,15 @@ public: */ Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override; bool isBufferLatched() const override { return mRefreshPending; } + void setDefaultBufferSize(uint32_t w, uint32_t h) override; #ifdef USE_HWC2 - void setPerFrameData(const sp<const DisplayDevice>& displayDevice); + void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override; #else - void setPerFrameData(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer); + void setAcquireFence(const sp<const DisplayDevice>& hw, + HWComposer::HWCLayerInterface& layer) override; #endif + bool isOpaque(const Layer::State& s) const override; private: @@ -160,6 +185,8 @@ public: sp<IGraphicBufferProducer> getProducer() const; private: + sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer; + // Check all of the local sync points to ensure that all transactions // which need to have been applied prior to the frame which is about to // be latched have signaled diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 500f81f263..8a17f882d0 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -61,6 +61,36 @@ bool ColorLayer::isVisible() const { return !isHiddenByPolicy() && s.color.a; } +#ifdef USE_HWC2 +void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { + const Transform& tr = displayDevice->getTransform(); + const auto& viewport = displayDevice->getViewport(); + Region visible = tr.transform(visibleRegion.intersect(viewport)); + auto hwcId = displayDevice->getHwcDisplayId(); + auto& hwcInfo = mHwcLayers[hwcId]; + auto& hwcLayer = hwcInfo.layer; + auto error = hwcLayer->setVisibleRegion(visible); + + setCompositionType(hwcId, HWC2::Composition::SolidColor); + + half4 color = getColor(); + error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)), + static_cast<uint8_t>(std::round(255.0f * color.g)), + static_cast<uint8_t>(std::round(255.0f * color.b)), 255}); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), + static_cast<int32_t>(error)); + } + + // Clear out the transform, because it doesn't make sense absent a source buffer + error = hwcLayer->setTransform(HWC2::Transform::None); + if (error != HWC2::Error::None) { + ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(), + static_cast<int32_t>(error)); + } +} +#endif + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index 89013274af..debd3c3869 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -46,8 +46,29 @@ public: void releasePendingBuffer(nsecs_t) override {} #endif Region latchBuffer(bool&, nsecs_t) override { return Region(); } + void useSurfaceDamage() override {} + void useEmptyDamage() override {} bool isBufferLatched() const override { return false; } bool onPreComposition(nsecs_t) override { return true; } + void abandon() override {} +#ifdef USE_HWC2 + void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override; +#else + void setAcquireFence(const sp<const DisplayDevice>& /*hw*/, + HWComposer::HWCLayerInterface& /*layer*/) override {} +#endif + void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {} + bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; } + bool onPostComposition(const std::shared_ptr<FenceTime>& /*glDoneFence*/, + const std::shared_ptr<FenceTime>& /*presentFence*/, + const CompositorTiming& /*compositorTiming*/) override { + return false; + } + void setTransformHint(uint32_t /*orientation*/) const override {} + std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool /*forceFlush*/) override { + return {}; + } + bool getTransformToDisplayInverse() const override { return false; } }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index a318a8f46a..c823d67d9f 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -69,7 +69,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& n : contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), mFlinger(flinger), - mSurfaceFlingerConsumer(NULL), mPremultipliedAlpha(true), mName(name), mTransactionFlags(0), @@ -153,23 +152,16 @@ Layer::~Layer() { // callbacks // --------------------------------------------------------------------------- +/* + * onLayerDisplayed is only meaningful for BufferLayer, but, is called through + * Layer. So, the implementation is done in BufferLayer. When called on a + * ColorLayer object, it's essentially a NOP. + */ #ifdef USE_HWC2 -void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) { - if (mHwcLayers.empty()) { - return; - } - if (mSurfaceFlingerConsumer) { - mSurfaceFlingerConsumer->setReleaseFence(releaseFence); - } -} +void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {} #else void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, - HWComposer::HWCLayerInterface* layer) { - if (layer) { - layer->onDisplayed(); - mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); - } -} + HWComposer::HWCLayerInterface* /*layer*/) {} #endif void Layer::onRemovedFromCurrentState() { @@ -191,10 +183,8 @@ void Layer::onRemovedFromCurrentState() { void Layer::onRemoved() { // the layer is removed from SF mLayersPendingRemoval + abandon(); - if (mSurfaceFlingerConsumer) { - mSurfaceFlingerConsumer->abandon(); - } #ifdef USE_HWC2 destroyAllHwcLayers(); #endif @@ -690,105 +680,9 @@ void Layer::forceClientComposition(int32_t hwcId) { mHwcLayers[hwcId].forceClientComposition = true; } - -void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { - // Apply this display's projection's viewport to the visible region - // before giving it to the HWC HAL. - const Transform& tr = displayDevice->getTransform(); - const auto& viewport = displayDevice->getViewport(); - Region visible = tr.transform(visibleRegion.intersect(viewport)); - auto hwcId = displayDevice->getHwcDisplayId(); - auto& hwcInfo = mHwcLayers[hwcId]; - auto& hwcLayer = hwcInfo.layer; - auto error = hwcLayer->setVisibleRegion(visible); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - visible.dump(LOG_TAG); - } - - error = hwcLayer->setSurfaceDamage(surfaceDamageRegion); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - surfaceDamageRegion.dump(LOG_TAG); - } - - // Sideband layers - if (mSidebandStream.get()) { - setCompositionType(hwcId, HWC2::Composition::Sideband); - ALOGV("[%s] Requesting Sideband composition", mName.string()); - error = hwcLayer->setSidebandStream(mSidebandStream->handle()); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(), - mSidebandStream->handle(), to_string(error).c_str(), static_cast<int32_t>(error)); - } - return; - } - - // Client layers - if (hwcInfo.forceClientComposition || - (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) { - ALOGV("[%s] Requesting Client composition", mName.string()); - setCompositionType(hwcId, HWC2::Composition::Client); - return; - } - - // SolidColor layers - if (mActiveBuffer == nullptr) { - setCompositionType(hwcId, HWC2::Composition::SolidColor); - - half4 color = getColor(); - error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)), - static_cast<uint8_t>(std::round(255.0f * color.g)), - static_cast<uint8_t>(std::round(255.0f * color.b)), 255}); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(), - static_cast<int32_t>(error)); - } - - // Clear out the transform, because it doesn't make sense absent a - // source buffer - error = hwcLayer->setTransform(HWC2::Transform::None); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), - to_string(error).c_str(), static_cast<int32_t>(error)); - } - - return; - } - - // Device or Cursor layers - if (mPotentialCursor) { - ALOGV("[%s] Requesting Cursor composition", mName.string()); - setCompositionType(hwcId, HWC2::Composition::Cursor); - } else { - ALOGV("[%s] Requesting Device composition", mName.string()); - setCompositionType(hwcId, HWC2::Composition::Device); - } - - ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace); - error = hwcLayer->setDataspace(mCurrentState.dataSpace); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace, - to_string(error).c_str(), static_cast<int32_t>(error)); - } - - uint32_t hwcSlot = 0; - sp<GraphicBuffer> hwcBuffer; - hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer); - - auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence(); - error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence); - if (error != HWC2::Error::None) { - ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle, - to_string(error).c_str(), static_cast<int32_t>(error)); - } -} - #else void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer) { + HWComposer::HWCLayerInterface& layer) { // we have to set the visible region on every frame because // we currently free it during onLayerDisplayed(), which is called // after HWComposer::commit() -- every frame. @@ -810,6 +704,7 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, } #endif + #ifdef USE_HWC2 void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) { auto hwcId = displayDevice->getHwcDisplayId(); @@ -844,26 +739,6 @@ void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) { static_cast<int32_t>(error)); } #else -void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, - HWComposer::HWCLayerInterface& layer) { - int fenceFd = -1; - - // TODO: there is a possible optimization here: we only need to set the - // acquire fence the first time a new buffer is acquired on EACH display. - - if (layer.getCompositionType() == HWC_OVERLAY || - layer.getCompositionType() == HWC_CURSOR_OVERLAY) { - sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); - if (fence->isValid()) { - fenceFd = fence->dup(); - if (fenceFd == -1) { - ALOGW("failed to dup layer fence, skipping sync: %d", errno); - } - } - } - layer.setAcquireFenceFd(fenceFd); -} - Rect Layer::getPosition(const sp<const DisplayDevice>& hw) { // this gives us only the "orientation" component of the transform const State& s(getCurrentState()); @@ -1176,7 +1051,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h); - if (mSurfaceFlingerConsumer && sizeChanged) { + if (sizeChanged) { // the size changed, we need to ask our client to request a new buffer ALOGD_IF(DEBUG_RESIZE, "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" @@ -1192,7 +1067,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { // record the new size, form this point on, when the client request // a buffer, it'll get the new size. - mSurfaceFlingerConsumer->setDefaultBufferSize(c.requested.w, c.requested.h); + setDefaultBufferSize(c.requested.w, c.requested.h); } // Don't let Layer::doTransaction update the drawing state @@ -1527,86 +1402,11 @@ void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t fra deferTransactionUntil(handle->owner.promote(), frameNumber); } -void Layer::useSurfaceDamage() { - if (mFlinger->mForceFullDamage) { - surfaceDamageRegion = Region::INVALID_REGION; - } else { - surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); - } -} - -void Layer::useEmptyDamage() { - surfaceDamageRegion.clear(); -} // ---------------------------------------------------------------------------- // pageflip handling... // ---------------------------------------------------------------------------- -bool Layer::shouldPresentNow(const DispSync& dispSync) const { - if (mSidebandStreamChanged || mAutoRefresh) { - return true; - } - - Mutex::Autolock lock(mQueueItemLock); - if (mQueueItems.empty()) { - return false; - } - auto timestamp = mQueueItems[0].mTimestamp; - nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); - - // Ignore timestamps more than a second in the future - bool isPlausible = timestamp < (expectedPresent + s2ns(1)); - ALOGW_IF(!isPlausible, - "[%s] Timestamp %" PRId64 " seems implausible " - "relative to expectedPresent %" PRId64, - mName.string(), timestamp, expectedPresent); - - bool isDue = timestamp < expectedPresent; - return isDue || !isPlausible; -} - -bool Layer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, - const std::shared_ptr<FenceTime>& presentFence, - const CompositorTiming& compositorTiming) { - // mFrameLatencyNeeded is true when a new frame was latched for the - // composition. - if (!mFrameLatencyNeeded) return false; - - // Update mFrameEventHistory. - { - Mutex::Autolock lock(mFrameEventHistoryMutex); - mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, - compositorTiming); - } - - // Update mFrameTracker. - nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); - mFrameTracker.setDesiredPresentTime(desiredPresentTime); - - std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); - if (frameReadyFence->isValid()) { - mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); - } else { - // There was no fence for this frame, so assume that it was ready - // to be presented at the desired present time. - mFrameTracker.setFrameReadyTime(desiredPresentTime); - } - - if (presentFence->isValid()) { - mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence)); - } else { - // The HWC doesn't support present fences, so use the refresh - // timestamp instead. - mFrameTracker.setActualPresentTime( - mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); - } - - mFrameTracker.advanceFrame(); - mFrameLatencyNeeded = false; - return true; -} - bool Layer::isHiddenByPolicy() const { const Layer::State& s(mDrawingState); const auto& parent = mDrawingParent.promote(); @@ -1641,9 +1441,7 @@ void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { orientation = 0; } } - if (mSurfaceFlingerConsumer) { - mSurfaceFlingerConsumer->setTransformHint(orientation); - } + setTransformHint(orientation); } // ---------------------------------------------------------------------------- @@ -1788,26 +1586,6 @@ void Layer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, } } -std::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(bool forceFlush) { - std::vector<OccupancyTracker::Segment> history; - - if (!mSurfaceFlingerConsumer) return {}; - - 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 { - if (mSurfaceFlingerConsumer) { - return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); - } - return false; -} - size_t Layer::getChildrenCount() const { size_t count = 0; for (const sp<Layer>& child : mCurrentChildren) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index db94a31c5e..004d22057b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -42,7 +42,6 @@ #include "LayerVector.h" #include "MonitoredProducer.h" #include "SurfaceFlinger.h" -#include "SurfaceFlingerConsumer.h" #include "Transform.h" #include <layerproto/LayerProtoHeader.h> @@ -230,8 +229,8 @@ public: // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with // one empty rect. - void useSurfaceDamage(); - void useEmptyDamage(); + virtual void useSurfaceDamage() = 0; + virtual void useEmptyDamage() = 0; uint32_t getTransactionFlags(uint32_t flags); uint32_t setTransactionFlags(uint32_t flags); @@ -294,10 +293,12 @@ protected: bool useIdentityTransform) const = 0; public: + virtual void setDefaultBufferSize(uint32_t w, uint32_t h) = 0; + #ifdef USE_HWC2 void setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z); void forceClientComposition(int32_t hwcId); - void setPerFrameData(const sp<const DisplayDevice>& displayDevice); + virtual void setPerFrameData(const sp<const DisplayDevice>& displayDevice) = 0; // callIntoHwc exists so we can update our local state and call // acceptDisplayChanges without unnecessarily updating the device's state @@ -309,8 +310,8 @@ public: #else void setGeometry(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); void setPerFrameData(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); - void setAcquireFence(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer); + virtual void setAcquireFence(const sp<const DisplayDevice>& hw, + HWComposer::HWCLayerInterface& layer) = 0; Rect getPosition(const sp<const DisplayDevice>& hw); #endif @@ -318,12 +319,16 @@ public: * called after page-flip */ #ifdef USE_HWC2 - void onLayerDisplayed(const sp<Fence>& releaseFence); + virtual void onLayerDisplayed(const sp<Fence>& releaseFence); #else - void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer); + virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw, + HWComposer::HWCLayerInterface* layer); #endif - bool shouldPresentNow(const DispSync& dispSync) const; + virtual void abandon() = 0; + + virtual bool shouldPresentNow(const DispSync& dispSync) const = 0; + virtual void setTransformHint(uint32_t orientation) const = 0; /* * called before composition. @@ -335,9 +340,9 @@ public: * called after composition. * returns true if the layer latched a new buffer this frame. */ - bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, - const std::shared_ptr<FenceTime>& presentFence, - const CompositorTiming& compositorTiming); + virtual bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, + const std::shared_ptr<FenceTime>& presentFence, + const CompositorTiming& compositorTiming) = 0; #ifdef USE_HWC2 // If a buffer was replaced this frame, release the former buffer @@ -461,13 +466,13 @@ public: void logFrameStats(); void getFrameStats(FrameStats* outStats) const; - std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush); + virtual std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) = 0; void onDisconnect(); void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry, FrameEventHistoryDelta* outDelta); - bool getTransformToDisplayInverse() const; + virtual bool getTransformToDisplayInverse() const = 0; Transform getTransform() const; @@ -524,6 +529,7 @@ protected: virtual void onFirstRef(); friend class SurfaceInterceptor; + void commitTransaction(const State& stateToCommit); uint32_t getEffectiveUsage(uint32_t usage) const; @@ -545,7 +551,6 @@ protected: void addZOrderRelative(const wp<Layer>& relative); void removeZOrderRelative(const wp<Layer>& relative); -protected: class SyncPoint { public: explicit SyncPoint(uint64_t frameNumber) @@ -617,8 +622,6 @@ public: protected: // ----------------------------------------------------------------------- - // constants - sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer; bool mPremultipliedAlpha; String8 mName; String8 mTransactionName; // A cached version of "TX - " + mName for systraces |