summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Melody Hsu <melodymhsu@google.com> 2024-05-03 01:25:50 +0000
committer Melody Hsu <melodymhsu@google.com> 2024-05-06 22:34:48 +0000
commit41ade202bb683797beaa64e3459a69952ce1f0bc (patch)
tree8b4cce20ab36dc777d850df0962911df8a827d31
parentd50d517fb36c05ee2a877a3684fb1d3ff6e273c2 (diff)
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
-rw-r--r--services/surfaceflinger/RegionSamplingThread.cpp8
-rw-r--r--services/surfaceflinger/RenderAreaBuilder.h114
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp47
3 files changed, 144 insertions, 25 deletions
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 77e045d6f9..2ec20ad5c2 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -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;
diff --git a/services/surfaceflinger/RenderAreaBuilder.h b/services/surfaceflinger/RenderAreaBuilder.h
new file mode 100644
index 0000000000..012acd2a67
--- /dev/null
+++ b/services/surfaceflinger/RenderAreaBuilder.h
@@ -0,0 +1,114 @@
+/*
+ * 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
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index df226c94ff..5263aa80b9 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -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,
- args.hintForSeamlessTransition,
- false /* captureSecureLayers */);
+ DisplayRenderAreaBuilder displayRenderArea(Rect(), size, args.dataspace,
+ args.hintForSeamlessTransition,
+ false /* captureSecureLayers */, displayWeak);
+ return displayRenderArea.build();
});
GetLayerSnapshotsFunction getLayerSnapshots;
@@ -8079,25 +8083,22 @@ 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;
- 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();
- }
- layerBufferSize = snapshot->bufferSize;
- }
+ 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);
- return std::make_unique<LayerRenderArea>(parent, crop, reqSize, dataspace,
- args.captureSecureLayers, layerTransform,
- layerBufferSize, args.hintForSeamlessTransition);
- });
+ frontend::LayerSnapshot* snapshot =
+ mLayerSnapshotBuilder.getSnapshot(parent->getSequence());
+ if (!snapshot) {
+ ALOGW("Couldn't find layer snapshot for %d", parent->getSequence());
+ } else {
+ layerRenderArea.setLayerInfo(snapshot);
+ }
+ return layerRenderArea.build();
+ });
GetLayerSnapshotsFunction getLayerSnapshots;
if (mLayerLifecycleManagerEnabled) {
std::optional<FloatRect> parentCrop = std::nullopt;