Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b43b5837 authored by Melody Hsu's avatar Melody Hsu
Browse files

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: I729b62b3fc1919b5b048b7992b4aead336e87d7f
parent 2e077971
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -377,7 +377,7 @@ void RegionSamplingThread::captureSample() {
    constexpr bool kIsProtected = false;

    if (const auto fenceResult =
                mFlinger.captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, buffer,
                mFlinger.captureScreenshot(std::move(renderAreaFuture), getLayerSnapshots, buffer,
                                           kRegionSampling, kGrayscale, kIsProtected, nullptr)
                        .get();
        fenceResult.ok()) {
+55 −49
Original line number Diff line number Diff line
@@ -8040,6 +8040,19 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
                        args.allowProtected, args.grayscale, captureListener);
}

bool SurfaceFlinger::layersHasProtectedLayer(
        const std::vector<std::pair<Layer*, sp<LayerFE>>>& 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,
@@ -8055,6 +8068,9 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
        return;
    }

    // Snapshots must be taken from the main thread.
    auto layers = mScheduler->schedule([=]() { return getLayerSnapshots(); }).get();

    // Loop over all visible layers to see whether there's any protected layer. A protected layer is
    // typically a layer with DRM contents, or have the GRALLOC_USAGE_PROTECTED set on the buffer.
    // A protected layer has no implication on whether it's secure, which is explicitly set by
@@ -8062,18 +8078,7 @@ 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();
        hasProtectedLayer = layersHasProtectedLayer(layers);
    }
    const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
    const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
@@ -8098,20 +8103,19 @@ 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<FenceResult> SurfaceFlinger::captureScreenCommon(
ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
        RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots,
        const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
        bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener) {
    ATRACE_CALL();

    auto future = mScheduler->schedule(
            [=, this, renderAreaFuture = std::move(renderAreaFuture)]() FTL_FAKE_GUARD(
    auto takeScreenshotFn = [=, this, renderAreaFuture = std::move(renderAreaFuture)]() REQUIRES(
                                    kMainThreadContext) mutable -> ftl::SharedFuture<FenceResult> {
        ScreenCaptureResults captureResults;
        std::shared_ptr<RenderArea> renderArea = renderAreaFuture.get();
@@ -8126,8 +8130,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(

        ftl::SharedFuture<FenceResult> renderFuture;
        renderArea->render([&]() FTL_FAKE_GUARD(kMainThreadContext) {
                    renderFuture =
                            renderScreenImpl(renderArea, getLayerSnapshots, buffer, regionSampling,
            renderFuture = renderScreenImpl(renderArea, getLayerSnapshots, buffer, regionSampling,
                                            grayscale, isProtected, captureResults);
        });

@@ -8143,7 +8146,10 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(
                    .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<FenceResult> future) {
+5 −1
Original line number Diff line number Diff line
@@ -874,13 +874,17 @@ private:
    // Boot animation, on/off animations and screen capture
    void startBootAnim();

    bool layersHasProtectedLayer(const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) const;

    void captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, ui::Size bufferSize,
                             ui::PixelFormat, bool allowProtected, bool grayscale,
                             const sp<IScreenCaptureListener>&);
    ftl::SharedFuture<FenceResult> captureScreenCommon(

    ftl::SharedFuture<FenceResult> captureScreenshot(
            RenderAreaFuture, GetLayerSnapshotsFunction,
            const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
            bool grayscale, bool isProtected, const sp<IScreenCaptureListener>&);

    ftl::SharedFuture<FenceResult> renderScreenImpl(
            std::shared_ptr<const RenderArea>, GetLayerSnapshotsFunction,
            const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,