diff options
author | 2024-11-12 22:22:43 -0800 | |
---|---|---|
committer | 2024-11-12 22:22:43 -0800 | |
commit | 6dc15689f6bb4b04c102ac3107f31377ee91f05e (patch) | |
tree | 3ca9d372bc99ac1182fdb4bc895c556d0f108bd3 /services/surfaceflinger/SurfaceFlinger.cpp | |
parent | d4d02798539f29d00059d458fd01e5b2869acbb6 (diff) | |
parent | f151262626f1c08a104cc35d9864493ea8a72dec (diff) |
Merge 24Q4 (ab/12406339) into aosp-main-future
Bug: 370570306
Merged-In: I9be1254c3e2685b0aa950b314c581824f40ce26c
Change-Id: I35bc501a2b1d9eb100aaab25cd660cf2e0542f99
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 2228 |
1 files changed, 507 insertions, 1721 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d4d32aa37a..65a0ed3065 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -40,8 +40,10 @@ #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> +#include <com_android_graphics_libgui_flags.h> #include <com_android_graphics_surfaceflinger_flags.h> #include <common/FlagManager.h> +#include <common/trace.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/CompositionRefreshArgs.h> #include <compositionengine/Display.h> @@ -63,7 +65,7 @@ #include <ftl/fake_guard.h> #include <ftl/future.h> #include <ftl/unit.h> -#include <gui/AidlStatusUtil.h> +#include <gui/AidlUtil.h> #include <gui/BufferQueue.h> #include <gui/DebugEGLImageTracker.h> #include <gui/IProducerListener.h> @@ -71,9 +73,8 @@ #include <gui/LayerState.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> -#include <gui/TraceUtils.h> #include <hidl/ServiceManagement.h> -#include <layerproto/LayerProtoParser.h> +#include <layerproto/LayerProtoHeader.h> #include <linux/sched/types.h> #include <log/log.h> #include <private/android_filesystem_config.h> @@ -143,6 +144,7 @@ #include "FrontEnd/LayerLog.h" #include "FrontEnd/LayerSnapshot.h" #include "HdrLayerInfoReporter.h" +#include "Jank/JankTracker.h" #include "Layer.h" #include "LayerProtoHelper.h" #include "LayerRenderArea.h" @@ -204,8 +206,6 @@ using ui::Dataspace; using ui::DisplayPrimaries; using ui::RenderIntent; -using KernelIdleTimerController = scheduler::RefreshRateSelector::KernelIdleTimerController; - namespace hal = android::hardware::graphics::composer::hal; namespace { @@ -373,8 +373,6 @@ const String16 sCaptureBlackoutContent("android.permission.CAPTURE_BLACKOUT_CONT const String16 sInternalSystemWindow("android.permission.INTERNAL_SYSTEM_WINDOW"); const String16 sWakeupSurfaceFlinger("android.permission.WAKEUP_SURFACE_FLINGER"); -const char* KERNEL_IDLE_TIMER_PROP = "graphics.display.kernel_idle_timer.enabled"; - // --------------------------------------------------------------------------- int64_t SurfaceFlinger::dispSyncPresentTimeOffset; bool SurfaceFlinger::useHwcForRgbToYuv; @@ -433,7 +431,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) } SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) { - ATRACE_CALL(); + SFTRACE_CALL(); ALOGI("SurfaceFlinger is starting"); hasSyncFramework = running_without_sync_framework(true); @@ -533,13 +531,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false); - mLayerLifecycleManagerEnabled = - base::GetBoolProperty("persist.debug.sf.enable_layer_lifecycle_manager"s, true); - // These are set by the HWC implementation to indicate that they will use the workarounds. - mIsHotplugErrViaNegVsync = - base::GetBoolProperty("debug.sf.hwc_hotplug_error_via_neg_vsync"s, false); - mIsHdcpViaNegVsync = base::GetBoolProperty("debug.sf.hwc_hdcp_via_neg_vsync"s, false); } @@ -728,6 +720,7 @@ void SurfaceFlinger::bootFinished() { mBootFinished = true; FlagManager::getMutableInstance().markBootCompleted(); + ::tracing_perfetto::registerWithPerfetto(); mInitBootPropsFuture.wait(); mRenderEnginePrimeCacheFuture.wait(); @@ -854,13 +847,15 @@ renderengine::RenderEngine::BlurAlgorithm chooseBlurAlgorithm(bool supportsBlur) auto const algorithm = base::GetProperty(PROPERTY_DEBUG_RENDERENGINE_BLUR_ALGORITHM, ""); if (algorithm == "gaussian") { return renderengine::RenderEngine::BlurAlgorithm::GAUSSIAN; + } else if (algorithm == "kawase2") { + return renderengine::RenderEngine::BlurAlgorithm::KAWASE_DUAL_FILTER; } else { return renderengine::RenderEngine::BlurAlgorithm::KAWASE; } } void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { - ATRACE_CALL(); + SFTRACE_CALL(); ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); addTransactionReadyFilters(); @@ -912,9 +907,11 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { LOG_ALWAYS_FATAL_IF(!configureLocked(), "Initial display configuration failed: HWC did not hotplug"); + mActiveDisplayId = getPrimaryDisplayIdLocked(); + // Commit primary display. sp<const DisplayDevice> display; - if (const auto indexOpt = mCurrentState.getDisplayIndex(getPrimaryDisplayIdLocked())) { + if (const auto indexOpt = mCurrentState.getDisplayIndex(mActiveDisplayId)) { const auto& displays = mCurrentState.displays; const auto& token = displays.keyAt(*indexOpt); @@ -1006,6 +1003,8 @@ void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) { // which we maintain for backwards compatibility. config.cacheUltraHDR = base::GetBoolProperty("ro.surface_flinger.prime_shader_cache.ultrahdr"s, false); + config.cacheEdgeExtension = + base::GetBoolProperty("debug.sf.edge_extension_shader"s, true); return getRenderEngine().primeCache(config); }); @@ -1280,20 +1279,14 @@ status_t SurfaceFlinger::getDisplayStats(const sp<IBinder>& displayToken, return BAD_VALUE; } + // TODO: b/277364366 - Require a display token from clients and remove fallback to pacesetter. std::optional<PhysicalDisplayId> displayIdOpt; - { + if (displayToken) { Mutex::Autolock lock(mStateLock); - if (displayToken) { - displayIdOpt = getPhysicalDisplayIdLocked(displayToken); - if (!displayIdOpt) { - ALOGW("%s: Invalid physical display token %p", __func__, displayToken.get()); - return NAME_NOT_FOUND; - } - } else { - // TODO (b/277364366): Clients should be updated to pass in the display they - // want, rather than us picking an arbitrary one (the active display, in this - // case). - displayIdOpt = mActiveDisplayId; + displayIdOpt = getPhysicalDisplayIdLocked(displayToken); + if (!displayIdOpt) { + ALOGW("%s: Invalid physical display token %p", __func__, displayToken.get()); + return NAME_NOT_FOUND; } } @@ -1312,7 +1305,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { const auto mode = desiredMode.mode; const auto displayId = mode.modePtr->getPhysicalDisplayId(); - ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); + SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); const bool emitEvent = desiredMode.emitEvent; @@ -1340,22 +1333,16 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { // VsyncController model is locked. mScheduler->modulateVsync(displayId, &VsyncModulator::onRefreshRateChangeInitiated); - if (displayId == mActiveDisplayId) { - mScheduler->updatePhaseConfiguration(mode.fps); - } - + mScheduler->updatePhaseConfiguration(displayId, mode.fps); mScheduler->setModeChangePending(true); break; } case DesiredModeAction::InitiateRenderRateSwitch: mScheduler->setRenderRate(displayId, mode.fps, /*applyImmediately*/ false); - - if (displayId == mActiveDisplayId) { - mScheduler->updatePhaseConfiguration(mode.fps); - } + mScheduler->updatePhaseConfiguration(displayId, mode.fps); if (emitEvent) { - dispatchDisplayModeChangeEvent(displayId, mode); + mScheduler->onDisplayModeChanged(displayId, mode); } break; case DesiredModeAction::None: @@ -1365,7 +1352,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& desiredMode) { status_t SurfaceFlinger::setActiveModeFromBackdoor(const sp<display::DisplayToken>& displayToken, DisplayModeId modeId, Fps minFps, Fps maxFps) { - ATRACE_CALL(); + SFTRACE_CALL(); if (!displayToken) { return BAD_VALUE; @@ -1417,7 +1404,7 @@ status_t SurfaceFlinger::setActiveModeFromBackdoor(const sp<display::DisplayToke // TODO: b/241285876 - Restore thread safety analysis once mStateLock below is unconditional. [[clang::no_thread_safety_analysis]] void SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { - ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); + SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); const auto pendingModeOpt = mDisplayModeController.getPendingMode(displayId); if (!pendingModeOpt) { @@ -1447,12 +1434,10 @@ void SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) { mDisplayModeController.finalizeModeChange(displayId, activeMode.modePtr->getId(), activeMode.modePtr->getVsyncRate(), activeMode.fps); - if (displayId == mActiveDisplayId) { - mScheduler->updatePhaseConfiguration(activeMode.fps); - } + mScheduler->updatePhaseConfiguration(displayId, activeMode.fps); if (pendingModeOpt->emitEvent) { - dispatchDisplayModeChangeEvent(displayId, activeMode); + mScheduler->onDisplayModeChanged(displayId, activeMode); } } @@ -1473,17 +1458,13 @@ void SurfaceFlinger::applyActiveMode(PhysicalDisplayId displayId) { constexpr bool kAllowToEnable = true; mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, std::move(activeModePtr).take()); - mScheduler->setRenderRate(displayId, renderFps, /*applyImmediately*/ true); - if (displayId == mActiveDisplayId) { - mScheduler->updatePhaseConfiguration(renderFps); - } + mScheduler->setRenderRate(displayId, renderFps, /*applyImmediately*/ true); + mScheduler->updatePhaseConfiguration(displayId, renderFps); } void SurfaceFlinger::initiateDisplayModeChanges() { - ATRACE_CALL(); - - std::optional<PhysicalDisplayId> displayToUpdateImmediately; + SFTRACE_CALL(); for (const auto& [displayId, physical] : mPhysicalDisplays) { auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId); @@ -1538,21 +1519,14 @@ void SurfaceFlinger::initiateDisplayModeChanges() { if (outTimeline.refreshRequired) { scheduleComposite(FrameHint::kNone); } else { - // TODO(b/255635711): Remove `displayToUpdateImmediately` to `finalizeDisplayModeChange` - // for all displays. This was only needed when the loop iterated over `mDisplays` rather - // than `mPhysicalDisplays`. - displayToUpdateImmediately = displayId; - } - } - - if (displayToUpdateImmediately) { - const auto displayId = *displayToUpdateImmediately; - finalizeDisplayModeChange(displayId); + // HWC has requested to apply the mode change immediately rather than on the next frame. + finalizeDisplayModeChange(displayId); - const auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId); - if (desiredModeOpt && - mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) { - applyActiveMode(displayId); + const auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId); + if (desiredModeOpt && + mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) { + applyActiveMode(displayId); + } } } } @@ -1560,7 +1534,7 @@ void SurfaceFlinger::initiateDisplayModeChanges() { void SurfaceFlinger::disableExpensiveRendering() { const char* const whence = __func__; auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) { - ATRACE_NAME(whence); + SFTRACE_NAME(whence); if (mPowerAdvisor->isUsingExpensiveRendering()) { for (const auto& [_, display] : mDisplays) { constexpr bool kDisable = false; @@ -2171,12 +2145,12 @@ sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection( return mScheduler->createDisplayEventConnection(cycle, eventRegistration, layerHandle); } -void SurfaceFlinger::scheduleCommit(FrameHint hint) { +void SurfaceFlinger::scheduleCommit(FrameHint hint, Duration workDurationSlack) { if (hint == FrameHint::kActive) { mScheduler->resetIdleTimer(); } mPowerAdvisor->notifyDisplayUpdateImminentAndCpuReset(); - mScheduler->scheduleFrame(); + mScheduler->scheduleFrame(workDurationSlack); } void SurfaceFlinger::scheduleComposite(FrameHint hint) { @@ -2193,41 +2167,25 @@ void SurfaceFlinger::scheduleSample() { static_cast<void>(mScheduler->schedule([this] { sample(); })); } -nsecs_t SurfaceFlinger::getVsyncPeriodFromHWC() const { - if (const auto display = getDefaultDisplayDeviceLocked()) { - return display->getVsyncPeriodFromHWC(); - } - - return 0; -} - void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp, std::optional<hal::VsyncPeriodNanos> vsyncPeriod) { if (FlagManager::getInstance().connected_display() && timestamp < 0 && vsyncPeriod.has_value()) { - // use ~0 instead of -1 as AidlComposerHal.cpp passes the param as unsigned int32 - if (mIsHotplugErrViaNegVsync && vsyncPeriod.value() == ~0) { - const auto errorCode = static_cast<int32_t>(-timestamp); - ALOGD("%s: Hotplug error %d for display %" PRIu64, __func__, errorCode, hwcDisplayId); - mScheduler->dispatchHotplugError(errorCode); - return; - } - if (mIsHdcpViaNegVsync && vsyncPeriod.value() == ~1) { const int32_t value = static_cast<int32_t>(-timestamp); // one byte is good enough to encode android.hardware.drm.HdcpLevel const int32_t maxLevel = (value >> 8) & 0xFF; const int32_t connectedLevel = value & 0xFF; - ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for display %" PRIu64, __func__, - connectedLevel, maxLevel, hwcDisplayId); + ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for hwcDisplayId %" PRIu64, + __func__, connectedLevel, maxLevel, hwcDisplayId); updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel); return; } } - ATRACE_NAME(vsyncPeriod - ? ftl::Concat(__func__, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str() - : ftl::Concat(__func__, ' ', hwcDisplayId).c_str()); + SFTRACE_NAME(vsyncPeriod + ? ftl::Concat(__func__, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str() + : ftl::Concat(__func__, ' ', hwcDisplayId).c_str()); Mutex::Autolock lock(mStateLock); if (const auto displayIdOpt = getHwComposer().onVsync(hwcDisplayId, timestamp)) { @@ -2259,7 +2217,7 @@ void SurfaceFlinger::onComposerHalHotplugEvent(hal::HWDisplayId hwcDisplayId, if (FlagManager::getInstance().hotplug2()) { // TODO(b/311403559): use enum type instead of int const auto errorCode = static_cast<int32_t>(event); - ALOGD("%s: Hotplug error %d for display %" PRIu64, __func__, errorCode, hwcDisplayId); + ALOGD("%s: Hotplug error %d for hwcDisplayId %" PRIu64, __func__, errorCode, hwcDisplayId); mScheduler->dispatchHotplugError(errorCode); } } @@ -2285,12 +2243,12 @@ void SurfaceFlinger::onComposerHalRefresh(hal::HWDisplayId) { } void SurfaceFlinger::onComposerHalVsyncIdle(hal::HWDisplayId) { - ATRACE_CALL(); + SFTRACE_CALL(); mScheduler->forceNextResync(); } void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData& data) { - ATRACE_CALL(); + SFTRACE_CALL(); const char* const whence = __func__; static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD( kMainThreadContext) { @@ -2299,7 +2257,7 @@ void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData const Fps refreshRate = Fps::fromPeriodNsecs( getHwComposer().getComposer()->isVrrSupported() ? data.refreshPeriodNanos : data.vsyncPeriodNanos); - ATRACE_FORMAT("%s refresh rate = %d", whence, refreshRate.getIntValue()); + SFTRACE_FORMAT("%s refresh rate = %d", whence, refreshRate.getIntValue()); const auto renderRate = mDisplayModeController.getActiveMode(*displayIdOpt).fps; constexpr bool kSetByHwc = true; @@ -2309,6 +2267,18 @@ void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData })); } +void SurfaceFlinger::onComposerHalHdcpLevelsChanged(hal::HWDisplayId hwcDisplayId, + const HdcpLevels& levels) { + if (FlagManager::getInstance().hdcp_level_hal()) { + // TODO(b/362270040): propagate enum constants + const int32_t maxLevel = static_cast<int32_t>(levels.maxLevel); + const int32_t connectedLevel = static_cast<int32_t>(levels.connectedLevel); + ALOGD("%s: HDCP levels changed (connected=%d, max=%d) for hwcDisplayId %" PRIu64, __func__, + connectedLevel, maxLevel, hwcDisplayId); + updateHdcpLevels(hwcDisplayId, connectedLevel, maxLevel); + } +} + void SurfaceFlinger::configure() { Mutex::Autolock lock(mStateLock); if (configureLocked()) { @@ -2316,37 +2286,6 @@ void SurfaceFlinger::configure() { } } -bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs, - bool flushTransactions, - bool& outTransactionsAreEmpty) { - ATRACE_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); - } - 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; @@ -2418,10 +2357,10 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, bool flushTransactions, bool& outTransactionsAreEmpty) { using Changes = frontend::RequestedLayerState::Changes; - ATRACE_CALL(); + SFTRACE_CALL(); frontend::Update update; if (flushTransactions) { - ATRACE_NAME("TransactionHandler:flushTransactions"); + 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 @@ -2435,7 +2374,7 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, { // TODO(b/238781169) lockless queue this and keep order. std::scoped_lock<std::mutex> lock(mCreatedLayersLock); - update.layerCreatedStates = std::move(mCreatedLayers); + update.legacyLayers = std::move(mCreatedLayers); mCreatedLayers.clear(); update.newLayers = std::move(mNewLayers); mNewLayers.clear(); @@ -2454,11 +2393,8 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, } mLayerLifecycleManager.applyTransactions(update.transactions); mLayerLifecycleManager.onHandlesDestroyed(update.destroyedHandles); - for (auto& legacyLayer : update.layerCreatedStates) { - sp<Layer> layer = legacyLayer.layer.promote(); - if (layer) { - mLegacyLayers[layer->sequence] = layer; - } + for (auto& legacyLayer : update.legacyLayers) { + mLegacyLayers[legacyLayer->sequence] = legacyLayer; } mLayerHierarchyBuilder.update(mLayerLifecycleManager); } @@ -2473,7 +2409,7 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, mustComposite |= applyAndCommitDisplayTransactionStatesLocked(update.transactions); { - ATRACE_NAME("LayerSnapshotBuilder:update"); + SFTRACE_NAME("LayerSnapshotBuilder:update"); frontend::LayerSnapshotBuilder::Args args{.root = mLayerHierarchyBuilder.getHierarchy(), .layerLifecycleManager = mLayerLifecycleManager, @@ -2514,7 +2450,7 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, } bool newDataLatched = false; - ATRACE_NAME("DisplayCallbackAndStatsUpdates"); + SFTRACE_NAME("DisplayCallbackAndStatsUpdates"); mustComposite |= applyTransactionsLocked(update.transactions); traverseLegacyLayers([&](Layer* layer) { layer->commitTransaction(); }); const nsecs_t latchTime = systemTime(); @@ -2562,17 +2498,25 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, it->second->latchBufferImpl(unused, latchTime, bgColorOnly); newDataLatched = true; - mLayersWithQueuedFrames.emplace(it->second); + frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence); + gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported; + mLayersWithQueuedFrames.emplace(it->second, gameMode); mLayersIdsWithQueuedFrames.emplace(it->second->sequence); } updateLayerHistory(latchTime); - mLayerSnapshotBuilder.forEachVisibleSnapshot([&](const frontend::LayerSnapshot& snapshot) { - if (mLayersIdsWithQueuedFrames.find(snapshot.path.id) == mLayersIdsWithQueuedFrames.end()) - return; - Region visibleReg; - visibleReg.set(snapshot.transformedBoundsWithoutTransparentRegion); - invalidateLayerStack(snapshot.outputFilter, visibleReg); + mLayerSnapshotBuilder.forEachSnapshot([&](const frontend::LayerSnapshot& snapshot) { + // update output dirty region if we have a queued buffer that is visible or a snapshot + // recently became invisible + // TODO(b/360050020) investigate if we need to update dirty region when layer color changes + if ((snapshot.isVisible && + (mLayersIdsWithQueuedFrames.find(snapshot.path.id) != + mLayersIdsWithQueuedFrames.end())) || + (!snapshot.isVisible && snapshot.changes.test(Changes::Visibility))) { + Region visibleReg; + visibleReg.set(snapshot.transformedBoundsWithoutTransparentRegion); + invalidateLayerStack(snapshot.outputFilter, visibleReg); + } }); for (auto& destroyedLayer : mLayerLifecycleManager.getDestroyedLayers()) { @@ -2580,7 +2524,7 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, } { - ATRACE_NAME("LLM:commitChanges"); + SFTRACE_NAME("LLM:commitChanges"); mLayerLifecycleManager.commitChanges(); } @@ -2603,7 +2547,7 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, const scheduler::FrameTarget& pacesetterFrameTarget = *frameTargets.get(pacesetterId)->get(); const VsyncId vsyncId = pacesetterFrameTarget.vsyncId(); - ATRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str()); + SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str()); if (pacesetterFrameTarget.didMissFrame()) { mTimeStats->incrementMissedFrames(); @@ -2630,13 +2574,16 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, } } - if (pacesetterFrameTarget.isFramePending()) { + if (pacesetterFrameTarget.wouldBackpressureHwc()) { if (mBackpressureGpuComposition || pacesetterFrameTarget.didMissHwcFrame()) { if (FlagManager::getInstance().vrr_config()) { mScheduler->getVsyncSchedule()->getTracker().onFrameMissed( pacesetterFrameTarget.expectedPresentTime()); } - scheduleCommit(FrameHint::kNone); + const Duration slack = FlagManager::getInstance().allow_n_vsyncs_in_targeter() + ? TimePoint::now() - pacesetterFrameTarget.frameBeginTime() + : Duration::fromNs(0); + scheduleCommit(FrameHint::kNone, slack); return false; } } @@ -2683,11 +2630,8 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded); bool transactionsAreEmpty = false; - if (mLayerLifecycleManagerEnabled) { - mustComposite |= - updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(), - flushTransactions, transactionsAreEmpty); - } + mustComposite |= updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(), + flushTransactions, transactionsAreEmpty); // Tell VsyncTracker that we are going to present this frame before scheduling // setTransactionFlags which will schedule another SF frame. This was if the tracker @@ -2721,9 +2665,7 @@ bool SurfaceFlinger::commit(PhysicalDisplayId pacesetterId, mUpdateAttachedChoreographer = false; Mutex::Autolock lock(mStateLock); - mScheduler->chooseRefreshRateForContent(mLayerLifecycleManagerEnabled - ? &mLayerHierarchyBuilder.getHierarchy() - : nullptr, + mScheduler->chooseRefreshRateForContent(&mLayerHierarchyBuilder.getHierarchy(), updateAttachedChoreographer); if (FlagManager::getInstance().connected_display()) { @@ -2756,7 +2698,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( frameTargeters.get(pacesetterId)->get()->target(); const VsyncId vsyncId = pacesetterTarget.vsyncId(); - ATRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str()); + SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str()); compositionengine::CompositionRefreshArgs refreshArgs; refreshArgs.powerCallback = this; @@ -2793,17 +2735,14 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( const bool updateTaskMetadata = mCompositionEngine->getFeatureFlags().test( compositionengine::Feature::kSnapshotLayerMetadata); - if (updateTaskMetadata && (mVisibleRegionsDirty || mLayerMetadataSnapshotNeeded)) { - updateLayerMetadataSnapshot(); - mLayerMetadataSnapshotNeeded = false; - } refreshArgs.bufferIdsToUncache = std::move(mBufferIdsToUncache); if (!FlagManager::getInstance().ce_fence_promise()) { refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size()); - for (auto& layer : mLayersWithQueuedFrames) { - if (const auto& layerFE = layer->getCompositionEngineLayerFE()) + for (auto& [layer, _] : mLayersWithQueuedFrames) { + if (const auto& layerFE = layer->getCompositionEngineLayerFE( + {static_cast<uint32_t>(layer->sequence)})) refreshArgs.layersWithQueuedFrames.push_back(layerFE); } } @@ -2844,7 +2783,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( constexpr bool kCursorOnly = false; const auto layers = moveSnapshotsToCompositionArgs(refreshArgs, kCursorOnly); - if (mLayerLifecycleManagerEnabled && !mVisibleRegionsDirty) { + if (!mVisibleRegionsDirty) { for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) { auto compositionDisplay = display->getCompositionDisplay(); if (!compositionDisplay->getState().isEnabled) continue; @@ -2878,8 +2817,9 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( } refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size()); - for (auto& layer : mLayersWithQueuedFrames) { - if (const auto& layerFE = layer->getCompositionEngineLayerFE()) { + for (auto& [layer, _] : mLayersWithQueuedFrames) { + if (const auto& layerFE = layer->getCompositionEngineLayerFE( + {static_cast<uint32_t>(layer->sequence)})) { refreshArgs.layersWithQueuedFrames.push_back(layerFE); // Some layers are not displayed and do not yet have a future release fence if (layerFE->getReleaseFencePromiseStatus() == @@ -2910,9 +2850,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( for (auto [layer, layerFE] : layers) { CompositionResult compositionResult{layerFE->stealCompositionResult()}; for (auto& [releaseFence, layerStack] : compositionResult.releaseFences) { - Layer* clonedFrom = layer->getClonedFrom().get(); - auto owningLayer = clonedFrom ? clonedFrom : layer; - owningLayer->onLayerDisplayed(std::move(releaseFence), layerStack); + layer->onLayerDisplayed(std::move(releaseFence), layerStack); } if (compositionResult.lastClientCompositionFence) { layer->setWasClientComposed(compositionResult.lastClientCompositionFence); @@ -2920,6 +2858,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( } } + SFTRACE_NAME("postComposition"); mTimeStats->recordFrameDuration(pacesetterTarget.frameBeginTime().ns(), systemTime()); // Send a power hint after presentation is finished. @@ -2927,6 +2866,9 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( // Now that the current frame has been presented above, PowerAdvisor needs the present time // of the previous frame (whose fence is signaled by now) to determine how long the HWC had // waited on that fence to retire before presenting. + // TODO(b/355238809) `presentFenceForPreviousFrame` might not always be signaled (e.g. on + // devices + // where HWC does not block on the previous present fence). Revise this assumtion. const auto& previousPresentFence = pacesetterTarget.presentFenceForPreviousFrame(); mPowerAdvisor->setSfPresentTiming(TimePoint::fromNs(previousPresentFence->getSignalTime()), @@ -3014,21 +2956,6 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( return resultsPerDisplay; } -void SurfaceFlinger::updateLayerGeometry() { - ATRACE_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 @@ -3099,7 +3026,7 @@ ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(DisplayId displayId, void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, const scheduler::FrameTargeters& frameTargeters, nsecs_t presentStartTime) { - ATRACE_CALL(); + SFTRACE_CALL(); ui::PhysicalDisplayMap<PhysicalDisplayId, std::shared_ptr<FenceTime>> presentFences; ui::PhysicalDisplayMap<PhysicalDisplayId, const sp<Fence>> gpuCompositionDoneFences; @@ -3195,10 +3122,10 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, } mLayersWithBuffersRemoved.clear(); - for (const auto& layer: mLayersWithQueuedFrames) { + for (const auto& [layer, gameMode] : mLayersWithQueuedFrames) { layer->onCompositionPresented(pacesetterDisplay.get(), pacesetterGpuCompositionDoneFenceTime, - pacesetterPresentFenceTime, compositorTiming); + pacesetterPresentFenceTime, compositorTiming, gameMode); layer->releasePendingBuffer(presentTime.ns()); } @@ -3259,28 +3186,20 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, } }; - if (mLayerLifecycleManagerEnabled) { - mLayerSnapshotBuilder.forEachVisibleSnapshot( - [&, compositionDisplay = compositionDisplay]( - std::unique_ptr<frontend::LayerSnapshot>& - snapshot) FTL_FAKE_GUARD(kMainThreadContext) { - auto it = mLegacyLayers.find(snapshot->sequence); - LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(), - "Couldnt find layer object for %s", - snapshot->getDebugString().c_str()); - auto& legacyLayer = it->second; - sp<LayerFE> layerFe = - legacyLayer->getCompositionEngineLayerFE(snapshot->path); - - updateInfoFn(compositionDisplay, *snapshot, layerFe); - }); - } else { - mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) { - const auto layerFe = layer->getCompositionEngineLayerFE(); - const frontend::LayerSnapshot& snapshot = *layer->getLayerSnapshot(); - updateInfoFn(compositionDisplay, snapshot, layerFe); - }); - } + mLayerSnapshotBuilder.forEachVisibleSnapshot( + [&, compositionDisplay = compositionDisplay]( + std::unique_ptr<frontend::LayerSnapshot>& snapshot) + FTL_FAKE_GUARD(kMainThreadContext) { + auto it = mLegacyLayers.find(snapshot->sequence); + LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(), + "Couldnt find layer object for %s", + snapshot->getDebugString().c_str()); + auto& legacyLayer = it->second; + sp<LayerFE> layerFe = + legacyLayer->getCompositionEngineLayerFE(snapshot->path); + + updateInfoFn(compositionDisplay, *snapshot, layerFe); + }); listener->dispatchHdrLayerInfo(info); } } @@ -3326,9 +3245,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, if (!layer->hasTrustedPresentationListener()) { return; } - const frontend::LayerSnapshot* snapshot = mLayerLifecycleManagerEnabled - ? mLayerSnapshotBuilder.getSnapshot(layer->sequence) - : layer->getLayerSnapshot(); + const frontend::LayerSnapshot* snapshot = + mLayerSnapshotBuilder.getSnapshot(layer->sequence); std::optional<const DisplayDevice*> displayOpt = std::nullopt; if (snapshot) { displayOpt = layerStackToDisplay.get(snapshot->outputFilter.layerStack); @@ -3340,48 +3258,18 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, }); } - // Even though ATRACE_INT64 already checks if tracing is enabled, it doesn't prevent the + // Even though SFTRACE_INT64 already checks if tracing is enabled, it doesn't prevent the // side-effect of getTotalSize(), so we check that again here - if (ATRACE_ENABLED()) { + if (SFTRACE_ENABLED()) { // getTotalSize returns the total number of buffers that were allocated by SurfaceFlinger - ATRACE_INT64("Total Buffer Size", GraphicBufferAllocator::get().getTotalSize()); + SFTRACE_INT64("Total Buffer Size", GraphicBufferAllocator::get().getTotalSize()); } 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() { - ATRACE_CALL(); + SFTRACE_CALL(); mDebugInTransaction = systemTime(); // Here we're guaranteed that some transaction flags are set @@ -3393,28 +3281,6 @@ void SurfaceFlinger::commitTransactions() { mDebugInTransaction = 0; } -void SurfaceFlinger::commitTransactionsLegacy() { - ATRACE_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; @@ -3673,7 +3539,12 @@ std::optional<DisplayModeId> SurfaceFlinger::processHotplugConnect(PhysicalDispl state.physical = {.id = displayId, .hwcDisplayId = hwcDisplayId, .activeMode = std::move(activeMode)}; - state.isSecure = connectionType == ui::DisplayConnectionType::Internal; + if (mIsHdcpViaNegVsync) { + state.isSecure = connectionType == ui::DisplayConnectionType::Internal; + } else { + // TODO(b/349703362): Remove this when HDCP aidl API becomes ready + state.isSecure = true; // All physical displays are currently considered secure. + } state.isProtected = true; state.displayName = std::move(info.name); @@ -3697,16 +3568,6 @@ void SurfaceFlinger::processHotplugDisconnect(PhysicalDisplayId displayId, mPhysicalDisplays.erase(displayId); } -void SurfaceFlinger::dispatchDisplayModeChangeEvent(PhysicalDisplayId displayId, - const scheduler::FrameRateMode& mode) { - // TODO(b/255635821): Merge code paths and move to Scheduler. - const auto onDisplayModeChanged = displayId == mActiveDisplayId - ? &scheduler::Scheduler::onPrimaryDisplayModeChanged - : &scheduler::Scheduler::onNonPrimaryDisplayModeChanged; - - ((*mScheduler).*onDisplayModeChanged)(scheduler::Cycle::Render, mode); -} - sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay, @@ -3782,7 +3643,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( if (const auto& physical = state.physical) { const auto& mode = *physical->activeMode; mDisplayModeController.setActiveMode(physical->id, mode.getId(), mode.getVsyncRate(), - mode.getVsyncRate()); + mode.getPeakFps()); } display->setLayerFilter(makeLayerFilterForDisplay(display->getId(), state.layerStack)); @@ -3852,11 +3713,20 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, state.surface.get()); const auto displayId = PhysicalDisplayId::tryCast(compositionDisplay->getId()); LOG_FATAL_IF(!displayId); +#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) + const auto frameBufferSurface = + sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqProducer, bqConsumer, + state.physical->activeMode->getResolution(), + ui::Size(maxGraphicsWidth, maxGraphicsHeight)); + displaySurface = frameBufferSurface; + producer = frameBufferSurface->getSurface()->getIGraphicBufferProducer(); +#else displaySurface = sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer, state.physical->activeMode->getResolution(), ui::Size(maxGraphicsWidth, maxGraphicsHeight)); producer = bqProducer; +#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) } LOG_FATAL_IF(!displaySurface); @@ -3949,7 +3819,8 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, mDisplays.erase(displayToken); if (const auto& physical = currentState.physical) { - getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id); + getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id, + /*physicalSize=*/std::nullopt); } processDisplayAdded(displayToken, currentState); @@ -3960,11 +3831,8 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, setPowerModeInternal(display, hal::PowerMode::ON); } - // TODO(b/175678251) Call a listener instead. - if (currentState.physical->hwcDisplayId == getHwComposer().getPrimaryHwcDisplayId()) { - const Fps refreshRate = - mDisplayModeController.getActiveMode(display->getPhysicalId()).fps; - mScheduler->resetPhaseConfiguration(refreshRate); + if (display->getPhysicalId() == mActiveDisplayId) { + onActiveDisplayChangedLocked(nullptr, *display); } } return; @@ -4048,14 +3916,6 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { // Commit display transactions. const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded; mFrontEndDisplayInfosChanged = displayTransactionNeeded; - if (displayTransactionNeeded && !mLayerLifecycleManagerEnabled) { - processDisplayChangesLocked(); - mFrontEndDisplayInfos.clear(); - for (const auto& [_, display] : mDisplays) { - mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo()); - } - } - mForceTransactionDisplayChange = displayTransactionNeeded; if (mSomeChildrenChanged) { mVisibleRegionsDirty = true; @@ -4063,51 +3923,6 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { mUpdateInputInfo = true; } - // Update transform hint. - if (transactionFlags & (eTransformHintUpdateNeeded | eDisplayTransactionNeeded)) { - // Layers and/or displays have changed, so update the transform hint for each layer. - // - // NOTE: we do this here, rather than when presenting the display so that - // the hint is set before we acquire a buffer from the surface texture. - // - // NOTE: layer transactions have taken place already, so we use their - // drawing state. However, SurfaceFlinger's own transaction has not - // happened yet, so we must use the current state layer list - // (soon to become the drawing state list). - // - sp<const DisplayDevice> hintDisplay; - ui::LayerStack layerStack; - - mCurrentState.traverse([&](Layer* layer) REQUIRES(mStateLock) { - // NOTE: we rely on the fact that layers are sorted by - // layerStack first (so we don't have to traverse the list - // of displays for every layer). - if (const auto filter = layer->getOutputFilter(); layerStack != filter.layerStack) { - layerStack = filter.layerStack; - hintDisplay = nullptr; - - // Find the display that includes the layer. - for (const auto& [token, display] : mDisplays) { - if (!display->getCompositionDisplay()->includesLayer(filter)) { - continue; - } - - // Pick the primary display if another display mirrors the layer. - if (hintDisplay) { - hintDisplay = nullptr; - break; - } - - hintDisplay = display; - } - } - - if (hintDisplay) { - layer->updateTransformHint(hintDisplay->getTransformHint()); - } - }); - } - if (mLayersAdded) { mLayersAdded = false; // Layers have been added. @@ -4121,14 +3936,6 @@ void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) { mLayersRemoved = false; mVisibleRegionsDirty = true; mUpdateInputInfo = true; - mDrawingState.traverseInZOrder([&](Layer* layer) { - if (mLayersPendingRemoval.indexOf(sp<Layer>::fromExisting(layer)) >= 0) { - // this layer is not visible anymore - Region visibleReg; - visibleReg.set(layer->getScreenBounds()); - invalidateLayerStack(layer->getOutputFilter(), visibleReg); - } - }); } if (transactionFlags & eInputInfoUpdateNeeded) { @@ -4142,7 +3949,7 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) { if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) { return; } - ATRACE_CALL(); + SFTRACE_CALL(); std::vector<WindowInfo> windowInfos; std::vector<DisplayInfo> displayInfos; @@ -4172,7 +3979,7 @@ void SurfaceFlinger::updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) { std::move(mInputWindowCommands), inputFlinger = mInputFlinger, this, visibleWindowsChanged, vsyncId, frameTime]() { - ATRACE_NAME("BackgroundExecutor::updateInputFlinger"); + SFTRACE_NAME("BackgroundExecutor::updateInputFlinger"); if (updateWindowInfo) { mWindowInfosListenerInvoker ->windowInfosChanged(gui::WindowInfosUpdate{std::move(windowInfos), @@ -4235,23 +4042,10 @@ void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos, outWindowInfos.reserve(sNumWindowInfos); sNumWindowInfos = 0; - if (mLayerLifecycleManagerEnabled) { - mLayerSnapshotBuilder.forEachInputSnapshot( - [&outWindowInfos](const frontend::LayerSnapshot& snapshot) { - outWindowInfos.push_back(snapshot.inputInfo); - }); - } else { - mDrawingState.traverseInReverseZOrder([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) { - if (!layer->needsInputInfo()) return; - const auto opt = - mFrontEndDisplayInfos.get(layer->getLayerStack()) - .transform([](const frontend::DisplayInfo& info) { - return Layer::InputDisplayArgs{&info.transform, info.isSecure}; - }); - - outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{}))); - }); - } + mLayerSnapshotBuilder.forEachInputSnapshot( + [&outWindowInfos](const frontend::LayerSnapshot& snapshot) { + outWindowInfos.push_back(snapshot.inputInfo); + }); sNumWindowInfos = outWindowInfos.size(); @@ -4285,7 +4079,7 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest return; } - ATRACE_CALL(); + SFTRACE_CALL(); // If this is called from the main thread mStateLock must be locked before // Currently the only way to call this function from the main thread is from @@ -4310,25 +4104,14 @@ void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest } } -void SurfaceFlinger::triggerOnFrameRateOverridesChanged() { - PhysicalDisplayId displayId = [&]() { - ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); - return getDefaultDisplayDeviceLocked()->getPhysicalId(); - }(); - - mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId); -} - void SurfaceFlinger::notifyCpuLoadUp() { mPowerAdvisor->notifyCpuLoadUp(); } void SurfaceFlinger::onChoreographerAttached() { - ATRACE_CALL(); - if (mLayerLifecycleManagerEnabled) { - mUpdateAttachedChoreographer = true; - scheduleCommit(FrameHint::kNone); - } + SFTRACE_CALL(); + mUpdateAttachedChoreographer = true; + scheduleCommit(FrameHint::kNone); } void SurfaceFlinger::onExpectedPresentTimePosted(TimePoint expectedPresentTime, @@ -4453,6 +4236,8 @@ void SurfaceFlinger::scheduleNotifyExpectedPresentHint(PhysicalDisplayId display if (data.hintStatus.compare_exchange_strong(scheduleHintOnTx, NotifyExpectedPresentHintStatus::Sent)) { sendHint(); + constexpr bool kAllowToEnable = true; + mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable); } })); } @@ -4552,75 +4337,9 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) { } void SurfaceFlinger::doCommitTransactions() { - ATRACE_CALL(); - - if (!mLayersPendingRemoval.isEmpty()) { - // Notify removed layers now that they can't be drawn from - for (const auto& l : mLayersPendingRemoval) { - // Ensure any buffers set to display on any children are released. - if (l->isRemovedFromCurrentState()) { - l->latchAndReleaseBuffer(); - } - - // If a layer has a parent, we allow it to out-live it's handle - // with the idea that the parent holds a reference and will eventually - // be cleaned up. However no one cleans up the top-level so we do so - // here. - if (l->isAtRoot()) { - l->setIsAtRoot(false); - mCurrentState.layersSortedByZ.remove(l); - } - - // If the layer has been removed and has no parent, then it will not be reachable - // when traversing layers on screen. Add the layer to the offscreenLayers set to - // ensure we can copy its current to drawing state. - if (!l->getParent()) { - mOffscreenLayers.emplace(l.get()); - } - } - mLayersPendingRemoval.clear(); - } - + SFTRACE_CALL(); mDrawingState = mCurrentState; mCurrentState.colorMatrixChanged = false; - - if (mVisibleRegionsDirty) { - for (const auto& rootLayer : mDrawingState.layersSortedByZ) { - rootLayer->commitChildList(); - } - } - - commitOffscreenLayers(); - if (mLayerMirrorRoots.size() > 0) { - std::deque<Layer*> pendingUpdates; - pendingUpdates.insert(pendingUpdates.end(), mLayerMirrorRoots.begin(), - mLayerMirrorRoots.end()); - std::vector<Layer*> needsUpdating; - for (Layer* cloneRoot : mLayerMirrorRoots) { - pendingUpdates.pop_front(); - if (cloneRoot->isRemovedFromCurrentState()) { - continue; - } - if (cloneRoot->updateMirrorInfo(pendingUpdates)) { - } else { - needsUpdating.push_back(cloneRoot); - } - } - for (Layer* cloneRoot : needsUpdating) { - cloneRoot->updateMirrorInfo({}); - } - } -} - -void SurfaceFlinger::commitOffscreenLayers() { - for (Layer* offscreenLayer : mOffscreenLayers) { - offscreenLayer->traverse(LayerVector::StateSet::Drawing, [](Layer* layer) { - if (layer->clearTransactionFlags(eTransactionNeeded)) { - layer->doTransaction(0); - layer->commitChildList(); - } - }); - } } void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty) { @@ -4632,160 +4351,30 @@ void SurfaceFlinger::invalidateLayerStack(const ui::LayerFilter& layerFilter, co } } -bool SurfaceFlinger::latchBuffers() { - ATRACE_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) { if (mNumLayers >= MAX_LAYERS) { + static std::atomic<nsecs_t> lasttime{0}; + nsecs_t now = systemTime(); + if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) { + ALOGE("AddClientLayer already dumped 10s before"); + return NO_MEMORY; + } else { + lasttime = now; + } + ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(), MAX_LAYERS); - static_cast<void>(mScheduler->schedule([=, this] { - ALOGE("Dumping layer keeping > 20 children alive:"); - bool leakingParentLayerFound = false; - mDrawingState.traverse([&](Layer* layer) { - if (leakingParentLayerFound) { - return; - } - if (layer->getChildrenCount() > 20) { - leakingParentLayerFound = true; - sp<Layer> parent = sp<Layer>::fromExisting(layer); - while (parent) { - ALOGE("Parent Layer: %s%s", parent->getName().c_str(), - (parent->isHandleAlive() ? "handleAlive" : "")); - parent = parent->getParent(); - } - // Sample up to 100 layers - ALOGE("Dumping random sampling of child layers total(%zu): ", - layer->getChildrenCount()); - int sampleSize = (layer->getChildrenCount() / 100) + 1; - layer->traverseChildren([&](Layer* layer) { - if (rand() % sampleSize == 0) { - ALOGE("Child Layer: %s%s", layer->getName().c_str(), - (layer->isHandleAlive() ? "handleAlive" : "")); - } - }); - } - }); - - int numLayers = 0; - mDrawingState.traverse([&](Layer* layer) { numLayers++; }); - - ALOGE("Dumping random sampling of on-screen layers total(%u):", numLayers); - mDrawingState.traverse([&](Layer* layer) { - // Aim to dump about 200 layers to avoid totally trashing - // logcat. On the other hand, if there really are 4096 layers - // something has gone totally wrong its probably the most - // useful information in logcat. - if (rand() % 20 == 13) { - ALOGE("Layer: %s%s", layer->getName().c_str(), - (layer->isHandleAlive() ? "handleAlive" : "")); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - } - }); - ALOGE("Dumping random sampling of off-screen layers total(%zu): ", - mOffscreenLayers.size()); - for (Layer* offscreenLayer : mOffscreenLayers) { - if (rand() % 20 == 13) { - ALOGE("Offscreen-layer: %s%s", offscreenLayer->getName().c_str(), - (offscreenLayer->isHandleAlive() ? "handleAlive" : "")); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - } - } + static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) { + ALOGE("Dumping on-screen layers."); + mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy()); + ALOGE("Dumping off-screen layers."); + mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy()); })); return NO_MEMORY; } - layer->updateTransformHint(mActiveDisplayTransformHint); if (outTransformHint) { *outTransformHint = mActiveDisplayTransformHint; } @@ -4793,7 +4382,7 @@ status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinde args.layerIdToMirror = LayerHandle::getLayerId(args.mirrorLayerHandle.promote()); { std::scoped_lock<std::mutex> lock(mCreatedLayersLock); - mCreatedLayers.emplace_back(layer, parent, args.addToRoot); + mCreatedLayers.emplace_back(layer); mNewLayers.emplace_back(std::make_unique<frontend::RequestedLayerState>(args)); args.mirrorLayerHandle.clear(); args.parentHandle.clear(); @@ -4810,7 +4399,7 @@ uint32_t SurfaceFlinger::getTransactionFlags() const { uint32_t SurfaceFlinger::clearTransactionFlags(uint32_t mask) { uint32_t transactionFlags = mTransactionFlags.fetch_and(~mask); - ATRACE_INT("mTransactionFlags", transactionFlags); + SFTRACE_INT("mTransactionFlags", transactionFlags); return transactionFlags & mask; } @@ -4818,7 +4407,7 @@ void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule sche const sp<IBinder>& applyToken, FrameHint frameHint) { mScheduler->modulateVsync({}, &VsyncModulator::setTransactionSchedule, schedule, applyToken); uint32_t transactionFlags = mTransactionFlags.fetch_or(mask); - ATRACE_INT("mTransactionFlags", transactionFlags); + SFTRACE_INT("mTransactionFlags", transactionFlags); if (const bool scheduled = transactionFlags & mask; !scheduled) { scheduleCommit(frameHint); @@ -4843,8 +4432,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyTimelin // for stability reasons. if (!transaction.isAutoTimestamp && desiredPresentTime >= expectedPresentTime && desiredPresentTime < expectedPresentTime + 1s) { - ATRACE_FORMAT("not current desiredPresentTime: %" PRId64 " expectedPresentTime: %" PRId64, - desiredPresentTime, expectedPresentTime); + SFTRACE_FORMAT("not current desiredPresentTime: %" PRId64 " expectedPresentTime: %" PRId64, + desiredPresentTime, expectedPresentTime); return TransactionReadiness::NotReady; } @@ -4856,117 +4445,22 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyTimelin // incorrectly as the frame rate of SF changed before it drained the older transactions. if (ftl::to_underlying(vsyncId) == FrameTimelineInfo::INVALID_VSYNC_ID && !mScheduler->isVsyncValid(expectedPresentTime, transaction.originUid)) { - ATRACE_FORMAT("!isVsyncValid expectedPresentTime: %" PRId64 " uid: %d", expectedPresentTime, - transaction.originUid); + SFTRACE_FORMAT("!isVsyncValid expectedPresentTime: %" PRId64 " uid: %d", + expectedPresentTime, transaction.originUid); return TransactionReadiness::NotReady; } // If the client didn't specify desiredPresentTime, use the vsyncId to determine the // expected present time of this transaction. if (transaction.isAutoTimestamp && frameIsEarly(expectedPresentTime, vsyncId)) { - ATRACE_FORMAT("frameIsEarly vsyncId: %" PRId64 " expectedPresentTime: %" PRId64, - transaction.frameTimelineInfo.vsyncId, expectedPresentTime); + SFTRACE_FORMAT("frameIsEarly vsyncId: %" PRId64 " expectedPresentTime: %" PRId64, + transaction.frameTimelineInfo.vsyncId, expectedPresentTime); return TransactionReadiness::NotReady; } return TransactionReadiness::Ready; } -TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheckLegacy( - const TransactionHandler::TransactionFlushState& flushState) { - using TransactionReadiness = TransactionHandler::TransactionReadiness; - auto ready = TransactionReadiness::Ready; - flushState.transaction->traverseStatesWithBuffersWhileTrue([&](const ResolvedComposerState& - resolvedState) -> bool { - sp<Layer> layer = LayerHandle::getLayer(resolvedState.state.surface); - - const auto& transaction = *flushState.transaction; - const auto& s = resolvedState.state; - // check for barrier frames - if (s.bufferData->hasBarrier) { - // The current producerId is already a newer producer than the buffer that has a - // barrier. This means the incoming buffer is older and we can release it here. We - // don't wait on the barrier since we know that's stale information. - if (layer->getDrawingState().barrierProducerId > s.bufferData->producerId) { - layer->callReleaseBufferCallback(s.bufferData->releaseBufferListener, - resolvedState.externalTexture->getBuffer(), - s.bufferData->frameNumber, - s.bufferData->acquireFence); - // Delete the entire state at this point and not just release the buffer because - // everything associated with the Layer in this Transaction is now out of date. - ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d", - layer->getDebugName(), layer->getDrawingState().barrierProducerId, - s.bufferData->producerId); - return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL; - } - - if (layer->getDrawingState().barrierFrameNumber < s.bufferData->barrierFrameNumber) { - const bool willApplyBarrierFrame = - flushState.bufferLayersReadyToPresent.contains(s.surface.get()) && - ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >= - s.bufferData->barrierFrameNumber)); - if (!willApplyBarrierFrame) { - ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 " > %" PRId64, - layer->getDebugName(), - layer->getDrawingState().barrierFrameNumber, - s.bufferData->barrierFrameNumber); - ready = TransactionReadiness::NotReadyBarrier; - return TraverseBuffersReturnValues::STOP_TRAVERSAL; - } - } - } - - // If backpressure is enabled and we already have a buffer to commit, keep - // the transaction in the queue. - const bool hasPendingBuffer = - flushState.bufferLayersReadyToPresent.contains(s.surface.get()); - if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) { - ATRACE_FORMAT("hasPendingBuffer %s", layer->getDebugName()); - ready = TransactionReadiness::NotReady; - return TraverseBuffersReturnValues::STOP_TRAVERSAL; - } - - const bool acquireFenceAvailable = s.bufferData && - s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) && - s.bufferData->acquireFence; - const bool fenceSignaled = !acquireFenceAvailable || - s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled; - if (!fenceSignaled) { - // check fence status - const bool allowLatchUnsignaled = shouldLatchUnsignaled(s, transaction.states.size(), - flushState.firstTransaction) && - layer->isSimpleBufferUpdate(s); - - if (allowLatchUnsignaled) { - ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s", - layer->getDebugName()); - ready = TransactionReadiness::NotReadyUnsignaled; - } else { - ready = TransactionReadiness::NotReady; - auto& listener = s.bufferData->releaseBufferListener; - if (listener && - (flushState.queueProcessTime - transaction.postTime) > - std::chrono::nanoseconds(4s).count()) { - // Used to add a stalled transaction which uses an internal lock. - ftl::FakeGuard guard(kMainThreadContext); - mTransactionHandler - .onTransactionQueueStalled(transaction.id, - {.pid = layer->getOwnerPid(), - .layerId = static_cast<uint32_t>( - layer->getSequence()), - .layerName = layer->getDebugName(), - .bufferId = s.bufferData->getId(), - .frameNumber = s.bufferData->frameNumber}); - } - ATRACE_FORMAT("fence unsignaled %s", layer->getDebugName()); - return TraverseBuffersReturnValues::STOP_TRAVERSAL; - } - } - return TraverseBuffersReturnValues::CONTINUE_TRAVERSAL; - }); - return ready; -} - TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheck( const TransactionHandler::TransactionFlushState& flushState) { using TransactionReadiness = TransactionHandler::TransactionReadiness; @@ -4988,8 +4482,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC uint32_t currentMaxAcquiredBufferCount = getMaxAcquiredBufferCountForCurrentRefreshRate( layer->ownerUid.val()); - ATRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, - layer->name.c_str(), s.bufferData->frameNumber); + SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, + layer->name.c_str(), s.bufferData->frameNumber); s.bufferData->releaseBufferListener ->onReleaseBuffer({resolvedState.externalTexture->getBuffer() ->getId(), @@ -5003,9 +4497,9 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC // Delete the entire state at this point and not just release the buffer // because everything associated with the Layer in this Transaction is now // out of date. - ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d", - layer->name.c_str(), layer->barrierProducerId, - s.bufferData->producerId); + SFTRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d", + layer->name.c_str(), layer->barrierProducerId, + s.bufferData->producerId); return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL; } @@ -5015,10 +4509,10 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >= s.bufferData->barrierFrameNumber)); if (!willApplyBarrierFrame) { - ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 - " > %" PRId64, - layer->name.c_str(), layer->barrierFrameNumber, - s.bufferData->barrierFrameNumber); + SFTRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 + " > %" PRId64, + layer->name.c_str(), layer->barrierFrameNumber, + s.bufferData->barrierFrameNumber); ready = TransactionReadiness::NotReadyBarrier; return TraverseBuffersReturnValues::STOP_TRAVERSAL; } @@ -5031,7 +4525,7 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC flushState.bufferLayersReadyToPresent.contains(s.surface.get()); if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) { - ATRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str()); + SFTRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str()); ready = TransactionReadiness::NotReady; return TraverseBuffersReturnValues::STOP_TRAVERSAL; } @@ -5048,8 +4542,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC flushState.firstTransaction) && layer->isSimpleBufferUpdate(s); if (allowLatchUnsignaled) { - ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s", - layer->name.c_str()); + SFTRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s", + layer->name.c_str()); ready = TransactionReadiness::NotReadyUnsignaled; } else { ready = TransactionReadiness::NotReady; @@ -5066,7 +4560,7 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC .frameNumber = s.bufferData->frameNumber}); } - ATRACE_FORMAT("fence unsignaled %s", layer->name.c_str()); + SFTRACE_FORMAT("fence unsignaled %s", layer->name.c_str()); return TraverseBuffersReturnValues::STOP_TRAVERSAL; } } @@ -5078,15 +4572,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC void SurfaceFlinger::addTransactionReadyFilters() { mTransactionHandler.addTransactionReadyFilter( std::bind(&SurfaceFlinger::transactionReadyTimelineCheck, this, std::placeholders::_1)); - if (mLayerLifecycleManagerEnabled) { - mTransactionHandler.addTransactionReadyFilter( - std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this, - std::placeholders::_1)); - } else { - mTransactionHandler.addTransactionReadyFilter( - std::bind(&SurfaceFlinger::transactionReadyBufferCheckLegacy, this, - std::placeholders::_1)); - } + mTransactionHandler.addTransactionReadyFilter( + std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this, std::placeholders::_1)); } // For tests only @@ -5145,22 +4632,22 @@ bool SurfaceFlinger::frameIsEarly(TimePoint expectedPresentTime, VsyncId vsyncId bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t numStates, bool firstTransaction) const { if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::Disabled) { - ATRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::Disabled)", __func__); + SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::Disabled)", __func__); return false; } // We only want to latch unsignaled when a single layer is updated in this // transaction (i.e. not a blast sync transaction). if (numStates != 1) { - ATRACE_FORMAT_INSTANT("%s: false (numStates=%zu)", __func__, numStates); + SFTRACE_FORMAT_INSTANT("%s: false (numStates=%zu)", __func__, numStates); return false; } if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) { if (!firstTransaction) { - ATRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; not first " - "transaction)", - __func__); + SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; not first " + "transaction)", + __func__); return false; } @@ -5168,9 +4655,9 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t nu // as it leads to jank due to RenderEngine waiting for unsignaled buffer // or window animations being slow. if (mScheduler->vsyncModulator().isVsyncConfigEarly()) { - ATRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; " - "isVsyncConfigEarly)", - __func__); + SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; " + "isVsyncConfigEarly)", + __func__); return false; } } @@ -5180,12 +4667,12 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t nu status_t SurfaceFlinger::setTransactionState( const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states, - const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, + Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) { - ATRACE_CALL(); + SFTRACE_CALL(); IPCThreadState* ipc = IPCThreadState::self(); const int originPid = ipc->getCallingPid(); @@ -5195,7 +4682,7 @@ status_t SurfaceFlinger::setTransactionState( composerState.state.sanitize(permissions); } - for (DisplayState display : displays) { + for (DisplayState& display : displays) { display.sanitize(permissions); } @@ -5316,11 +4803,6 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid, uint64_t transactionId) { uint32_t transactionFlags = 0; - if (!mLayerLifecycleManagerEnabled) { - for (DisplayState& display : displays) { - transactionFlags |= setDisplayStateLocked(display); - } - } // start and end registration for listeners w/ no surface so they can get their callback. Note // that listeners with SurfaceControls will start registration during setClientStateLocked @@ -5328,27 +4810,11 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin for (const auto& listener : listenerCallbacks) { mTransactionCallbackInvoker.addEmptyTransaction(listener); } - nsecs_t now = systemTime(); uint32_t clientStateFlags = 0; for (auto& resolvedState : states) { clientStateFlags |= updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState, desiredPresentTime, isAutoTimestamp, postTime, transactionId); - if (!mLayerLifecycleManagerEnabled) { - if ((flags & eAnimation) && resolvedState.state.surface) { - if (const auto layer = LayerHandle::getLayer(resolvedState.state.surface)) { - const auto layerProps = scheduler::LayerProps{ - .visible = layer->isVisible(), - .bounds = layer->getBounds(), - .transform = layer->getTransform(), - .setFrameRateVote = layer->getFrameRateForLayerTree(), - .frameRateSelectionPriority = layer->getFrameRateSelectionPriority(), - .isFrontBuffered = layer->isFrontBuffered(), - }; - layer->recordLayerHistoryAnimationTx(layerProps, now); - } - } - } } transactionFlags |= clientStateFlags; @@ -5483,366 +4949,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), - std::vector<JankData>()); - } - 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, @@ -5879,10 +4985,8 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f } if (layer == nullptr) { for (auto& [listener, callbackIds] : s.listeners) { - mTransactionCallbackInvoker.addCallbackHandle(sp<CallbackHandle>::make(listener, - callbackIds, - s.surface), - std::vector<JankData>()); + mTransactionCallbackInvoker.addCallbackHandle( + sp<CallbackHandle>::make(listener, callbackIds, s.surface)); } return 0; } @@ -5897,6 +5001,17 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f sp<CallbackHandle>::make(listener, callbackIds, s.surface)); } } + + frontend::LayerSnapshot* snapshot = nullptr; + gui::GameMode gameMode = gui::GameMode::Unsupported; + if (what & (layer_state_t::eSidebandStreamChanged | layer_state_t::eBufferChanged) || + frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { + snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); + if (snapshot) { + gameMode = snapshot->gameMode; + } + } + // TODO(b/238781169) remove after screenshot refactor, currently screenshots // requires to read drawing state from binder thread. So we need to fix that // before removing this. @@ -5911,7 +5026,7 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; } if (what & layer_state_t::eSidebandStreamChanged) { - if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime)) + if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime, gameMode)) flags |= eTraversalNeeded; } if (what & layer_state_t::eDataspaceChanged) { @@ -5929,18 +5044,17 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f } if (what & layer_state_t::eBufferChanged) { std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt; - frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); if (snapshot) { transformHint = snapshot->transformHint; } layer->setTransformHint(transformHint); if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime, - desiredPresentTime, isAutoTimestamp, frameTimelineInfo)) { + desiredPresentTime, isAutoTimestamp, frameTimelineInfo, gameMode)) { flags |= eTraversalNeeded; } - mLayersWithQueuedFrames.emplace(layer); + mLayersWithQueuedFrames.emplace(layer, gameMode); } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { - layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime); + layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime, gameMode); } if ((what & layer_state_t::eBufferChanged) == 0) { @@ -5954,6 +5068,10 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f } } + if (what & layer_state_t::eBufferReleaseChannelChanged) { + layer->setBufferReleaseChannel(s.bufferReleaseChannel); + } + const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence()); bool willPresentCurrentTransaction = requestedLayerState && (requestedLayerState->hasReadyFrame() || @@ -5992,8 +5110,6 @@ status_t SurfaceFlinger::mirrorLayer(const LayerCreationArgs& args, if (result != NO_ERROR) { return result; } - - mirrorLayer->setClonedChild(mirrorFrom->createClone()); } outResult.layerId = mirrorLayer->sequence; @@ -6107,31 +5223,22 @@ status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBi return NO_ERROR; } -void SurfaceFlinger::markLayerPendingRemovalLocked(const sp<Layer>& layer) { - mLayersPendingRemoval.add(layer); - mLayersRemoved = true; - setTransactionFlags(eTransactionNeeded); -} - void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer, uint32_t layerId) { { - std::scoped_lock<std::mutex> lock(mCreatedLayersLock); - mDestroyedHandles.emplace_back(layerId, layer->getDebugName()); - } - - { // Used to remove stalled transactions which uses an internal lock. ftl::FakeGuard guard(kMainThreadContext); mTransactionHandler.onLayerDestroyed(layerId); } + JankTracker::flushJankData(layerId); - Mutex::Autolock lock(mStateLock); - markLayerPendingRemovalLocked(layer); + std::scoped_lock<std::mutex> lock(mCreatedLayersLock); + mDestroyedHandles.emplace_back(layerId, layer->getDebugName()); + + Mutex::Autolock stateLock(mStateLock); layer->onHandleDestroyed(); mBufferCountTracker.remove(handle); layer.clear(); - - setTransactionFlags(eTransactionFlushNeeded); + setTransactionFlags(eTransactionFlushNeeded | eTransactionNeeded); } void SurfaceFlinger::initializeDisplays() { @@ -6402,15 +5509,23 @@ status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) { return NO_ERROR; } - // Traversal of drawing state must happen on the main thread. - // Otherwise, SortedVector may have shared ownership during concurrent - // traversals, which can result in use-after-frees. + // Collect debug data from main thread std::string compositionLayers; mScheduler ->schedule([&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) { dumpVisibleFrontEnd(compositionLayers); }) .get(); + // get window info listener data without the state lock + auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo(); + compositionLayers.append("Window Infos:\n"); + StringAppendF(&compositionLayers, " max send vsync id: %" PRId64 "\n", + ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId)); + StringAppendF(&compositionLayers, " max send delay (ns): %" PRId64 " ns\n", + windowInfosDebug.maxSendDelayDuration); + StringAppendF(&compositionLayers, " unsent messages: %zu\n", + windowInfosDebug.pendingMessageCount); + compositionLayers.append("\n"); dumpAll(args, compositionLayers, result); write(fd, result.c_str(), result.size()); return NO_ERROR; @@ -6427,7 +5542,7 @@ void SurfaceFlinger::listLayers(std::string& result) const { } void SurfaceFlinger::dumpStats(const DumpArgs& args, std::string& result) const { - StringAppendF(&result, "%" PRId64 "\n", getVsyncPeriodFromHWC()); + StringAppendF(&result, "%" PRId64 "\n", mScheduler->getPacesetterVsyncPeriod().ns()); if (args.size() < 2) return; const auto name = String8(args[1]); @@ -6462,8 +5577,8 @@ void SurfaceFlinger::logFrameStats(TimePoint now) { if (now - sTimestamp < 30min) return; sTimestamp = now; - ATRACE_CALL(); - mDrawingState.traverse([&](Layer* layer) { layer->logFrameStats(); }); + SFTRACE_CALL(); + traverseLegacyLayers([&](Layer* layer) { layer->logFrameStats(); }); } void SurfaceFlinger::appendSfConfigString(std::string& result) const { @@ -6487,11 +5602,6 @@ void SurfaceFlinger::dumpScheduler(std::string& result) const { // TODO(b/241285876): Move to DisplayModeController. dumper.dump("debugDisplayModeSetByBackdoor"sv, mDebugDisplayModeSetByBackdoor); dumper.eol(); - - StringAppendF(&result, - " present offset: %9" PRId64 " ns\t VSYNC period: %9" PRId64 - " ns\n\n", - dispSyncPresentTimeOffset, getVsyncPeriodFromHWC()); } void SurfaceFlinger::dumpEvents(std::string& result) const { @@ -6654,53 +5764,35 @@ void SurfaceFlinger::dumpFrontEnd(std::string& result) { } void SurfaceFlinger::dumpVisibleFrontEnd(std::string& result) { - if (!mLayerLifecycleManagerEnabled) { - StringAppendF(&result, "Composition layers\n"); - mDrawingState.traverseInZOrder([&](Layer* layer) { - auto* compositionState = layer->getCompositionState(); - if (!compositionState || !compositionState->isVisible) return; - android::base::StringAppendF(&result, "* Layer %p (%s)\n", layer, - layer->getDebugName() ? layer->getDebugName() - : "<unknown>"); - compositionState->dump(result); - }); - - StringAppendF(&result, "Offscreen Layers\n"); - for (Layer* offscreenLayer : mOffscreenLayers) { - offscreenLayer->traverse(LayerVector::StateSet::Drawing, - [&](Layer* layer) { layer->dumpOffscreenDebugInfo(result); }); - } - } else { - std::ostringstream out; - out << "\nComposition list\n"; - ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK; - mLayerSnapshotBuilder.forEachVisibleSnapshot( - [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) { - if (snapshot->hasSomethingToDraw()) { - if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) { - lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack; - out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n"; - } - out << " " << *snapshot << "\n"; + std::ostringstream out; + out << "\nComposition list\n"; + ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK; + mLayerSnapshotBuilder.forEachVisibleSnapshot( + [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) { + if (snapshot->hasSomethingToDraw()) { + if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) { + lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack; + out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n"; } - }); + out << " " << *snapshot << "\n"; + } + }); - out << "\nInput list\n"; - lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK; - mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) { - if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) { - lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack; - out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n"; - } - out << " " << snapshot << "\n"; - }); + out << "\nInput list\n"; + lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK; + mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) { + if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) { + lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack; + out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n"; + } + out << " " << snapshot << "\n"; + }); - out << "\nLayer Hierarchy\n" - << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n" - << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n"; - result = out.str(); - dumpHwcLayersMinidump(result); - } + out << "\nLayer Hierarchy\n" + << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n" + << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n"; + result = out.str(); + dumpHwcLayersMinidump(result); } perfetto::protos::LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const { @@ -6715,9 +5807,16 @@ perfetto::protos::LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t tra } } - return LayerProtoFromSnapshotGenerator(mLayerSnapshotBuilder, mFrontEndDisplayInfos, - mLegacyLayers, traceFlags) - .generate(mLayerHierarchyBuilder.getHierarchy()); + auto traceGenerator = + LayerProtoFromSnapshotGenerator(mLayerSnapshotBuilder, mFrontEndDisplayInfos, + mLegacyLayers, traceFlags) + .with(mLayerHierarchyBuilder.getHierarchy()); + + if (traceFlags & LayerTracing::Flag::TRACE_EXTRA) { + traceGenerator.withOffscreenLayers(mLayerHierarchyBuilder.getOffscreenHierarchy()); + } + + return traceGenerator.generate(); } google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> @@ -6751,26 +5850,6 @@ void SurfaceFlinger::dumpHwc(std::string& result) const { getHwComposer().dump(result); } -void SurfaceFlinger::dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto, - uint32_t traceFlags) const { - // Add a fake invisible root layer to the proto output and parent all the offscreen layers to - // it. - perfetto::protos::LayerProto* rootProto = layersProto.add_layers(); - const int32_t offscreenRootLayerId = INT32_MAX - 2; - rootProto->set_id(offscreenRootLayerId); - rootProto->set_name("Offscreen Root"); - rootProto->set_parent(-1); - - for (Layer* offscreenLayer : mOffscreenLayers) { - // Add layer as child of the fake root - rootProto->add_children(offscreenLayer->sequence); - - // Add layer - auto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags); - layerProto->set_parent(offscreenRootLayerId); - } -} - perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) { return mScheduler ->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) { @@ -6779,41 +5858,7 @@ perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t t .get(); } -void SurfaceFlinger::dumpOffscreenLayers(std::string& result) { - auto future = mScheduler->schedule([this] { - std::string result; - for (Layer* offscreenLayer : mOffscreenLayers) { - offscreenLayer->traverse(LayerVector::StateSet::Drawing, - [&](Layer* layer) { layer->dumpOffscreenDebugInfo(result); }); - } - return result; - }); - - result.append("Offscreen Layers:\n"); - result.append(future.get()); -} - -void SurfaceFlinger::dumpHwcLayersMinidumpLockedLegacy(std::string& result) const { - for (const auto& [token, display] : mDisplays) { - const auto displayId = HalDisplayId::tryCast(display->getId()); - if (!displayId) { - continue; - } - - StringAppendF(&result, "Display %s (%s) HWC layers:\n", to_string(*displayId).c_str(), - displayId == mActiveDisplayId ? "active" : "inactive"); - Layer::miniDumpHeader(result); - - const DisplayDevice& ref = *display; - mDrawingState.traverseInZOrder([&](Layer* layer) { layer->miniDumpLegacy(result, ref); }); - result.append("\n"); - } -} - void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const { - if (!mLayerLifecycleManagerEnabled) { - return dumpHwcLayersMinidumpLockedLegacy(result); - } for (const auto& [token, display] : mDisplays) { const auto displayId = HalDisplayId::tryCast(display->getId()); if (!displayId) { @@ -6893,8 +5938,7 @@ void SurfaceFlinger::dumpAll(const DumpArgs& args, const std::string& compositio * Dump the visible layer list */ colorizer.bold(result); - StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n", - mLayerLifecycleManagerEnabled ? "true" : "false"); + StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n", "true"); StringAppendF(&result, "Active Layers - layers with client handles (count = %zu)\n", mNumLayers.load()); colorizer.reset(result); @@ -6993,15 +6037,6 @@ void SurfaceFlinger::dumpAll(const DumpArgs& args, const std::string& compositio result.append(mTimeStats->miniDump()); result.append("\n"); - - result.append("Window Infos:\n"); - auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo(); - StringAppendF(&result, " max send vsync id: %" PRId64 "\n", - ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId)); - StringAppendF(&result, " max send delay (ns): %" PRId64 " ns\n", - windowInfosDebug.maxSendDelayDuration); - StringAppendF(&result, " unsent messages: %zu\n", windowInfosDebug.pendingMessageCount); - result.append("\n"); } mat4 SurfaceFlinger::calculateColorMatrix(float saturation) { @@ -7495,15 +6530,9 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r return NO_ERROR; } case 1039: { - PhysicalDisplayId displayId = [&]() { - Mutex::Autolock lock(mStateLock); - return getDefaultDisplayDeviceLocked()->getPhysicalId(); - }(); - - auto inUid = static_cast<uid_t>(data.readInt32()); + const auto uid = static_cast<uid_t>(data.readInt32()); const auto refreshRate = data.readFloat(); - mScheduler->setPreferredRefreshRateForUid(FrameRateOverride{inUid, refreshRate}); - mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId); + mScheduler->setPreferredRefreshRateForUid(FrameRateOverride{uid, refreshRate}); return NO_ERROR; } // Toggle caching feature @@ -7692,7 +6721,7 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) { // Update the overlay on the main thread to avoid race conditions with // RefreshRateSelector::getActiveMode - static_cast<void>(mScheduler->schedule([=, this] { + static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) { const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()); if (!display) { ALOGW("%s: default display is null", __func__); @@ -7700,15 +6729,9 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) { } if (!display->isRefreshRateOverlayEnabled()) return; - const auto desiredModeIdOpt = - mDisplayModeController.getDesiredMode(display->getPhysicalId()) - .transform([](const display::DisplayModeRequest& request) { - return request.mode.modePtr->getId(); - }); - - const bool timerExpired = mKernelIdleTimerEnabled && expired; + const auto state = mDisplayModeController.getKernelIdleTimerState(display->getPhysicalId()); - if (display->onKernelTimerChanged(desiredModeIdOpt, timerExpired)) { + if (display->onKernelTimerChanged(state.desiredModeIdOpt, state.isEnabled && expired)) { mScheduler->scheduleFrame(); } })); @@ -7730,8 +6753,8 @@ void SurfaceFlinger::vrrDisplayIdle(bool idle) { })); } -std::pair<std::optional<KernelIdleTimerController>, std::chrono::milliseconds> -SurfaceFlinger::getKernelIdleTimerProperties(PhysicalDisplayId displayId) { +auto SurfaceFlinger::getKernelIdleTimerProperties(PhysicalDisplayId displayId) + -> std::pair<std::optional<KernelIdleTimerController>, std::chrono::milliseconds> { const bool isKernelIdleTimerHwcSupported = getHwComposer().getComposer()->isSupported( android::Hwc2::Composer::OptionalFeature::KernelIdleTimer); const auto timeout = getIdleTimerTimeout(displayId); @@ -7755,63 +6778,6 @@ SurfaceFlinger::getKernelIdleTimerProperties(PhysicalDisplayId displayId) { return {std::nullopt, timeout}; } -void SurfaceFlinger::updateKernelIdleTimer(std::chrono::milliseconds timeout, - KernelIdleTimerController controller, - PhysicalDisplayId displayId) { - switch (controller) { - case KernelIdleTimerController::HwcApi: { - getHwComposer().setIdleTimerEnabled(displayId, timeout); - break; - } - case KernelIdleTimerController::Sysprop: { - base::SetProperty(KERNEL_IDLE_TIMER_PROP, timeout > 0ms ? "true" : "false"); - break; - } - } -} - -void SurfaceFlinger::toggleKernelIdleTimer() { - using KernelIdleTimerAction = scheduler::RefreshRateSelector::KernelIdleTimerAction; - - const auto display = getDefaultDisplayDeviceLocked(); - if (!display) { - ALOGW("%s: default display is null", __func__); - return; - } - - // If the support for kernel idle timer is disabled for the active display, - // don't do anything. - const std::optional<KernelIdleTimerController> kernelIdleTimerController = - display->refreshRateSelector().kernelIdleTimerController(); - if (!kernelIdleTimerController.has_value()) { - return; - } - - const KernelIdleTimerAction action = display->refreshRateSelector().getIdleTimerAction(); - - switch (action) { - case KernelIdleTimerAction::TurnOff: - if (mKernelIdleTimerEnabled) { - ATRACE_INT("KernelIdleTimer", 0); - std::chrono::milliseconds constexpr kTimerDisabledTimeout = 0ms; - updateKernelIdleTimer(kTimerDisabledTimeout, kernelIdleTimerController.value(), - display->getPhysicalId()); - mKernelIdleTimerEnabled = false; - } - break; - case KernelIdleTimerAction::TurnOn: - if (!mKernelIdleTimerEnabled) { - ATRACE_INT("KernelIdleTimer", 1); - const std::chrono::milliseconds timeout = - display->refreshRateSelector().getIdleTimerTimeout(); - updateKernelIdleTimer(timeout, kernelIdleTimerController.value(), - display->getPhysicalId()); - mKernelIdleTimerEnabled = true; - } - break; - } -} - // A simple RAII class to disconnect from an ANativeWindow* when it goes out of scope class WindowDisconnector { public: @@ -7837,7 +6803,8 @@ static status_t validateScreenshotPermissions(const CaptureArgs& captureArgs) { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); const int uid = ipc->getCallingUid(); - if (uid == AID_GRAPHICS || PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { + if (uid == AID_GRAPHICS || uid == AID_SYSTEM || + PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { return OK; } @@ -7930,9 +6897,10 @@ static void invokeScreenCaptureError(const status_t status, void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { - ATRACE_CALL(); + SFTRACE_CALL(); - status_t validate = validateScreenshotPermissions(args); + const auto& captureArgs = args.captureArgs; + status_t validate = validateScreenshotPermissions(captureArgs); if (validate != OK) { ALOGD("Permission denied to captureDisplay"); invokeScreenCaptureError(validate, captureListener); @@ -7945,7 +6913,7 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, return; } - if (args.captureSecureLayers && !hasCaptureBlackoutContentPermission()) { + if (captureArgs.captureSecureLayers && !hasCaptureBlackoutContentPermission()) { ALOGD("Attempting to capture secure layers without CAPTURE_BLACKOUT_CONTENT"); invokeScreenCaptureError(PERMISSION_DENIED, captureListener); return; @@ -7971,7 +6939,7 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, reqSize = display->getLayerStackSpaceRect().getSize(); } - for (const auto& handle : args.excludeHandles) { + for (const auto& handle : captureArgs.excludeHandles) { uint32_t excludeLayer = LayerHandle::getLayerId(handle); if (excludeLayer != UNASSIGNED_LAYER_ID) { excludeLayerIds.emplace(excludeLayer); @@ -7984,17 +6952,22 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, } GetLayerSnapshotsFunction getLayerSnapshotsFn = - getLayerSnapshotsForScreenshots(layerStack, args.uid, std::move(excludeLayerIds)); + getLayerSnapshotsForScreenshots(layerStack, captureArgs.uid, + std::move(excludeLayerIds)); ftl::Flags<RenderArea::Options> options; - if (args.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; - if (args.hintForSeamlessTransition) + if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; + if (captureArgs.hintForSeamlessTransition) options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>, - args.sourceCrop, reqSize, args.dataspace, + gui::aidl_utils::fromARect(captureArgs.sourceCrop), + reqSize, + static_cast<ui::Dataspace>(captureArgs.dataspace), displayWeak, options), - getLayerSnapshotsFn, reqSize, args.pixelFormat, args.allowProtected, - args.grayscale, captureListener); + getLayerSnapshotsFn, reqSize, + static_cast<ui::PixelFormat>(captureArgs.pixelFormat), + captureArgs.allowProtected, captureArgs.grayscale, + captureArgs.attachGainmap, captureListener); } void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args, @@ -8047,10 +7020,11 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args if (args.hintForSeamlessTransition) options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>, - Rect(), size, args.dataspace, displayWeak, - options), - getLayerSnapshotsFn, size, args.pixelFormat, kAllowProtected, kGrayscale, - captureListener); + Rect(), size, + static_cast<ui::Dataspace>(args.dataspace), + displayWeak, options), + getLayerSnapshotsFn, size, static_cast<ui::PixelFormat>(args.pixelFormat), + kAllowProtected, kGrayscale, args.attachGainmap, captureListener); } ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) { @@ -8061,22 +7035,25 @@ ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& a void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { - ATRACE_CALL(); + SFTRACE_CALL(); + + const auto& captureArgs = args.captureArgs; - status_t validate = validateScreenshotPermissions(args); + status_t validate = validateScreenshotPermissions(captureArgs); if (validate != OK) { ALOGD("Permission denied to captureLayers"); invokeScreenCaptureError(validate, captureListener); return; } + auto crop = gui::aidl_utils::fromARect(captureArgs.sourceCrop); + ui::Size reqSize; sp<Layer> parent; - Rect crop(args.sourceCrop); std::unordered_set<uint32_t> excludeLayerIds; - ui::Dataspace dataspace = args.dataspace; + ui::Dataspace dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace); - if (args.captureSecureLayers && !hasCaptureBlackoutContentPermission()) { + if (captureArgs.captureSecureLayers && !hasCaptureBlackoutContentPermission()) { ALOGD("Attempting to capture secure layers without CAPTURE_BLACKOUT_CONTENT"); invokeScreenCaptureError(PERMISSION_DENIED, captureListener); return; @@ -8093,26 +7070,27 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, } Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState()); - if (args.sourceCrop.width() <= 0) { + if (crop.width() <= 0) { crop.left = 0; crop.right = parentSourceBounds.getWidth(); } - if (args.sourceCrop.height() <= 0) { + if (crop.height() <= 0) { crop.top = 0; crop.bottom = parentSourceBounds.getHeight(); } - if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) { + if (crop.isEmpty() || captureArgs.frameScaleX <= 0.0f || captureArgs.frameScaleY <= 0.0f) { // Error out if the layer has no source bounds (i.e. they are boundless) and a source // crop was not specified, or an invalid frame scale was provided. ALOGD("Boundless layer, unspecified crop, or invalid frame scale to captureLayers"); invokeScreenCaptureError(BAD_VALUE, captureListener); return; } - reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY); + reqSize = ui::Size(crop.width() * captureArgs.frameScaleX, + crop.height() * captureArgs.frameScaleY); - for (const auto& handle : args.excludeHandles) { + for (const auto& handle : captureArgs.excludeHandles) { uint32_t excludeLayer = LayerHandle::getLayerId(handle); if (excludeLayer != UNASSIGNED_LAYER_ID) { excludeLayerIds.emplace(excludeLayer); @@ -8138,8 +7116,9 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, } GetLayerSnapshotsFunction getLayerSnapshotsFn = - getLayerSnapshotsForScreenshots(parent->sequence, args.uid, std::move(excludeLayerIds), - args.childrenOnly, parentCrop); + getLayerSnapshotsForScreenshots(parent->sequence, captureArgs.uid, + std::move(excludeLayerIds), args.childrenOnly, + parentCrop); if (captureListener == nullptr) { ALOGD("capture screen must provide a capture listener callback"); @@ -8148,14 +7127,16 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, } ftl::Flags<RenderArea::Options> options; - if (args.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; - if (args.hintForSeamlessTransition) + if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; + if (captureArgs.hintForSeamlessTransition) options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<LayerRenderAreaBuilder>, crop, reqSize, dataspace, parent, args.childrenOnly, options), - getLayerSnapshotsFn, reqSize, args.pixelFormat, args.allowProtected, - args.grayscale, captureListener); + getLayerSnapshotsFn, reqSize, + static_cast<ui::PixelFormat>(captureArgs.pixelFormat), + captureArgs.allowProtected, captureArgs.grayscale, + captureArgs.attachGainmap, captureListener); } // Creates a Future release fence for a layer and keeps track of it in a list to @@ -8164,9 +7145,7 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, void SurfaceFlinger::attachReleaseFenceFutureToLayer(Layer* layer, LayerFE* layerFE, ui::LayerStack layerStack) { ftl::Future<FenceResult> futureFence = layerFE->createReleaseFenceFuture(); - Layer* clonedFrom = layer->getClonedFrom().get(); - auto owningLayer = clonedFrom ? clonedFrom : layer; - owningLayer->prepareReleaseCallbacks(std::move(futureFence), layerStack); + layer->prepareReleaseCallbacks(std::move(futureFence), layerStack); } // Loop over all visible layers to see whether there's any protected layer. A protected layer is @@ -8189,12 +7168,12 @@ bool SurfaceFlinger::layersHasProtectedLayer(const std::vector<sp<LayerFE>>& lay // Accessing display requires mStateLock, and contention for this lock // is reduced when grabbed from the main thread, thus also reducing // risk of deadlocks. -std::optional<SurfaceFlinger::OutputCompositionState> -SurfaceFlinger::getDisplayAndLayerSnapshotsFromMainThread( +std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapshotsFromMainThread( RenderAreaBuilderVariant& renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, std::vector<sp<LayerFE>>& layerFEs) { return mScheduler ->schedule([=, this, &renderAreaBuilder, &layerFEs]() REQUIRES(kMainThreadContext) { + SFTRACE_NAME("getSnapshotsFromMainThread"); auto layers = getLayerSnapshotsFn(); for (auto& [layer, layerFE] : layers) { attachReleaseFenceFutureToLayer(layer, layerFE.get(), ui::INVALID_LAYER_STACK); @@ -8208,9 +7187,9 @@ SurfaceFlinger::getDisplayAndLayerSnapshotsFromMainThread( void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, - bool allowProtected, bool grayscale, + bool allowProtected, bool grayscale, bool attachGainmap, const sp<IScreenCaptureListener>& captureListener) { - ATRACE_CALL(); + SFTRACE_CALL(); if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) { ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32 @@ -8224,8 +7203,7 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil FlagManager::getInstance().ce_fence_promise() && mRenderEngine->isThreaded()) { std::vector<sp<LayerFE>> layerFEs; auto displayState = - getDisplayAndLayerSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, - layerFEs); + getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layerFEs); const bool supportsProtected = getRenderEngine().supportsProtectedContent(); bool hasProtectedLayer = false; @@ -8255,9 +7233,9 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture::Usage:: WRITEABLE); - auto futureFence = - captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, grayscale, - isProtected, captureListener, displayState, layerFEs); + auto futureFence = captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, + grayscale, isProtected, attachGainmap, captureListener, + displayState, layerFEs); futureFence.get(); } else { @@ -8292,7 +7270,7 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil WRITEABLE); auto futureFence = captureScreenshotLegacy(renderAreaBuilder, getLayerSnapshotsFn, texture, false /* regionSampling */, grayscale, - isProtected, captureListener); + isProtected, attachGainmap, captureListener); futureFence.get(); } } @@ -8346,9 +7324,10 @@ std::vector<sp<LayerFE>> SurfaceFlinger::extractLayerFEs( ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( const RenderAreaBuilderVariant& renderAreaBuilder, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, + bool grayscale, bool isProtected, bool attachGainmap, + const sp<IScreenCaptureListener>& captureListener, std::optional<OutputCompositionState>& displayState, std::vector<sp<LayerFE>>& layerFEs) { - ATRACE_CALL(); + SFTRACE_CALL(); ScreenCaptureResults captureResults; std::unique_ptr<const RenderArea> renderArea = @@ -8363,19 +7342,87 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( } return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share(); } + float displayBrightnessNits = displayState.value().displayBrightnessNits; + float sdrWhitePointNits = displayState.value().sdrWhitePointNits; // Empty vector needed to pass into renderScreenImpl for legacy path std::vector<std::pair<Layer*, sp<android::LayerFE>>> layers; ftl::SharedFuture<FenceResult> renderFuture = - renderScreenImpl(std::move(renderArea), buffer, regionSampling, grayscale, isProtected, - captureResults, displayState, layers, layerFEs); + renderScreenImpl(renderArea.get(), buffer, regionSampling, grayscale, isProtected, + attachGainmap, captureResults, displayState, layers, layerFEs); + + if (captureResults.capturedHdrLayers && attachGainmap && + FlagManager::getInstance().true_hdr_screenshots()) { + sp<GraphicBuffer> hdrBuffer = + getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), + HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */, + buffer->getUsage(), "screenshot-hdr"); + sp<GraphicBuffer> gainmapBuffer = + getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), + buffer->getPixelFormat(), 1 /* layerCount */, + buffer->getUsage(), "screenshot-gainmap"); + + const status_t bufferStatus = hdrBuffer->initCheck(); + const status_t gainmapBufferStatus = gainmapBuffer->initCheck(); + + if (bufferStatus != OK) { + ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.", __func__, + bufferStatus); + } else if (gainmapBufferStatus != OK) { + ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.", + __func__, gainmapBufferStatus); + } else { + captureResults.optionalGainMap = gainmapBuffer; + const auto hdrTexture = std::make_shared< + renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(), + renderengine::impl::ExternalTexture:: + Usage::WRITEABLE); + const auto gainmapTexture = std::make_shared< + renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(), + renderengine::impl::ExternalTexture:: + Usage::WRITEABLE); + ScreenCaptureResults unusedResults; + ftl::SharedFuture<FenceResult> hdrRenderFuture = + renderScreenImpl(renderArea.get(), hdrTexture, regionSampling, grayscale, + isProtected, attachGainmap, unusedResults, displayState, + layers, layerFEs); + + renderFuture = + ftl::Future(std::move(renderFuture)) + .then([&, hdrRenderFuture = std::move(hdrRenderFuture), + displayBrightnessNits, sdrWhitePointNits, + dataspace = captureResults.capturedDataspace, buffer, hdrTexture, + gainmapTexture](FenceResult fenceResult) -> FenceResult { + if (!fenceResult.ok()) { + return fenceResult; + } + + auto hdrFenceResult = hdrRenderFuture.get(); + + if (!hdrFenceResult.ok()) { + return hdrFenceResult; + } + + return getRenderEngine() + .drawGainmap(buffer, fenceResult.value()->get(), hdrTexture, + hdrFenceResult.value()->get(), + displayBrightnessNits / sdrWhitePointNits, + static_cast<ui::Dataspace>(dataspace), + gainmapTexture) + .get(); + }) + .share(); + }; + } if (captureListener) { // Defer blocking on renderFuture back to the Binder thread. return ftl::Future(std::move(renderFuture)) - .then([captureListener, captureResults = std::move(captureResults)]( - FenceResult fenceResult) mutable -> FenceResult { + .then([captureListener, captureResults = std::move(captureResults), + displayBrightnessNits, + sdrWhitePointNits](FenceResult fenceResult) mutable -> FenceResult { captureResults.fenceResult = std::move(fenceResult); + captureResults.hdrSdrRatio = displayBrightnessNits / sdrWhitePointNits; captureListener->onScreenCaptureCompleted(captureResults); return base::unexpected(NO_ERROR); }) @@ -8387,8 +7434,9 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshotLegacy( RenderAreaBuilderVariant renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener) { - ATRACE_CALL(); + bool grayscale, bool isProtected, bool attachGainmap, + const sp<IScreenCaptureListener>& captureListener) { + SFTRACE_CALL(); auto takeScreenshotFn = [=, this, renderAreaBuilder = std::move(renderAreaBuilder)]() REQUIRES( kMainThreadContext) mutable -> ftl::SharedFuture<FenceResult> { @@ -8416,8 +7464,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshotLegacy( auto layerFEs = extractLayerFEs(layers); ftl::SharedFuture<FenceResult> renderFuture = - renderScreenImpl(std::move(renderArea), buffer, regionSampling, grayscale, - isProtected, captureResults, displayState, layers, layerFEs); + renderScreenImpl(renderArea.get(), buffer, regionSampling, grayscale, isProtected, + attachGainmap, captureResults, displayState, layers, layerFEs); if (captureListener) { // Defer blocking on renderFuture back to the Binder thread. @@ -8447,12 +7495,11 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshotLegacy( } ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( - std::unique_ptr<const RenderArea> renderArea, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, ScreenCaptureResults& captureResults, - std::optional<OutputCompositionState>& displayState, + const RenderArea* renderArea, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + bool regionSampling, bool grayscale, bool isProtected, bool attachGainmap, + ScreenCaptureResults& captureResults, std::optional<OutputCompositionState>& displayState, std::vector<std::pair<Layer*, sp<LayerFE>>>& layers, std::vector<sp<LayerFE>>& layerFEs) { - ATRACE_CALL(); + SFTRACE_CALL(); for (auto& layerFE : layerFEs) { frontend::LayerSnapshot* snapshot = layerFE->mSnapshot.get(); @@ -8628,65 +7675,13 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( } void SurfaceFlinger::traverseLegacyLayers(const LayerVector::Visitor& visitor) const { - if (mLayerLifecycleManagerEnabled) { - for (auto& layer : mLegacyLayers) { - visitor(layer.second.get()); - } - } else { - mDrawingState.traverse(visitor); + for (auto& layer : mLegacyLayers) { + visitor(layer.second.get()); } } // --------------------------------------------------------------------------- -void SurfaceFlinger::State::traverse(const LayerVector::Visitor& visitor) const { - layersSortedByZ.traverse(visitor); -} - -void SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const { - layersSortedByZ.traverseInZOrder(stateSet, visitor); -} - -void SurfaceFlinger::State::traverseInReverseZOrder(const LayerVector::Visitor& visitor) const { - layersSortedByZ.traverseInReverseZOrder(stateSet, visitor); -} - -void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const int32_t uid, - std::unordered_set<uint32_t> excludeLayerIds, - const LayerVector::Visitor& visitor) { - // We loop through the first level of layers without traversing, - // as we need to determine which layers belong to the requested display. - for (const auto& layer : mDrawingState.layersSortedByZ) { - if (layer->getLayerStack() != layerStack) { - continue; - } - // relative layers are traversed in Layer::traverseInZOrder - layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) { - if (layer->isInternalDisplayOverlay()) { - return; - } - if (!layer->isVisible()) { - return; - } - if (uid != CaptureArgs::UNSET_UID && layer->getOwnerUid() != uid) { - return; - } - - if (!excludeLayerIds.empty()) { - auto p = sp<Layer>::fromExisting(layer); - while (p != nullptr) { - if (excludeLayerIds.count(p->sequence) != 0) { - return; - } - p = p->getParent(); - } - } - - visitor(layer); - }); - } -} - ftl::Optional<scheduler::FrameRateMode> SurfaceFlinger::getPreferredDisplayMode( PhysicalDisplayId displayId, DisplayModeId defaultModeId) const { if (const auto schedulerMode = mScheduler->getPreferredDisplayMode(); @@ -8708,7 +7703,7 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecsInternal( const sp<DisplayDevice>& display, const scheduler::RefreshRateSelector::PolicyVariant& policy) { const auto displayId = display->getPhysicalId(); - ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); + SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str()); Mutex::Autolock lock(mStateLock); @@ -8737,13 +7732,9 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy( const scheduler::RefreshRateSelector::Policy currentPolicy = selector.getCurrentPolicy(); ALOGV("Setting desired display mode specs: %s", currentPolicy.toString().c_str()); - // TODO(b/140204874): Leave the event in until we do proper testing with all apps that might - // be depending in this callback. - if (const auto activeMode = selector.getActiveMode(); displayId == mActiveDisplayId) { - mScheduler->onPrimaryDisplayModeChanged(scheduler::Cycle::Render, activeMode); - toggleKernelIdleTimer(); - } else { - mScheduler->onNonPrimaryDisplayModeChanged(scheduler::Cycle::Render, activeMode); + if (const bool isPacesetter = + mScheduler->onDisplayModeChanged(displayId, selector.getActiveMode())) { + mDisplayModeController.updateKernelIdleTimer(displayId); } auto preferredModeOpt = getPreferredDisplayMode(displayId, currentPolicy.defaultMode); @@ -8767,10 +7758,7 @@ status_t SurfaceFlinger::applyRefreshRateSelectorPolicy( setDesiredMode({std::move(preferredMode), .emitEvent = true}); // Update the frameRateOverride list as the display render rate might have changed - if (mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps)) { - triggerOnFrameRateOverridesChanged(); - } - + mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps); return NO_ERROR; } @@ -8801,7 +7789,7 @@ gui::DisplayModeSpecs::RefreshRateRanges translate(const FpsRanges& ranges) { status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken, const gui::DisplayModeSpecs& specs) { - ATRACE_CALL(); + SFTRACE_CALL(); if (!displayToken) { return BAD_VALUE; @@ -8835,7 +7823,7 @@ status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayTo status_t SurfaceFlinger::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken, gui::DisplayModeSpecs* outSpecs) { - ATRACE_CALL(); + SFTRACE_CALL(); if (!displayToken || !outSpecs) { return BAD_VALUE; @@ -8862,17 +7850,12 @@ status_t SurfaceFlinger::getDesiredDisplayModeSpecs(const sp<IBinder>& displayTo void SurfaceFlinger::onLayerFirstRef(Layer* layer) { mNumLayers++; - if (!layer->isRemovedFromCurrentState()) { - mScheduler->registerLayer(layer); - } + mScheduler->registerLayer(layer, scheduler::FrameRateCompatibility::Default); } void SurfaceFlinger::onLayerDestroyed(Layer* layer) { mNumLayers--; - removeHierarchyFromOffscreenLayers(layer); - if (!layer->isRemovedFromCurrentState()) { - mScheduler->deregisterLayer(layer); - } + mScheduler->deregisterLayer(layer); if (mTransactionTracing) { mTransactionTracing->onLayerRemoved(layer->getSequence()); } @@ -8883,24 +7866,6 @@ void SurfaceFlinger::onLayerUpdate() { scheduleCommit(FrameHint::kActive); } -// WARNING: ONLY CALL THIS FROM LAYER DTOR -// Here we add children in the current state to offscreen layers and remove the -// layer itself from the offscreen layer list. Since -// this is the dtor, it is safe to access the current state. This keeps us -// from dangling children layers such that they are not reachable from the -// Drawing state nor the offscreen layer list -// See b/141111965 -void SurfaceFlinger::removeHierarchyFromOffscreenLayers(Layer* layer) { - for (auto& child : layer->getCurrentChildren()) { - mOffscreenLayers.emplace(child.get()); - } - mOffscreenLayers.erase(layer); -} - -void SurfaceFlinger::removeFromOffscreenLayers(Layer* layer) { - mOffscreenLayers.erase(layer); -} - status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, float lightPosY, float lightPosZ, float lightRadius) { @@ -8930,13 +7895,7 @@ const std::unordered_map<std::string, uint32_t>& SurfaceFlinger::getGenericLayer } status_t SurfaceFlinger::setGameModeFrameRateOverride(uid_t uid, float frameRate) { - PhysicalDisplayId displayId = [&]() { - Mutex::Autolock lock(mStateLock); - return getDefaultDisplayDeviceLocked()->getPhysicalId(); - }(); - - mScheduler->setGameModeFrameRateForUid(FrameRateOverride{static_cast<uid_t>(uid), frameRate}); - mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId); + mScheduler->setGameModeFrameRateForUid(FrameRateOverride{uid, frameRate}); return NO_ERROR; } @@ -9049,51 +8008,6 @@ int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) con return calculateMaxAcquiredBufferCount(refreshRate, presentLatency); } -void SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state, VsyncId vsyncId) { - sp<Layer> layer = state.layer.promote(); - if (!layer) { - ALOGD("Layer was destroyed soon after creation %p", state.layer.unsafe_get()); - return; - } - MUTEX_ALIAS(mStateLock, layer->mFlinger->mStateLock); - - sp<Layer> parent; - bool addToRoot = state.addToRoot; - if (state.initialParent != nullptr) { - parent = state.initialParent.promote(); - if (parent == nullptr) { - ALOGD("Parent was destroyed soon after creation %p", state.initialParent.unsafe_get()); - addToRoot = false; - } - } - - if (parent == nullptr && addToRoot) { - layer->setIsAtRoot(true); - mCurrentState.layersSortedByZ.add(layer); - } else if (parent == nullptr) { - layer->onRemovedFromCurrentState(); - } else if (parent->isRemovedFromCurrentState()) { - parent->addChild(layer); - layer->onRemovedFromCurrentState(); - } else { - parent->addChild(layer); - } - - ui::LayerStack layerStack = layer->getLayerStack(LayerVector::StateSet::Current); - sp<const DisplayDevice> hintDisplay; - // Find the display that includes the layer. - for (const auto& [token, display] : mDisplays) { - if (display->getLayerStack() == layerStack) { - hintDisplay = display; - break; - } - } - - if (hintDisplay) { - layer->updateTransformHint(hintDisplay->getTransformHint()); - } -} - void SurfaceFlinger::sample() { if (!mLumaSampling || !mRegionSamplingThread) { return; @@ -9127,7 +8041,7 @@ sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const { void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveDisplayPtr, const DisplayDevice& activeDisplay) { - ATRACE_CALL(); + SFTRACE_CALL(); if (inactiveDisplayPtr) { inactiveDisplayPtr->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false); @@ -9136,8 +8050,6 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD mActiveDisplayId = activeDisplay.getPhysicalId(); activeDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true); - mScheduler->resetPhaseConfiguration(mDisplayModeController.getActiveMode(mActiveDisplayId).fps); - // TODO(b/255635711): Check for pending mode changes on other displays. mScheduler->setModeChangePending(false); @@ -9261,170 +8173,52 @@ 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) { - layer->updateMetadataSnapshot(parentMetadata); - } - - std::unordered_set<Layer*> visited; - mDrawingState.traverse([&visited](Layer* layer) { - if (visited.find(layer) != visited.end()) { - return; - } - - // If the layer isRelativeOf, then either it's relative metadata will be set - // recursively when updateRelativeMetadataSnapshot is called on its relative parent or - // it's relative parent has been deleted. Clear the layer's relativeLayerMetadata to ensure - // that layers with deleted relative parents don't hold stale relativeLayerMetadata. - if (layer->getDrawingState().isRelativeOf) { - layer->editLayerSnapshot()->relativeLayerMetadata = {}; - return; - } - - layer->updateRelativeMetadataSnapshot({}, visited); - }); -} - void SurfaceFlinger::moveSnapshotsFromCompositionArgs( compositionengine::CompositionRefreshArgs& refreshArgs, const std::vector<std::pair<Layer*, LayerFE*>>& layers) { - if (mLayerLifecycleManagerEnabled) { - std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots = - mLayerSnapshotBuilder.getSnapshots(); - for (auto [_, layerFE] : layers) { - auto i = layerFE->mSnapshot->globalZ; - snapshots[i] = std::move(layerFE->mSnapshot); - } - } - if (!mLayerLifecycleManagerEnabled) { - for (auto [layer, layerFE] : layers) { - layer->updateLayerSnapshot(std::move(layerFE->mSnapshot)); - } + std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots = + mLayerSnapshotBuilder.getSnapshots(); + for (auto [_, layerFE] : layers) { + auto i = layerFE->mSnapshot->globalZ; + snapshots[i] = std::move(layerFE->mSnapshot); } } std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToCompositionArgs( compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) { std::vector<std::pair<Layer*, LayerFE*>> layers; - if (mLayerLifecycleManagerEnabled) { - nsecs_t currentTime = systemTime(); - mLayerSnapshotBuilder.forEachVisibleSnapshot( - [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( - kMainThreadContext) { - if (cursorOnly && - snapshot->compositionType != - aidl::android::hardware::graphics::composer3::Composition::CURSOR) { - return; - } - - if (!snapshot->hasSomethingToDraw()) { - return; - } - - auto it = mLegacyLayers.find(snapshot->sequence); - LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(), - "Couldnt find layer object for %s", - snapshot->getDebugString().c_str()); - auto& legacyLayer = it->second; - sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path); - snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence); - layerFE->mSnapshot = std::move(snapshot); - refreshArgs.layers.push_back(layerFE); - layers.emplace_back(legacyLayer.get(), layerFE.get()); - }); - } - if (!mLayerLifecycleManagerEnabled) { - auto moveSnapshots = [&layers, &refreshArgs, cursorOnly](Layer* layer) { - if (const auto& layerFE = layer->getCompositionEngineLayerFE()) { + nsecs_t currentTime = systemTime(); + const bool needsMetadata = mCompositionEngine->getFeatureFlags().test( + compositionengine::Feature::kSnapshotLayerMetadata); + mLayerSnapshotBuilder.forEachSnapshot( + [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( + kMainThreadContext) { if (cursorOnly && - layer->getLayerSnapshot()->compositionType != - aidl::android::hardware::graphics::composer3::Composition::CURSOR) + snapshot->compositionType != + aidl::android::hardware::graphics::composer3::Composition::CURSOR) { return; - layer->updateSnapshot(refreshArgs.updatingGeometryThisFrame); - layerFE->mSnapshot = layer->stealLayerSnapshot(); - refreshArgs.layers.push_back(layerFE); - layers.emplace_back(layer, layerFE.get()); - } - }; + } - if (cursorOnly || !mVisibleRegionsDirty) { - // for hot path avoid traversals by walking though the previous composition list - for (sp<Layer> layer : mPreviouslyComposedLayers) { - moveSnapshots(layer.get()); - } - } else { - mPreviouslyComposedLayers.clear(); - mDrawingState.traverseInZOrder( - [&moveSnapshots](Layer* layer) { moveSnapshots(layer); }); - mPreviouslyComposedLayers.reserve(layers.size()); - for (auto [layer, _] : layers) { - mPreviouslyComposedLayers.push_back(sp<Layer>::fromExisting(layer)); - } - } - } + if (!snapshot->hasSomethingToDraw()) { + return; + } + auto it = mLegacyLayers.find(snapshot->sequence); + LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(), + "Couldnt find layer object for %s", + snapshot->getDebugString().c_str()); + auto& legacyLayer = it->second; + sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path); + snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence); + layerFE->mSnapshot = std::move(snapshot); + refreshArgs.layers.push_back(layerFE); + layers.emplace_back(legacyLayer.get(), layerFE.get()); + }, + [needsMetadata](const frontend::LayerSnapshot& snapshot) { + return snapshot.isVisible || + (needsMetadata && + snapshot.changes.test(frontend::RequestedLayerState::Changes::Metadata)); + }); return layers; } @@ -9551,33 +8345,6 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t u }; } -frontend::Update SurfaceFlinger::flushLifecycleUpdates() { - frontend::Update update; - ATRACE_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) { @@ -9599,7 +8366,7 @@ void SurfaceFlinger::doActiveLayersTracingIfNeeded(bool isCompositionComputed, perfetto::protos::LayersSnapshotProto SurfaceFlinger::takeLayersSnapshotProto( uint32_t traceFlags, TimePoint time, VsyncId vsyncId, bool visibleRegionDirty) { - ATRACE_CALL(); + SFTRACE_CALL(); perfetto::protos::LayersSnapshotProto snapshot; snapshot.set_elapsed_realtime_nanos(time.ns()); snapshot.set_vsync_id(ftl::to_underlying(vsyncId)); @@ -9608,9 +8375,6 @@ perfetto::protos::LayersSnapshotProto SurfaceFlinger::takeLayersSnapshotProto( 0); auto layers = dumpDrawingStateProto(traceFlags); - if (traceFlags & LayerTracing::Flag::TRACE_EXTRA) { - dumpOffscreenLayersProto(layers); - } *snapshot.mutable_layers() = std::move(layers); if (traceFlags & LayerTracing::Flag::TRACE_HWC) { @@ -10489,6 +9253,28 @@ binder::Status SurfaceComposerAIDL::notifyShutdown() { return ::android::binder::Status::ok(); } +binder::Status SurfaceComposerAIDL::addJankListener(const sp<IBinder>& layerHandle, + const sp<gui::IJankListener>& listener) { + sp<Layer> layer = LayerHandle::getLayer(layerHandle); + if (layer == nullptr) { + return binder::Status::fromExceptionCode(binder::Status::EX_NULL_POINTER); + } + JankTracker::addJankListener(layer->sequence, IInterface::asBinder(listener)); + return binder::Status::ok(); +} + +binder::Status SurfaceComposerAIDL::flushJankData(int32_t layerId) { + JankTracker::flushJankData(layerId); + return binder::Status::ok(); +} + +binder::Status SurfaceComposerAIDL::removeJankListener(int32_t layerId, + const sp<gui::IJankListener>& listener, + int64_t afterVsync) { + JankTracker::removeJankListener(layerId, IInterface::asBinder(listener), afterVsync); + return binder::Status::ok(); +} + status_t SurfaceComposerAIDL::checkAccessPermission(bool usePermissionCache) { if (!mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) { IPCThreadState* ipc = IPCThreadState::self(); |