From 82d524e49b4f0acd9ad1a85599500df84fcfc0d2 Mon Sep 17 00:00:00 2001 From: Melody Hsu Date: Fri, 23 Feb 2024 02:37:38 +0000 Subject: Reland refactor of screenshot code on main thread. Create helper functions to improve readability of what is scheduled on the SurfaceFlinger main thread. This will allow for cleaner changes in reducing the calls on the main thread for screenshots. Changes include some renaming for better clarity. Bug: b/294936197 Test: presubmit Test: atest SurfaceFlinger_test Change-Id: I3643b27b98e20578c51f90f6ab61d1aa2e3458bb --- services/surfaceflinger/SurfaceFlinger.cpp | 103 +++++++++++++++-------------- 1 file changed, 54 insertions(+), 49 deletions(-) (limited to 'services/surfaceflinger/SurfaceFlinger.cpp') diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index cf5f55d7bd..8847ceea44 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -8063,6 +8063,19 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, args.allowProtected, args.grayscale, captureListener); } +bool SurfaceFlinger::layersHasProtectedLayer( + const std::vector>>& layers) const { + bool protectedLayerFound = false; + for (auto& [_, layerFe] : layers) { + protectedLayerFound |= + (layerFe->mSnapshot->isVisible && layerFe->mSnapshot->hasProtectedContent); + if (protectedLayerFound) { + break; + } + } + return protectedLayerFound; +} + void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, @@ -8085,18 +8098,9 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, const bool supportsProtected = getRenderEngine().supportsProtectedContent(); bool hasProtectedLayer = false; if (allowProtected && supportsProtected) { - hasProtectedLayer = mScheduler - ->schedule([=]() { - bool protectedLayerFound = false; - auto layers = getLayerSnapshots(); - for (auto& [_, layerFe] : layers) { - protectedLayerFound |= - (layerFe->mSnapshot->isVisible && - layerFe->mSnapshot->hasProtectedContent); - } - return protectedLayerFound; - }) - .get(); + // Snapshots must be taken from the main thread. + auto layers = mScheduler->schedule([=]() { return getLayerSnapshots(); }).get(); + hasProtectedLayer = layersHasProtectedLayer(layers); } const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected; const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER | @@ -8121,52 +8125,53 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture::Usage:: WRITEABLE); - auto fence = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture, - false /* regionSampling */, grayscale, isProtected, - captureListener); - fence.get(); + auto futureFence = + captureScreenshot(std::move(renderAreaFuture), getLayerSnapshots, texture, + false /* regionSampling */, grayscale, isProtected, captureListener); + futureFence.get(); } -ftl::SharedFuture SurfaceFlinger::captureScreenCommon( +ftl::SharedFuture SurfaceFlinger::captureScreenshot( RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots, const std::shared_ptr& buffer, bool regionSampling, bool grayscale, bool isProtected, const sp& captureListener) { ATRACE_CALL(); - auto future = mScheduler->schedule( - [=, this, renderAreaFuture = std::move(renderAreaFuture)]() FTL_FAKE_GUARD( - kMainThreadContext) mutable -> ftl::SharedFuture { - ScreenCaptureResults captureResults; - std::shared_ptr renderArea = renderAreaFuture.get(); - if (!renderArea) { - ALOGW("Skipping screen capture because of invalid render area."); - if (captureListener) { - captureResults.fenceResult = base::unexpected(NO_MEMORY); - captureListener->onScreenCaptureCompleted(captureResults); - } - return ftl::yield(base::unexpected(NO_ERROR)).share(); - } + auto takeScreenshotFn = [=, this, renderAreaFuture = std::move(renderAreaFuture)]() REQUIRES( + kMainThreadContext) mutable -> ftl::SharedFuture { + ScreenCaptureResults captureResults; + std::shared_ptr renderArea = renderAreaFuture.get(); + if (!renderArea) { + ALOGW("Skipping screen capture because of invalid render area."); + if (captureListener) { + captureResults.fenceResult = base::unexpected(NO_MEMORY); + captureListener->onScreenCaptureCompleted(captureResults); + } + return ftl::yield(base::unexpected(NO_ERROR)).share(); + } - ftl::SharedFuture renderFuture; - renderArea->render([&]() FTL_FAKE_GUARD(kMainThreadContext) { - renderFuture = - renderScreenImpl(renderArea, getLayerSnapshots, buffer, regionSampling, - grayscale, isProtected, captureResults); - }); + ftl::SharedFuture renderFuture; + renderArea->render([&]() FTL_FAKE_GUARD(kMainThreadContext) { + renderFuture = renderScreenImpl(renderArea, getLayerSnapshots, buffer, regionSampling, + grayscale, isProtected, captureResults); + }); - 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 { - captureResults.fenceResult = std::move(fenceResult); - captureListener->onScreenCaptureCompleted(captureResults); - return base::unexpected(NO_ERROR); - }) - .share(); - } - return renderFuture; - }); + 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 { + captureResults.fenceResult = std::move(fenceResult); + captureListener->onScreenCaptureCompleted(captureResults); + return base::unexpected(NO_ERROR); + }) + .share(); + } + return renderFuture; + }; + + auto future = + mScheduler->schedule(FTL_FAKE_GUARD(kMainThreadContext, std::move(takeScreenshotFn))); // Flatten nested futures. auto chain = ftl::Future(std::move(future)).then([](ftl::SharedFuture future) { -- cgit v1.2.3-59-g8ed1b