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

Commit 41ade202 authored by Melody Hsu's avatar Melody Hsu
Browse files

Wrap RenderArea creation in a builder pattern

Use a builder to pass around parameters used for RenderArea
creation. This allows more flexibility for when the RenderArea
is created, which aids in the overall goal of reducing the
number of SF main thread hops during screenshots. Creating a builder
will allow the render area to later be passed into
captureScreenCommon() without being wrapped in a future.

Bug: b/294936197
Test: atest SurfaceFlinger_test
Change-Id: I9545e02af42c7e6cd9b0c328e2ecce995811f2d7
parent d50d517f
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include "DisplayRenderArea.h"
#include "FrontEnd/LayerCreationArgs.h"
#include "Layer.h"
#include "RenderAreaBuilder.h"
#include "Scheduler/VsyncController.h"
#include "SurfaceFlinger.h"

@@ -279,8 +280,11 @@ void RegionSamplingThread::captureSample() {
    constexpr bool kHintForSeamlessTransition = false;

    SurfaceFlinger::RenderAreaFuture renderAreaFuture = ftl::defer([=] {
        return DisplayRenderArea::create(displayWeak, sampledBounds, sampledBounds.getSize(),
                                         ui::Dataspace::V0_SRGB, kHintForSeamlessTransition);
        DisplayRenderAreaBuilder displayRenderArea(sampledBounds, sampledBounds.getSize(),
                                                   ui::Dataspace::V0_SRGB,
                                                   kHintForSeamlessTransition,
                                                   true /* captureSecureLayers */, displayWeak);
        return displayRenderArea.build();
    });

    std::unordered_set<sp<IRegionSamplingListener>, SpHash<IRegionSamplingListener>> listeners;
+114 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "DisplayDevice.h"
#include "DisplayRenderArea.h"
#include "LayerRenderArea.h"
#include "ui/Size.h"
#include "ui/Transform.h"

namespace android {
/**
 * A parameter object for creating a render area
 */
struct RenderAreaBuilder {
    // Source crop of the render area
    Rect crop;

    // Size of the physical render area
    ui::Size reqSize;

    // Composition data space of the render area
    ui::Dataspace reqDataSpace;

    // If true, the secure layer would be blacked out or skipped
    // when rendered to an insecure render area
    bool allowSecureLayers;

    // If true, the render result may be used for system animations
    // that must preserve the exact colors of the display
    bool hintForSeamlessTransition;

    virtual std::unique_ptr<RenderArea> build() const = 0;

    RenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
                      bool allowSecureLayers, bool hintForSeamlessTransition)
          : crop(crop),
            reqSize(reqSize),
            reqDataSpace(reqDataSpace),
            allowSecureLayers(allowSecureLayers),
            hintForSeamlessTransition(hintForSeamlessTransition) {}

    virtual ~RenderAreaBuilder() = default;
};

struct DisplayRenderAreaBuilder : RenderAreaBuilder {
    DisplayRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
                             bool allowSecureLayers, bool hintForSeamlessTransition,
                             wp<const DisplayDevice> displayWeak)
          : RenderAreaBuilder(crop, reqSize, reqDataSpace, allowSecureLayers,
                              hintForSeamlessTransition),
            displayWeak(displayWeak) {}

    // Display that render area will be on
    wp<const DisplayDevice> displayWeak;

    std::unique_ptr<RenderArea> build() const override {
        return DisplayRenderArea::create(displayWeak, crop, reqSize, reqDataSpace,
                                         hintForSeamlessTransition, allowSecureLayers);
    }
};

struct LayerRenderAreaBuilder : RenderAreaBuilder {
    LayerRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
                           bool allowSecureLayers, bool hintForSeamlessTransition, sp<Layer> layer,
                           bool childrenOnly)
          : RenderAreaBuilder(crop, reqSize, reqDataSpace, allowSecureLayers,
                              hintForSeamlessTransition),
            layer(layer),
            childrenOnly(childrenOnly) {}

    // Layer that the render area will be on
    sp<Layer> layer;

    // Transform to be applied on the layers to transform them
    // into the logical render area
    ui::Transform layerTransform{ui::Transform()};

    // Buffer bounds
    Rect layerBufferSize{Rect()};

    // If false, transform is inverted from the parent snapshot
    bool childrenOnly;

    // Uses parent snapshot to determine layer transform and buffer size
    void setLayerInfo(const frontend::LayerSnapshot* parentSnapshot) {
        if (!childrenOnly) {
            layerTransform = parentSnapshot->localTransform.inverse();
        }
        layerBufferSize = parentSnapshot->bufferSize;
    }

    std::unique_ptr<RenderArea> build() const override {
        return std::make_unique<LayerRenderArea>(layer, crop, reqSize, reqDataSpace,
                                                 allowSecureLayers, layerTransform, layerBufferSize,
                                                 hintForSeamlessTransition);
    }
};

} // namespace android
 No newline at end of file
+24 −23
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@
#include "MutexUtils.h"
#include "NativeWindowSurface.h"
#include "RegionSamplingThread.h"
#include "RenderAreaBuilder.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/LayerHistory.h"
#include "Scheduler/Scheduler.h"
@@ -7918,8 +7919,10 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
    }

    RenderAreaFuture renderAreaFuture = ftl::defer([=] {
        return DisplayRenderArea::create(displayWeak, args.sourceCrop, reqSize, args.dataspace,
                                         args.hintForSeamlessTransition, args.captureSecureLayers);
        DisplayRenderAreaBuilder displayRenderArea(args.sourceCrop, reqSize, args.dataspace,
                                                   args.hintForSeamlessTransition,
                                                   args.captureSecureLayers, displayWeak);
        return displayRenderArea.build();
    });

    GetLayerSnapshotsFunction getLayerSnapshots;
@@ -7972,9 +7975,10 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args
    }

    RenderAreaFuture renderAreaFuture = ftl::defer([=] {
        return DisplayRenderArea::create(displayWeak, Rect(), size, args.dataspace,
        DisplayRenderAreaBuilder displayRenderArea(Rect(), size, args.dataspace,
                                                   args.hintForSeamlessTransition,
                                         false /* captureSecureLayers */);
                                                   false /* captureSecureLayers */, displayWeak);
        return displayRenderArea.build();
    });

    GetLayerSnapshotsFunction getLayerSnapshots;
@@ -8079,24 +8083,21 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
        return;
    }

    RenderAreaFuture renderAreaFuture = ftl::defer([=, this]() FTL_FAKE_GUARD(kMainThreadContext)
                                                           -> std::unique_ptr<RenderArea> {
        ui::Transform layerTransform;
        Rect layerBufferSize;
    RenderAreaFuture renderAreaFuture = ftl::defer(
            [=, this]() FTL_FAKE_GUARD(kMainThreadContext) -> std::unique_ptr<RenderArea> {
                LayerRenderAreaBuilder layerRenderArea(crop, reqSize, dataspace,
                                                       args.captureSecureLayers,
                                                       args.hintForSeamlessTransition, parent,
                                                       args.childrenOnly);

                frontend::LayerSnapshot* snapshot =
                        mLayerSnapshotBuilder.getSnapshot(parent->getSequence());
                if (!snapshot) {
                    ALOGW("Couldn't find layer snapshot for %d", parent->getSequence());
                } else {
            if (!args.childrenOnly) {
                layerTransform = snapshot->localTransform.inverse();
                    layerRenderArea.setLayerInfo(snapshot);
                }
            layerBufferSize = snapshot->bufferSize;
        }

        return std::make_unique<LayerRenderArea>(parent, crop, reqSize, dataspace,
                                                 args.captureSecureLayers, layerTransform,
                                                 layerBufferSize, args.hintForSeamlessTransition);
                return layerRenderArea.build();
            });
    GetLayerSnapshotsFunction getLayerSnapshots;
    if (mLayerLifecycleManagerEnabled) {