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

Commit c5a5b6e0 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

[sf] support region sampling with new frontend

Use the new screenshot function but add support for a
layer filter used by region sampling code.

Test: check gesture nav bar color
Test: atest libgui_test
Bug: 238781169
Change-Id: I1c9370fd59b290fd1451d5c77cd27c275c685090
parent 93b8b794
Loading
Loading
Loading
Loading
+61 −36
Original line number Diff line number Diff line
@@ -285,29 +285,23 @@ void RegionSamplingThread::captureSample() {

    std::unordered_set<sp<IRegionSamplingListener>, SpHash<IRegionSamplingListener>> listeners;

    auto traverseLayers = [&](const LayerVector::Visitor& visitor) {
        bool stopLayerFound = false;
        auto filterVisitor = [&](Layer* layer) {
            // We don't want to capture any layers beyond the stop layer
            if (stopLayerFound) return;

    auto layerFilterFn = [&](const char* layerName, uint32_t layerId, const Rect& bounds,
                             const ui::Transform transform, bool& outStopTraversal) -> bool {
        // Likewise if we just found a stop layer, set the flag and abort
        for (const auto& [area, stopLayerId, listener] : descriptors) {
                if (stopLayerId != UNASSIGNED_LAYER_ID && layer->getSequence() == stopLayerId) {
                    stopLayerFound = true;
                    return;
            if (stopLayerId != UNASSIGNED_LAYER_ID && layerId == stopLayerId) {
                outStopTraversal = true;
                return false;
            }
        }

        // Compute the layer's position on the screen
            const Rect bounds = Rect(layer->getBounds());
            const ui::Transform transform = layer->getTransform();
        constexpr bool roundOutwards = true;
        Rect transformed = transform.transform(bounds, roundOutwards);

        // If this layer doesn't intersect with the larger sampledBounds, skip capturing it
        Rect ignore;
            if (!transformed.intersect(sampledBounds, &ignore)) return;
        if (!transformed.intersect(sampledBounds, &ignore)) return false;

        // If the layer doesn't intersect a sampling area, skip capturing it
        bool intersectsAnyArea = false;
@@ -317,14 +311,46 @@ void RegionSamplingThread::captureSample() {
                listeners.insert(listener);
            }
        }
            if (!intersectsAnyArea) return;
        if (!intersectsAnyArea) return false;

        ALOGV("Traversing [%s] [%d, %d, %d, %d]", layerName, bounds.left, bounds.top, bounds.right,
              bounds.bottom);

            ALOGV("Traversing [%s] [%d, %d, %d, %d]", layer->getDebugName(), bounds.left,
                  bounds.top, bounds.right, bounds.bottom);
        return true;
    };

    std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshots;
    if (mFlinger.mLayerLifecycleManagerEnabled) {
        auto filterFn = [&](const frontend::LayerSnapshot& snapshot,
                            bool& outStopTraversal) -> bool {
            const Rect bounds =
                    frontend::RequestedLayerState::reduce(Rect(snapshot.geomLayerBounds),
                                                          snapshot.transparentRegionHint);
            const ui::Transform transform = snapshot.geomLayerTransform;
            return layerFilterFn(snapshot.name.c_str(), snapshot.path.id, bounds, transform,
                                 outStopTraversal);
        };
        getLayerSnapshots =
                mFlinger.getLayerSnapshotsForScreenshots(layerStack, CaptureArgs::UNSET_UID,
                                                         filterFn);
    } else {
        auto traverseLayers = [&](const LayerVector::Visitor& visitor) {
            bool stopLayerFound = false;
            auto filterVisitor = [&](Layer* layer) {
                // We don't want to capture any layers beyond the stop layer
                if (stopLayerFound) return;

                if (!layerFilterFn(layer->getDebugName(), layer->getSequence(),
                                   Rect(layer->getBounds()), layer->getTransform(),
                                   stopLayerFound)) {
                    return;
                }
                visitor(layer);
            };
            mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor);
        };
        getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);
    }

    std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
    if (mCachedBuffer && mCachedBuffer->getBuffer()->getWidth() == sampledBounds.getWidth() &&
@@ -344,7 +370,6 @@ void RegionSamplingThread::captureSample() {
                                                     renderengine::impl::ExternalTexture::Usage::
                                                             WRITEABLE);
    }
    auto getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers);

    constexpr bool kRegionSampling = true;
    constexpr bool kGrayscale = false;
+17 −5
Original line number Diff line number Diff line
@@ -6782,7 +6782,8 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,

    GetLayerSnapshotsFunction getLayerSnapshots;
    if (mLayerLifecycleManagerEnabled) {
        getLayerSnapshots = getLayerSnapshotsForScreenshots(layerStack, args.uid);
        getLayerSnapshots =
                getLayerSnapshotsForScreenshots(layerStack, args.uid, /*snapshotFilterFn=*/nullptr);
    } else {
        auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) {
            traverseLayersInLayerStack(layerStack, args.uid, visitor);
@@ -6824,7 +6825,8 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId,

    GetLayerSnapshotsFunction getLayerSnapshots;
    if (mLayerLifecycleManagerEnabled) {
        getLayerSnapshots = getLayerSnapshotsForScreenshots(layerStack, CaptureArgs::UNSET_UID);
        getLayerSnapshots = getLayerSnapshotsForScreenshots(layerStack, CaptureArgs::UNSET_UID,
                                                            /*snapshotFilterFn=*/nullptr);
    } else {
        auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) {
            traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
@@ -7852,12 +7854,18 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit
}

std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>
SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack,
                                                uint32_t uid) {
SurfaceFlinger::getLayerSnapshotsForScreenshots(
        std::optional<ui::LayerStack> layerStack, uint32_t uid,
        std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)>
                snapshotFilterFn) {
    return [&, layerStack, uid]() {
        std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
        bool stopTraversal = false;
        mLayerSnapshotBuilder.forEachVisibleSnapshot(
                [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
                    if (stopTraversal) {
                        return;
                    }
                    if (layerStack && snapshot->outputFilter.layerStack != *layerStack) {
                        return;
                    }
@@ -7867,6 +7875,9 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> la
                    if (!snapshot->hasSomethingToDraw()) {
                        return;
                    }
                    if (snapshotFilterFn && !snapshotFilterFn(*snapshot, stopTraversal)) {
                        return;
                    }

                    auto it = mLegacyLayers.find(snapshot->sequence);
                    LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(),
@@ -7905,7 +7916,8 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t u
                     .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap()};
        mLayerSnapshotBuilder.update(args);

        auto getLayerSnapshotsFn = getLayerSnapshotsForScreenshots({}, uid);
        auto getLayerSnapshotsFn =
                getLayerSnapshotsForScreenshots({}, uid, /*snapshotFilterFn=*/nullptr);
        std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn();
        args.root = mLayerHierarchyBuilder.getHierarchy();
        args.parentCrop.reset();
+3 −1
Original line number Diff line number Diff line
@@ -1387,7 +1387,9 @@ private:
                [](const auto& display) { return display.isRefreshRateOverlayEnabled(); });
    }
    std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
            std::optional<ui::LayerStack> layerStack, uint32_t uid);
            std::optional<ui::LayerStack> layerStack, uint32_t uid,
            std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)>
                    snapshotFilterFn);
    std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots(
            uint32_t rootLayerId, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds,
            bool childrenOnly, const FloatRect& parentCrop);