diff options
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 635 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 32 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/Android.bp | 1 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp | 44 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/LayerTest.cpp | 86 |
5 files changed, 44 insertions, 754 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0d9004f7ed..ed2ad7d221 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2306,37 +2306,6 @@ void SurfaceFlinger::configure() { } } -bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs, - bool flushTransactions, - bool& outTransactionsAreEmpty) { - SFTRACE_CALL(); - frontend::Update update; - if (flushTransactions) { - update = flushLifecycleUpdates(); - if (mTransactionTracing) { - mTransactionTracing->addCommittedTransactions(ftl::to_underlying(vsyncId), frameTimeNs, - update, mFrontEndDisplayInfos, - mFrontEndDisplayInfosChanged); - } - } - - bool needsTraversal = false; - if (flushTransactions) { - needsTraversal |= commitMirrorDisplays(vsyncId); - needsTraversal |= commitCreatedLayers(vsyncId, update.layerCreatedStates); - needsTraversal |= applyTransactions(update.transactions, vsyncId); - } - outTransactionsAreEmpty = !needsTraversal; - const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal; - if (shouldCommit) { - commitTransactionsLegacy(); - } - - bool mustComposite = latchBuffers() || shouldCommit; - updateLayerGeometry(); - return mustComposite; -} - void SurfaceFlinger::updateLayerHistory(nsecs_t now) { for (const auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) { using Changes = frontend::RequestedLayerState::Changes; @@ -3006,21 +2975,6 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( return resultsPerDisplay; } -void SurfaceFlinger::updateLayerGeometry() { - SFTRACE_CALL(); - - if (mVisibleRegionsDirty) { - computeLayerBounds(); - } - - for (auto& layer : mLayersPendingRefresh) { - Region visibleReg; - visibleReg.set(layer->getScreenBounds()); - invalidateLayerStack(layer->getOutputFilter(), visibleReg); - } - mLayersPendingRefresh.clear(); -} - bool SurfaceFlinger::isHdrLayer(const frontend::LayerSnapshot& snapshot) const { // Even though the camera layer may be using an HDR transfer function or otherwise be "HDR" // the device may need to avoid boosting the brightness as a result of these layers to @@ -3333,36 +3287,6 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, logFrameStats(presentTime); } -FloatRect SurfaceFlinger::getMaxDisplayBounds() { - const ui::Size maxSize = [this] { - ftl::FakeGuard guard(mStateLock); - - // The LayerTraceGenerator tool runs without displays. - if (mDisplays.empty()) return ui::Size{5000, 5000}; - - return std::accumulate(mDisplays.begin(), mDisplays.end(), ui::kEmptySize, - [](ui::Size size, const auto& pair) -> ui::Size { - const auto& display = pair.second; - return {std::max(size.getWidth(), display->getWidth()), - std::max(size.getHeight(), display->getHeight())}; - }); - }(); - - // Ignore display bounds for now since they will be computed later. Use a large Rect bound - // to ensure it's bigger than an actual display will be. - const float xMax = maxSize.getWidth() * 10.f; - const float yMax = maxSize.getHeight() * 10.f; - - return {-xMax, -yMax, xMax, yMax}; -} - -void SurfaceFlinger::computeLayerBounds() { - const FloatRect maxBounds = getMaxDisplayBounds(); - for (const auto& layer : mDrawingState.layersSortedByZ) { - layer->computeBounds(maxBounds, ui::Transform(), 0.f /* shadowRadius */); - } -} - void SurfaceFlinger::commitTransactions() { SFTRACE_CALL(); mDebugInTransaction = systemTime(); @@ -3376,28 +3300,6 @@ void SurfaceFlinger::commitTransactions() { mDebugInTransaction = 0; } -void SurfaceFlinger::commitTransactionsLegacy() { - SFTRACE_CALL(); - - // Keep a copy of the drawing state (that is going to be overwritten - // by commitTransactionsLocked) outside of mStateLock so that the side - // effects of the State assignment don't happen with mStateLock held, - // which can cause deadlocks. - State drawingState(mDrawingState); - - Mutex::Autolock lock(mStateLock); - mDebugInTransaction = systemTime(); - - // Here we're guaranteed that some transaction flags are set - // so we can call commitTransactionsLocked unconditionally. - // We clear the flags with mStateLock held to guarantee that - // mCurrentState won't change until the transaction is committed. - mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit); - commitTransactionsLocked(clearTransactionFlags(eTransactionMask)); - - mDebugInTransaction = 0; -} - std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes( PhysicalDisplayId displayId) const { std::vector<HWComposer::HWCDisplayMode> hwcModes; @@ -4598,97 +4500,6 @@ void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, co } } -bool SurfaceFlinger::latchBuffers() { - SFTRACE_CALL(); - - const nsecs_t latchTime = systemTime(); - - bool visibleRegions = false; - bool frameQueued = false; - bool newDataLatched = false; - - // Store the set of layers that need updates. This set must not change as - // buffers are being latched, as this could result in a deadlock. - // Example: Two producers share the same command stream and: - // 1.) Layer 0 is latched - // 2.) Layer 0 gets a new frame - // 2.) Layer 1 gets a new frame - // 3.) Layer 1 is latched. - // Display is now waiting on Layer 1's frame, which is behind layer 0's - // second frame. But layer 0's second frame could be waiting on display. - mDrawingState.traverse([&](Layer* layer) { - if (layer->clearTransactionFlags(eTransactionNeeded) || mForceTransactionDisplayChange) { - const uint32_t flags = layer->doTransaction(0); - if (flags & Layer::eVisibleRegion) { - mVisibleRegionsDirty = true; - } - } - - if (layer->hasReadyFrame() || layer->willReleaseBufferOnLatch()) { - frameQueued = true; - mLayersWithQueuedFrames.emplace(sp<Layer>::fromExisting(layer)); - } else { - layer->useEmptyDamage(); - if (!layer->hasBuffer()) { - // The last latch time is used to classify a missed frame as buffer stuffing - // instead of a missed frame. This is used to identify scenarios where we - // could not latch a buffer or apply a transaction due to backpressure. - // We only update the latch time for buffer less layers here, the latch time - // is updated for buffer layers when the buffer is latched. - layer->updateLastLatchTime(latchTime); - } - } - }); - mForceTransactionDisplayChange = false; - - // The client can continue submitting buffers for offscreen layers, but they will not - // be shown on screen. Therefore, we need to latch and release buffers of offscreen - // layers to ensure dequeueBuffer doesn't block indefinitely. - for (Layer* offscreenLayer : mOffscreenLayers) { - offscreenLayer->traverse(LayerVector::StateSet::Drawing, - [&](Layer* l) { l->latchAndReleaseBuffer(); }); - } - - if (!mLayersWithQueuedFrames.empty()) { - // mStateLock is needed for latchBuffer as LayerRejecter::reject() - // writes to Layer current state. See also b/119481871 - Mutex::Autolock lock(mStateLock); - - for (const auto& layer : mLayersWithQueuedFrames) { - if (layer->willReleaseBufferOnLatch()) { - mLayersWithBuffersRemoved.emplace(layer); - } - if (layer->latchBuffer(visibleRegions, latchTime)) { - mLayersPendingRefresh.push_back(layer); - newDataLatched = true; - } - layer->useSurfaceDamage(); - } - } - - mVisibleRegionsDirty |= visibleRegions; - - // If we will need to wake up at some time in the future to deal with a - // queued frame that shouldn't be displayed during this vsync period, wake - // up during the next vsync period to check again. - if (frameQueued && (mLayersWithQueuedFrames.empty() || !newDataLatched)) { - scheduleCommit(FrameHint::kNone); - } - - // enter boot animation on first buffer latch - if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) { - ALOGI("Enter boot animation"); - mBootStage = BootStage::BOOTANIMATION; - } - - if (mLayerMirrorRoots.size() > 0) { - mDrawingState.traverse([&](Layer* layer) { layer->updateCloneBufferInfo(); }); - } - - // Only continue with the refresh if there is actually new work to do - return !mLayersWithQueuedFrames.empty() && newDataLatched; -} - status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle, const sp<Layer>& layer, const wp<Layer>& parent, uint32_t* outTransformHint) { @@ -5328,364 +5139,6 @@ bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermis return true; } -uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo, - ResolvedComposerState& composerState, - int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint64_t transactionId) { - layer_state_t& s = composerState.state; - - std::vector<ListenerCallbacks> filteredListeners; - for (auto& listener : s.listeners) { - // Starts a registration but separates the callback ids according to callback type. This - // allows the callback invoker to send on latch callbacks earlier. - // note that startRegistration will not re-register if the listener has - // already be registered for a prior surface control - - ListenerCallbacks onCommitCallbacks = listener.filter(CallbackId::Type::ON_COMMIT); - if (!onCommitCallbacks.callbackIds.empty()) { - filteredListeners.push_back(onCommitCallbacks); - } - - ListenerCallbacks onCompleteCallbacks = listener.filter(CallbackId::Type::ON_COMPLETE); - if (!onCompleteCallbacks.callbackIds.empty()) { - filteredListeners.push_back(onCompleteCallbacks); - } - } - - const uint64_t what = s.what; - uint32_t flags = 0; - sp<Layer> layer = nullptr; - if (s.surface) { - layer = LayerHandle::getLayer(s.surface); - } else { - // The client may provide us a null handle. Treat it as if the layer was removed. - ALOGW("Attempt to set client state with a null layer handle"); - } - if (layer == nullptr) { - for (auto& [listener, callbackIds] : s.listeners) { - mTransactionCallbackInvoker.addCallbackHandle( - sp<CallbackHandle>::make(listener, callbackIds, s.surface)); - } - return 0; - } - MUTEX_ALIAS(mStateLock, layer->mFlinger->mStateLock); - - ui::LayerStack oldLayerStack = layer->getLayerStack(LayerVector::StateSet::Current); - - // Only set by BLAST adapter layers - if (what & layer_state_t::eProducerDisconnect) { - layer->onDisconnect(); - } - - if (what & layer_state_t::ePositionChanged) { - if (layer->setPosition(s.x, s.y)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eLayerChanged) { - // NOTE: index needs to be calculated before we update the state - const auto& p = layer->getParent(); - if (p == nullptr) { - ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); - if (layer->setLayer(s.z) && idx >= 0) { - mCurrentState.layersSortedByZ.removeAt(idx); - mCurrentState.layersSortedByZ.add(layer); - // we need traversal (state changed) - // AND transaction (list changed) - flags |= eTransactionNeeded|eTraversalNeeded; - } - } else { - if (p->setChildLayer(layer, s.z)) { - flags |= eTransactionNeeded|eTraversalNeeded; - } - } - } - if (what & layer_state_t::eRelativeLayerChanged) { - // NOTE: index needs to be calculated before we update the state - const auto& p = layer->getParent(); - const auto& relativeHandle = s.relativeLayerSurfaceControl ? - s.relativeLayerSurfaceControl->getHandle() : nullptr; - if (p == nullptr) { - ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); - if (layer->setRelativeLayer(relativeHandle, s.z) && - idx >= 0) { - mCurrentState.layersSortedByZ.removeAt(idx); - mCurrentState.layersSortedByZ.add(layer); - // we need traversal (state changed) - // AND transaction (list changed) - flags |= eTransactionNeeded|eTraversalNeeded; - } - } else { - if (p->setChildRelativeLayer(layer, relativeHandle, s.z)) { - flags |= eTransactionNeeded|eTraversalNeeded; - } - } - } - if (what & layer_state_t::eAlphaChanged) { - if (layer->setAlpha(s.color.a)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eColorChanged) { - if (layer->setColor(s.color.rgb)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eColorTransformChanged) { - if (layer->setColorTransform(s.colorTransform)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eBackgroundColorChanged) { - if (layer->setBackgroundColor(s.bgColor.rgb, s.bgColor.a, s.bgColorDataspace)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eMatrixChanged) { - if (layer->setMatrix(s.matrix)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eTransparentRegionChanged) { - if (layer->setTransparentRegionHint(s.transparentRegion)) - flags |= eTraversalNeeded; - } - if (what & layer_state_t::eFlagsChanged) { - if (layer->setFlags(s.flags, s.mask)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eCornerRadiusChanged) { - if (layer->setCornerRadius(s.cornerRadius)) - flags |= eTraversalNeeded; - } - if (what & layer_state_t::eBackgroundBlurRadiusChanged && mSupportsBlur) { - if (layer->setBackgroundBlurRadius(s.backgroundBlurRadius)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eBlurRegionsChanged) { - if (layer->setBlurRegions(s.blurRegions)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eLayerStackChanged) { - ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); - // We only allow setting layer stacks for top level layers, - // everything else inherits layer stack from its parent. - if (layer->hasParent()) { - ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid", - layer->getDebugName()); - } else if (idx < 0) { - ALOGE("Attempt to set layer stack on layer without parent (%s) that " - "that also does not appear in the top level layer list. Something" - " has gone wrong.", - layer->getDebugName()); - } else if (layer->setLayerStack(s.layerStack)) { - mCurrentState.layersSortedByZ.removeAt(idx); - mCurrentState.layersSortedByZ.add(layer); - // we need traversal (state changed) - // AND transaction (list changed) - flags |= eTransactionNeeded | eTraversalNeeded | eTransformHintUpdateNeeded; - } - } - if (what & layer_state_t::eBufferTransformChanged) { - if (layer->setTransform(s.bufferTransform)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eTransformToDisplayInverseChanged) { - if (layer->setTransformToDisplayInverse(s.transformToDisplayInverse)) - flags |= eTraversalNeeded; - } - if (what & layer_state_t::eCropChanged) { - if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eDataspaceChanged) { - if (layer->setDataspace(s.dataspace)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eSurfaceDamageRegionChanged) { - if (layer->setSurfaceDamageRegion(s.surfaceDamageRegion)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eApiChanged) { - if (layer->setApi(s.api)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eSidebandStreamChanged) { - if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime)) - flags |= eTraversalNeeded; - } - if (what & layer_state_t::eInputInfoChanged) { - layer->setInputInfo(*s.windowInfoHandle->getInfo()); - flags |= eTraversalNeeded; - } - if (what & layer_state_t::eMetadataChanged) { - if (const int32_t gameMode = s.metadata.getInt32(gui::METADATA_GAME_MODE, -1); - gameMode != -1) { - // The transaction will be received on the Task layer and needs to be applied to all - // child layers. Child layers that are added at a later point will obtain the game mode - // info through addChild(). - layer->setGameModeForTree(static_cast<GameMode>(gameMode)); - } - - if (layer->setMetadata(s.metadata)) { - flags |= eTraversalNeeded; - mLayerMetadataSnapshotNeeded = true; - } - } - if (what & layer_state_t::eColorSpaceAgnosticChanged) { - if (layer->setColorSpaceAgnostic(s.colorSpaceAgnostic)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eShadowRadiusChanged) { - if (layer->setShadowRadius(s.shadowRadius)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eDefaultFrameRateCompatibilityChanged) { - const auto compatibility = - Layer::FrameRate::convertCompatibility(s.defaultFrameRateCompatibility); - - if (layer->setDefaultFrameRateCompatibility(compatibility)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eFrameRateSelectionPriority) { - if (layer->setFrameRateSelectionPriority(s.frameRateSelectionPriority)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eFrameRateChanged) { - const auto compatibility = - Layer::FrameRate::convertCompatibility(s.frameRateCompatibility); - const auto strategy = - Layer::FrameRate::convertChangeFrameRateStrategy(s.changeFrameRateStrategy); - - if (layer->setFrameRate(Layer::FrameRate::FrameRateVote(Fps::fromValue(s.frameRate), - compatibility, strategy))) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eFrameRateCategoryChanged) { - const FrameRateCategory category = Layer::FrameRate::convertCategory(s.frameRateCategory); - if (layer->setFrameRateCategory(category, s.frameRateCategorySmoothSwitchOnly)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eFrameRateSelectionStrategyChanged) { - const scheduler::LayerInfo::FrameRateSelectionStrategy strategy = - scheduler::LayerInfo::convertFrameRateSelectionStrategy( - s.frameRateSelectionStrategy); - if (layer->setFrameRateSelectionStrategy(strategy)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eFixedTransformHintChanged) { - if (layer->setFixedTransformHint(s.fixedTransformHint)) { - flags |= eTraversalNeeded | eTransformHintUpdateNeeded; - } - } - if (what & layer_state_t::eAutoRefreshChanged) { - layer->setAutoRefresh(s.autoRefresh); - } - if (what & layer_state_t::eDimmingEnabledChanged) { - if (layer->setDimmingEnabled(s.dimmingEnabled)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eExtendedRangeBrightnessChanged) { - if (layer->setExtendedRangeBrightness(s.currentHdrSdrRatio, s.desiredHdrSdrRatio)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eDesiredHdrHeadroomChanged) { - if (layer->setDesiredHdrHeadroom(s.desiredHdrSdrRatio)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eCachingHintChanged) { - if (layer->setCachingHint(s.cachingHint)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eHdrMetadataChanged) { - if (layer->setHdrMetadata(s.hdrMetadata)) flags |= eTraversalNeeded; - } - if (what & layer_state_t::eTrustedOverlayChanged) { - if (layer->setTrustedOverlay(s.trustedOverlay == gui::TrustedOverlay::ENABLED)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eStretchChanged) { - if (layer->setStretchEffect(s.stretchEffect)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eBufferCropChanged) { - if (layer->setBufferCrop(s.bufferCrop)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eDestinationFrameChanged) { - if (layer->setDestinationFrame(s.destinationFrame)) { - flags |= eTraversalNeeded; - } - } - if (what & layer_state_t::eDropInputModeChanged) { - if (layer->setDropInputMode(s.dropInputMode)) { - flags |= eTraversalNeeded; - mUpdateInputInfo = true; - } - } - // This has to happen after we reparent children because when we reparent to null we remove - // child layers from current state and remove its relative z. If the children are reparented in - // the same transaction, then we have to make sure we reparent the children first so we do not - // lose its relative z order. - if (what & layer_state_t::eReparent) { - bool hadParent = layer->hasParent(); - auto parentHandle = (s.parentSurfaceControlForChild) - ? s.parentSurfaceControlForChild->getHandle() - : nullptr; - if (layer->reparent(parentHandle)) { - if (!hadParent) { - layer->setIsAtRoot(false); - mCurrentState.layersSortedByZ.remove(layer); - } - flags |= eTransactionNeeded | eTraversalNeeded; - } - } - std::vector<sp<CallbackHandle>> callbackHandles; - if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!filteredListeners.empty())) { - for (auto& [listener, callbackIds] : filteredListeners) { - callbackHandles.emplace_back( - sp<CallbackHandle>::make(listener, callbackIds, s.surface)); - } - } - - if (what & layer_state_t::eBufferChanged) { - if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime, - desiredPresentTime, isAutoTimestamp, frameTimelineInfo)) { - flags |= eTraversalNeeded; - } - } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { - layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime); - } - - if ((what & layer_state_t::eBufferChanged) == 0) { - layer->setDesiredPresentTime(desiredPresentTime, isAutoTimestamp); - } - - if (what & layer_state_t::eTrustedPresentationInfoChanged) { - if (layer->setTrustedPresentationInfo(s.trustedPresentationThresholds, - s.trustedPresentationListener)) { - flags |= eTraversalNeeded; - } - } - - if (what & layer_state_t::eFlushJankData) { - // Do nothing. Processing the transaction completed listeners currently cause the flush. - } - - if (layer->setTransactionCompletedListeners(callbackHandles, - layer->willPresentCurrentTransaction() || - layer->willReleaseBufferOnLatch())) { - flags |= eTraversalNeeded; - } - - // Do not put anything that updates layer state or modifies flags after - // setTransactionCompletedListener - - // if the layer has been parented on to a new display, update its transform hint. - if (((flags & eTransformHintUpdateNeeded) == 0) && - oldLayerStack != layer->getLayerStack(LayerVector::StateSet::Current)) { - flags |= eTransformHintUpdateNeeded; - } - - return flags; -} - uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& frameTimelineInfo, ResolvedComposerState& composerState, int64_t desiredPresentTime, @@ -9033,67 +8486,6 @@ std::shared_ptr<renderengine::ExternalTexture> SurfaceFlinger::getExternalTextur return nullptr; } -bool SurfaceFlinger::commitMirrorDisplays(VsyncId vsyncId) { - std::vector<MirrorDisplayState> mirrorDisplays; - { - std::scoped_lock<std::mutex> lock(mMirrorDisplayLock); - mirrorDisplays = std::move(mMirrorDisplays); - mMirrorDisplays.clear(); - if (mirrorDisplays.size() == 0) { - return false; - } - } - - sp<IBinder> unused; - for (const auto& mirrorDisplay : mirrorDisplays) { - // Set mirror layer's default layer stack to -1 so it doesn't end up rendered on a display - // accidentally. - sp<Layer> rootMirrorLayer = LayerHandle::getLayer(mirrorDisplay.rootHandle); - ssize_t idx = mCurrentState.layersSortedByZ.indexOf(rootMirrorLayer); - bool ret = rootMirrorLayer->setLayerStack(ui::LayerStack::fromValue(-1)); - if (idx >= 0 && ret) { - mCurrentState.layersSortedByZ.removeAt(idx); - mCurrentState.layersSortedByZ.add(rootMirrorLayer); - } - - for (const auto& layer : mDrawingState.layersSortedByZ) { - if (layer->getLayerStack() != mirrorDisplay.layerStack || - layer->isInternalDisplayOverlay()) { - continue; - } - - LayerCreationArgs mirrorArgs(this, mirrorDisplay.client, "MirrorLayerParent", - ISurfaceComposerClient::eNoColorFill, - gui::LayerMetadata()); - sp<Layer> childMirror; - { - Mutex::Autolock lock(mStateLock); - createEffectLayer(mirrorArgs, &unused, &childMirror); - MUTEX_ALIAS(mStateLock, childMirror->mFlinger->mStateLock); - childMirror->setClonedChild(layer->createClone()); - childMirror->reparent(mirrorDisplay.rootHandle); - } - // lock on mStateLock needs to be released before binder handle gets destroyed - unused.clear(); - } - } - return true; -} - -bool SurfaceFlinger::commitCreatedLayers(VsyncId vsyncId, - std::vector<LayerCreatedState>& createdLayers) { - if (createdLayers.size() == 0) { - return false; - } - - Mutex::Autolock _l(mStateLock); - for (const auto& createdLayer : createdLayers) { - handleLayerCreatedLocked(createdLayer, vsyncId); - } - mLayersAdded = true; - return mLayersAdded; -} - void SurfaceFlinger::updateLayerMetadataSnapshot() { LayerMetadata parentMetadata; for (const auto& layer : mDrawingState.layersSortedByZ) { @@ -9291,33 +8683,6 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t u }; } -frontend::Update SurfaceFlinger::flushLifecycleUpdates() { - frontend::Update update; - SFTRACE_NAME("TransactionHandler:flushTransactions"); - // Locking: - // 1. to prevent onHandleDestroyed from being called while the state lock is held, - // we must keep a copy of the transactions (specifically the composer - // states) around outside the scope of the lock. - // 2. Transactions and created layers do not share a lock. To prevent applying - // transactions with layers still in the createdLayer queue, flush the transactions - // before committing the created layers. - mTransactionHandler.collectTransactions(); - update.transactions = mTransactionHandler.flushTransactions(); - { - // TODO(b/238781169) lockless queue this and keep order. - std::scoped_lock<std::mutex> lock(mCreatedLayersLock); - update.layerCreatedStates = std::move(mCreatedLayers); - mCreatedLayers.clear(); - update.newLayers = std::move(mNewLayers); - mNewLayers.clear(); - update.layerCreationArgs = std::move(mNewLayerArgs); - mNewLayerArgs.clear(); - update.destroyedHandles = std::move(mDestroyedHandles); - mDestroyedHandles.clear(); - } - return update; -} - void SurfaceFlinger::doActiveLayersTracingIfNeeded(bool isCompositionComputed, bool visibleRegionDirty, TimePoint time, VsyncId vsyncId) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 157b72244f..d15fe6f796 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -313,7 +313,6 @@ public: // Disables expensive rendering for all displays // This is scheduled on the main thread void disableExpensiveRendering(); - FloatRect getMaxDisplayBounds(); // If set, composition engine tries to predict the composition strategy provided by HWC // based on the previous frame. If the strategy can be predicted, gpu composition will @@ -764,16 +763,11 @@ private: const scheduler::RefreshRateSelector&) REQUIRES(mStateLock, kMainThreadContext); - void commitTransactionsLegacy() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext); void commitTransactions() REQUIRES(kMainThreadContext, mStateLock); void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock, kMainThreadContext); void doCommitTransactions() REQUIRES(mStateLock); - // Returns whether a new buffer has been latched. - bool latchBuffers(); - - void updateLayerGeometry(); void updateLayerMetadataSnapshot(); std::vector<std::pair<Layer*, LayerFE*>> moveSnapshotsToCompositionArgs( compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) @@ -782,13 +776,9 @@ private: const std::vector<std::pair<Layer*, LayerFE*>>& layers) REQUIRES(kMainThreadContext); // Return true if we must composite this frame - bool updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed, - bool& out) REQUIRES(kMainThreadContext); - // Return true if we must composite this frame bool updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); void updateLayerHistory(nsecs_t now) REQUIRES(kMainThreadContext); - frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) REQUIRES(kMainThreadContext); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); @@ -831,9 +821,6 @@ private: const TransactionHandler::TransactionFlushState& flushState) REQUIRES(kMainThreadContext); - uint32_t setClientStateLocked(const FrameTimelineInfo&, ResolvedComposerState&, - int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock); uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint64_t transactionId) @@ -883,9 +870,6 @@ private: const sp<Layer>& layer, const wp<Layer>& parentLayer, uint32_t* outTransformHint); - // Traverse through all the layers and compute and cache its bounds. - void computeLayerBounds(); - // Creates a promise for a future release fence for a layer. This allows for // the layer to keep track of when its buffer can be released. void attachReleaseFenceFutureToLayer(Layer* layer, LayerFE* layerFE, ui::LayerStack layerStack); @@ -1301,8 +1285,6 @@ private: std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved; std::unordered_set<uint32_t> mLayersIdsWithQueuedFrames; - // Tracks layers that need to update a display's dirty region. - std::vector<sp<Layer>> mLayersPendingRefresh; // Sorted list of layers that were composed during previous frame. This is used to // avoid an expensive traversal of the layer hierarchy when there are no // visible region changes. Because this is a list of strong pointers, this will @@ -1447,22 +1429,8 @@ private: // A temporay pool that store the created layers and will be added to current state in main // thread. std::vector<LayerCreatedState> mCreatedLayers GUARDED_BY(mCreatedLayersLock); - bool commitCreatedLayers(VsyncId, std::vector<LayerCreatedState>& createdLayers); void handleLayerCreatedLocked(const LayerCreatedState&, VsyncId) REQUIRES(mStateLock); - mutable std::mutex mMirrorDisplayLock; - struct MirrorDisplayState { - MirrorDisplayState(ui::LayerStack layerStack, sp<IBinder>& rootHandle, - const sp<Client>& client) - : layerStack(layerStack), rootHandle(rootHandle), client(client) {} - - ui::LayerStack layerStack; - sp<IBinder> rootHandle; - const sp<Client> client; - }; - std::vector<MirrorDisplayState> mMirrorDisplays GUARDED_BY(mMirrorDisplayLock); - bool commitMirrorDisplays(VsyncId); - std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint; // Must only be accessed on the main thread. diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 215f49deff..566981975f 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -94,7 +94,6 @@ cc_test { "LayerHierarchyTest.cpp", "LayerLifecycleManagerTest.cpp", "LayerSnapshotTest.cpp", - "LayerTest.cpp", "LayerTestUtils.cpp", "MessageQueueTest.cpp", "PowerAdvisorTest.cpp", diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp index 54d465902b..06319f3d26 100644 --- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp @@ -1539,4 +1539,48 @@ TEST_F(LayerSnapshotTest, doNotOverrideParentTrustedOverlayState) { gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)); } +static constexpr const FloatRect LARGE_FLOAT_RECT{std::numeric_limits<float>::min(), + std::numeric_limits<float>::min(), + std::numeric_limits<float>::max(), + std::numeric_limits<float>::max()}; +TEST_F(LayerSnapshotTest, layerVisibleByDefault) { + DisplayInfo info; + info.info.logicalHeight = 1000000; + info.info.logicalWidth = 1000000; + mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_FALSE(getSnapshot(1)->isHiddenByPolicy()); +} + +TEST_F(LayerSnapshotTest, hideLayerWithZeroMatrix) { + DisplayInfo info; + info.info.logicalHeight = 1000000; + info.info.logicalWidth = 1000000; + mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info); + setMatrix(1, 0.f, 0.f, 0.f, 0.f); + UPDATE_AND_VERIFY(mSnapshotBuilder, {2}); + EXPECT_TRUE(getSnapshot(1)->isHiddenByPolicy()); +} + +TEST_F(LayerSnapshotTest, hideLayerWithInfMatrix) { + DisplayInfo info; + info.info.logicalHeight = 1000000; + info.info.logicalWidth = 1000000; + mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info); + setMatrix(1, std::numeric_limits<float>::infinity(), 0.f, 0.f, + std::numeric_limits<float>::infinity()); + UPDATE_AND_VERIFY(mSnapshotBuilder, {2}); + EXPECT_TRUE(getSnapshot(1)->isHiddenByPolicy()); +} + +TEST_F(LayerSnapshotTest, hideLayerWithNanMatrix) { + DisplayInfo info; + info.info.logicalHeight = 1000000; + info.info.logicalWidth = 1000000; + mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info); + setMatrix(1, std::numeric_limits<float>::quiet_NaN(), 0.f, 0.f, + std::numeric_limits<float>::quiet_NaN()); + UPDATE_AND_VERIFY(mSnapshotBuilder, {2}); + EXPECT_TRUE(getSnapshot(1)->isHiddenByPolicy()); +} } // namespace android::surfaceflinger::frontend diff --git a/services/surfaceflinger/tests/unittests/LayerTest.cpp b/services/surfaceflinger/tests/unittests/LayerTest.cpp deleted file mode 100644 index 95e54f655b..0000000000 --- a/services/surfaceflinger/tests/unittests/LayerTest.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#undef LOG_TAG -#define LOG_TAG "LibSurfaceFlingerUnittests" - -#include <gtest/gtest.h> -#include <ui/FloatRect.h> -#include <ui/Transform.h> -#include <limits> - -#include "LayerTestUtils.h" -#include "TestableSurfaceFlinger.h" - -namespace android { -namespace { - -class LayerTest : public BaseLayerTest { -protected: - static constexpr const float MIN_FLOAT = std::numeric_limits<float>::min(); - static constexpr const float MAX_FLOAT = std::numeric_limits<float>::max(); - static constexpr const FloatRect LARGE_FLOAT_RECT{MIN_FLOAT, MIN_FLOAT, MAX_FLOAT, MAX_FLOAT}; -}; - -INSTANTIATE_TEST_SUITE_P(PerLayerType, LayerTest, - testing::Values(std::make_shared<BufferStateLayerFactory>(), - std::make_shared<EffectLayerFactory>()), - PrintToStringParamName); - -TEST_P(LayerTest, layerVisibleByDefault) { - sp<Layer> layer = GetParam()->createLayer(mFlinger); - layer->updateGeometry(); - layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f); - ASSERT_FALSE(layer->isHiddenByPolicy()); -} - -TEST_P(LayerTest, hideLayerWithZeroMatrix) { - sp<Layer> layer = GetParam()->createLayer(mFlinger); - - layer_state_t::matrix22_t matrix{0, 0, 0, 0}; - layer->setMatrix(matrix); - layer->updateGeometry(); - layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f); - - ASSERT_TRUE(layer->isHiddenByPolicy()); -} - -TEST_P(LayerTest, hideLayerWithInfMatrix) { - sp<Layer> layer = GetParam()->createLayer(mFlinger); - - constexpr const float INF = std::numeric_limits<float>::infinity(); - layer_state_t::matrix22_t matrix{INF, 0, 0, INF}; - layer->setMatrix(matrix); - layer->updateGeometry(); - layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f); - - ASSERT_TRUE(layer->isHiddenByPolicy()); -} - -TEST_P(LayerTest, hideLayerWithNanMatrix) { - sp<Layer> layer = GetParam()->createLayer(mFlinger); - - constexpr const float QUIET_NAN = std::numeric_limits<float>::quiet_NaN(); - layer_state_t::matrix22_t matrix{QUIET_NAN, 0, 0, QUIET_NAN}; - layer->setMatrix(matrix); - layer->updateGeometry(); - layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f); - - ASSERT_TRUE(layer->isHiddenByPolicy()); -} - -} // namespace -} // namespace android |