diff options
author | 2025-01-28 21:22:52 +0000 | |
---|---|---|
committer | 2025-02-04 23:13:41 +0000 | |
commit | 5b3d97658c251f80e7147fab23886fc6466d0d2b (patch) | |
tree | 900c10e2250e9a7bc3bc19a2baf47733368aea9d | |
parent | a234a4a6004464c2a9850c9fe511dc8bbc76db5f (diff) |
Extract RenderArea elements into screenshot args
Removes Renderarea and its child classes + builders and provides its
elements in a parameter struct. This is a step toward untangling
dependencies on legacy layer, SF state lock, and separating screenshot
logic into a separate class.
Bug: b/377758217
Test: atest SurfaceFlinger_test, atest CompositionTest
Test: presubmit, screenshots, screen lock/unlock
Flag: EXEMPT, refactor
Change-Id: Id92f2697101f07e1fac50a6f6a770ad6d762ad8b
-rw-r--r-- | services/surfaceflinger/Android.bp | 3 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayRenderArea.cpp | 62 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayRenderArea.h | 48 | ||||
-rw-r--r-- | services/surfaceflinger/LayerRenderArea.cpp | 60 | ||||
-rw-r--r-- | services/surfaceflinger/LayerRenderArea.h | 57 | ||||
-rw-r--r-- | services/surfaceflinger/RegionSamplingThread.cpp | 21 | ||||
-rw-r--r-- | services/surfaceflinger/RenderArea.cpp | 31 | ||||
-rw-r--r-- | services/surfaceflinger/RenderArea.h | 98 | ||||
-rw-r--r-- | services/surfaceflinger/RenderAreaBuilder.h | 102 | ||||
-rw-r--r-- | services/surfaceflinger/ScreenCaptureOutput.cpp | 42 | ||||
-rw-r--r-- | services/surfaceflinger/ScreenCaptureOutput.h | 18 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 201 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 62 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/CompositionTest.cpp | 17 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h | 18 |
15 files changed, 221 insertions, 619 deletions
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index ea7d6d7602..88ff370188 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -206,7 +206,6 @@ filegroup { "Display/DisplayModeController.cpp", "Display/DisplaySnapshot.cpp", "DisplayDevice.cpp", - "DisplayRenderArea.cpp", "Effects/Daltonizer.cpp", "FpsReporter.cpp", "FrameTracer/FrameTracer.cpp", @@ -225,12 +224,10 @@ filegroup { "Layer.cpp", "LayerFE.cpp", "LayerProtoHelper.cpp", - "LayerRenderArea.cpp", "LayerVector.cpp", "NativeWindowSurface.cpp", "RefreshRateOverlay.cpp", "RegionSamplingThread.cpp", - "RenderArea.cpp", "Scheduler/EventThread.cpp", "Scheduler/FrameRateOverrideMappings.cpp", "Scheduler/LayerHistory.cpp", diff --git a/services/surfaceflinger/DisplayRenderArea.cpp b/services/surfaceflinger/DisplayRenderArea.cpp deleted file mode 100644 index c63c738d34..0000000000 --- a/services/surfaceflinger/DisplayRenderArea.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2020 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. - */ - -#include "DisplayRenderArea.h" -#include "DisplayDevice.h" - -namespace android { - -std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak, - const Rect& sourceCrop, ui::Size reqSize, - ui::Dataspace reqDataSpace, - ftl::Flags<Options> options) { - if (auto display = displayWeak.promote()) { - // Using new to access a private constructor. - return std::unique_ptr<DisplayRenderArea>(new DisplayRenderArea(std::move(display), - sourceCrop, reqSize, - reqDataSpace, options)); - } - return nullptr; -} - -DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop, - ui::Size reqSize, ui::Dataspace reqDataSpace, - ftl::Flags<Options> options) - : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, options), - mDisplay(std::move(display)), - mSourceCrop(sourceCrop) {} - -const ui::Transform& DisplayRenderArea::getTransform() const { - return mTransform; -} - -bool DisplayRenderArea::isSecure() const { - return mOptions.test(Options::CAPTURE_SECURE_LAYERS) && mDisplay->isSecure(); -} - -sp<const DisplayDevice> DisplayRenderArea::getDisplayDevice() const { - return mDisplay; -} - -Rect DisplayRenderArea::getSourceCrop() const { - // use the projected display viewport by default. - if (mSourceCrop.isEmpty()) { - return mDisplay->getLayerStackSpaceRect(); - } - return mSourceCrop; -} - -} // namespace android diff --git a/services/surfaceflinger/DisplayRenderArea.h b/services/surfaceflinger/DisplayRenderArea.h deleted file mode 100644 index 677d01975a..0000000000 --- a/services/surfaceflinger/DisplayRenderArea.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2020 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 <ui/GraphicTypes.h> -#include <ui/Transform.h> - -#include "RenderArea.h" - -namespace android { - -class DisplayDevice; - -class DisplayRenderArea : public RenderArea { -public: - static std::unique_ptr<RenderArea> create(wp<const DisplayDevice>, const Rect& sourceCrop, - ui::Size reqSize, ui::Dataspace, - ftl::Flags<Options> options); - - const ui::Transform& getTransform() const override; - bool isSecure() const override; - sp<const DisplayDevice> getDisplayDevice() const override; - Rect getSourceCrop() const override; - -private: - DisplayRenderArea(sp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize, - ui::Dataspace, ftl::Flags<Options> options); - - const sp<const DisplayDevice> mDisplay; - const Rect mSourceCrop; - const ui::Transform mTransform; -}; - -} // namespace android diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp deleted file mode 100644 index bfe6d2a956..0000000000 --- a/services/surfaceflinger/LayerRenderArea.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2020 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. - */ - -#include <ui/GraphicTypes.h> -#include <ui/Transform.h> - -#include "DisplayDevice.h" -#include "FrontEnd/LayerCreationArgs.h" -#include "Layer.h" -#include "LayerRenderArea.h" -#include "SurfaceFlinger.h" - -namespace android { - -LayerRenderArea::LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot, - const Rect& crop, ui::Size reqSize, ui::Dataspace reqDataSpace, - const ui::Transform& layerTransform, const Rect& layerBufferSize, - ftl::Flags<RenderArea::Options> options) - : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, options), - mLayer(std::move(layer)), - mLayerSnapshot(std::move(layerSnapshot)), - mLayerBufferSize(layerBufferSize), - mCrop(crop), - mTransform(layerTransform) {} - -const ui::Transform& LayerRenderArea::getTransform() const { - return mTransform; -} - -bool LayerRenderArea::isSecure() const { - return mOptions.test(Options::CAPTURE_SECURE_LAYERS); -} - -sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const { - return nullptr; -} - -Rect LayerRenderArea::getSourceCrop() const { - if (mCrop.isEmpty()) { - // TODO this should probably be mBounds instead of just buffer bounds - return mLayerBufferSize; - } else { - return mCrop; - } -} - -} // namespace android diff --git a/services/surfaceflinger/LayerRenderArea.h b/services/surfaceflinger/LayerRenderArea.h deleted file mode 100644 index f72c7c7715..0000000000 --- a/services/surfaceflinger/LayerRenderArea.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020 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 <string> - -#include <ui/GraphicTypes.h> -#include <ui/Transform.h> -#include <utils/StrongPointer.h> - -#include "RenderArea.h" - -namespace android { - -class DisplayDevice; -class Layer; -class SurfaceFlinger; - -class LayerRenderArea : public RenderArea { -public: - LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot, const Rect& crop, - ui::Size reqSize, ui::Dataspace reqDataSpace, - const ui::Transform& layerTransform, const Rect& layerBufferSize, - ftl::Flags<RenderArea::Options> options); - - const ui::Transform& getTransform() const override; - bool isSecure() const override; - sp<const DisplayDevice> getDisplayDevice() const override; - Rect getSourceCrop() const override; - - sp<Layer> getParentLayer() const override { return mLayer; } - const frontend::LayerSnapshot* getLayerSnapshot() const override { return &mLayerSnapshot; } - -private: - const sp<Layer> mLayer; - const frontend::LayerSnapshot mLayerSnapshot; - const Rect mLayerBufferSize; - const Rect mCrop; - - ui::Transform mTransform; -}; - -} // namespace android diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index d3483b0cb0..1c4a11a9fa 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -39,11 +39,8 @@ #include <string> #include "DisplayDevice.h" -#include "DisplayRenderArea.h" #include "FrontEnd/LayerCreationArgs.h" #include "Layer.h" -#include "RenderAreaBuilder.h" -#include "Scheduler/VsyncController.h" #include "SurfaceFlinger.h" namespace android { @@ -259,6 +256,7 @@ void RegionSamplingThread::captureSample() { ui::LayerStack layerStack; ui::Transform::RotationFlags orientation; ui::Size displaySize; + Rect layerStackSpaceRect; { // TODO(b/159112860): Don't keep sp<DisplayDevice> outside of SF main thread @@ -267,6 +265,7 @@ void RegionSamplingThread::captureSample() { layerStack = display->getLayerStack(); orientation = ui::Transform::toRotationFlags(display->getOrientation()); displaySize = display->getSize(); + layerStackSpaceRect = display->getLayerStackSpaceRect(); } std::vector<RegionSamplingThread::Descriptor> descriptors; @@ -347,16 +346,20 @@ void RegionSamplingThread::captureSample() { constexpr bool kGrayscale = false; constexpr bool kIsProtected = false; - SurfaceFlinger::RenderAreaBuilderVariant - renderAreaBuilder(std::in_place_type<DisplayRenderAreaBuilder>, sampledBounds, - sampledBounds.getSize(), ui::Dataspace::V0_SRGB, displayWeak, - RenderArea::Options::CAPTURE_SECURE_LAYERS); + SurfaceFlinger::ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = displayWeak; + screenshotArgs.displayId = std::nullopt; + screenshotArgs.sourceCrop = sampledBounds.isEmpty() ? layerStackSpaceRect : sampledBounds; + screenshotArgs.reqSize = sampledBounds.getSize(); + screenshotArgs.dataspace = ui::Dataspace::V0_SRGB; + screenshotArgs.isSecure = true; + screenshotArgs.seamlessTransition = false; std::vector<std::pair<Layer*, sp<LayerFE>>> layers; auto displayState = - mFlinger.getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layers); + mFlinger.getSnapshotsFromMainThread(screenshotArgs, getLayerSnapshotsFn, layers); FenceResult fenceResult = - mFlinger.captureScreenshot(renderAreaBuilder, buffer, kRegionSampling, kGrayscale, + mFlinger.captureScreenshot(screenshotArgs, buffer, kRegionSampling, kGrayscale, kIsProtected, nullptr, displayState, layers) .get(); if (fenceResult.ok()) { diff --git a/services/surfaceflinger/RenderArea.cpp b/services/surfaceflinger/RenderArea.cpp deleted file mode 100644 index 5fea521f18..0000000000 --- a/services/surfaceflinger/RenderArea.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2017 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. - */ - -#include "RenderArea.h" - -namespace android { - -float RenderArea::getCaptureFillValue(CaptureFill captureFill) { - switch(captureFill) { - case CaptureFill::CLEAR: - return 0.0f; - case CaptureFill::OPAQUE: - default: - return 1.0f; - } -} - -} // namespace android diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h deleted file mode 100644 index aa66ccf172..0000000000 --- a/services/surfaceflinger/RenderArea.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once - -#include <ui/GraphicTypes.h> -#include <ui/Transform.h> - -#include <functional> - -#include "FrontEnd/LayerSnapshot.h" -#include "Layer.h" - -namespace android { - -class DisplayDevice; - -// RenderArea describes a rectangular area that layers can be rendered to. -// -// There is a logical render area and a physical render area. When a layer is -// rendered to the render area, it is first transformed and clipped to the logical -// render area. The transformed and clipped layer is then projected onto the -// physical render area. -class RenderArea { -public: - enum class CaptureFill {CLEAR, OPAQUE}; - enum class Options { - // If not set, the secure layer would be blacked out or skipped - // when rendered to an insecure render area - CAPTURE_SECURE_LAYERS = 1 << 0, - - // If set, the render result may be used for system animations - // that must preserve the exact colors of the display - HINT_FOR_SEAMLESS_TRANSITION = 1 << 1, - }; - static float getCaptureFillValue(CaptureFill captureFill); - - RenderArea(ui::Size reqSize, CaptureFill captureFill, ui::Dataspace reqDataSpace, - ftl::Flags<Options> options) - : mOptions(options), - mReqSize(reqSize), - mReqDataSpace(reqDataSpace), - mCaptureFill(captureFill) {} - - virtual ~RenderArea() = default; - - // Returns true if the render area is secure. A secure layer should be - // blacked out / skipped when rendered to an insecure render area. - virtual bool isSecure() const = 0; - - // Returns the transform to be applied on layers to transform them into - // the logical render area. - virtual const ui::Transform& getTransform() const = 0; - - // Returns the source crop of the render area. The source crop defines - // how layers are projected from the logical render area onto the physical - // render area. It can be larger than the logical render area. It can - // also be optionally rotated. - // - // The source crop is specified in layer space (when rendering a layer and - // its children), or in layer-stack space (when rendering all layers visible - // on the display). - virtual Rect getSourceCrop() const = 0; - - // Returns the size of the physical render area. - int getReqWidth() const { return mReqSize.width; } - int getReqHeight() const { return mReqSize.height; } - - // Returns the composition data space of the render area. - ui::Dataspace getReqDataSpace() const { return mReqDataSpace; } - - // Returns the fill color of the physical render area. Regions not - // covered by any rendered layer should be filled with this color. - CaptureFill getCaptureFill() const { return mCaptureFill; } - - virtual sp<const DisplayDevice> getDisplayDevice() const = 0; - - // If this is a LayerRenderArea, return the root layer of the - // capture operation. - virtual sp<Layer> getParentLayer() const { return nullptr; } - - // If this is a LayerRenderArea, return the layer snapshot - // of the root layer of the capture operation - virtual const frontend::LayerSnapshot* getLayerSnapshot() const { return nullptr; } - - // Returns whether the render result may be used for system animations that - // must preserve the exact colors of the display. - bool getHintForSeamlessTransition() const { - return mOptions.test(Options::HINT_FOR_SEAMLESS_TRANSITION); - } - -protected: - ftl::Flags<Options> mOptions; - -private: - const ui::Size mReqSize; - const ui::Dataspace mReqDataSpace; - const CaptureFill mCaptureFill; -}; - -} // namespace android diff --git a/services/surfaceflinger/RenderAreaBuilder.h b/services/surfaceflinger/RenderAreaBuilder.h deleted file mode 100644 index 599fa7e102..0000000000 --- a/services/surfaceflinger/RenderAreaBuilder.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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; - - ftl::Flags<RenderArea::Options> options; - virtual std::unique_ptr<RenderArea> build() const = 0; - - RenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, - ftl::Flags<RenderArea::Options> options) - : crop(crop), reqSize(reqSize), reqDataSpace(reqDataSpace), options(options) {} - - virtual ~RenderAreaBuilder() = default; -}; - -struct DisplayRenderAreaBuilder : RenderAreaBuilder { - DisplayRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, - wp<const DisplayDevice> displayWeak, - ftl::Flags<RenderArea::Options> options) - : RenderAreaBuilder(crop, reqSize, reqDataSpace, options), 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, options); - } -}; - -struct LayerRenderAreaBuilder : RenderAreaBuilder { - LayerRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, sp<Layer> layer, - bool childrenOnly, ftl::Flags<RenderArea::Options> options) - : RenderAreaBuilder(crop, reqSize, reqDataSpace, options), - layer(layer), - childrenOnly(childrenOnly) {} - - // Root layer of the render area - sp<Layer> layer; - - // Layer snapshot of the root layer - frontend::LayerSnapshot layerSnapshot; - - // 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 setLayerSnapshot(const frontend::LayerSnapshot& parentSnapshot) { - layerSnapshot = parentSnapshot; - if (!childrenOnly) { - layerTransform = parentSnapshot.localTransform.inverse(); - } - layerBufferSize = parentSnapshot.bufferSize; - } - - std::unique_ptr<RenderArea> build() const override { - return std::make_unique<LayerRenderArea>(layer, std::move(layerSnapshot), crop, reqSize, - reqDataSpace, layerTransform, layerBufferSize, - options); - } -}; - -} // namespace android
\ No newline at end of file diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp index 5f71b88d01..712390574f 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -29,11 +29,15 @@ namespace android { std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs args) { std::shared_ptr<ScreenCaptureOutput> output = compositionengine::impl::createOutputTemplated< - ScreenCaptureOutput, compositionengine::CompositionEngine, const RenderArea&, + ScreenCaptureOutput, compositionengine::CompositionEngine, + /* sourceCrop */ const Rect, std::optional<DisplayId>, const compositionengine::Output::ColorProfile&, - bool>(args.compositionEngine, args.renderArea, args.colorProfile, args.regionSampling, - args.dimInGammaSpaceForEnhancedScreenshots, args.enableLocalTonemapping); - output->editState().isSecure = args.renderArea.isSecure(); + /* layerAlpha */ float, + /* regionSampling */ bool>(args.compositionEngine, args.sourceCrop, args.displayId, + args.colorProfile, args.layerAlpha, args.regionSampling, + args.dimInGammaSpaceForEnhancedScreenshots, + args.enableLocalTonemapping); + output->editState().isSecure = args.isSecure; output->editState().isProtected = args.isProtected; output->setCompositionEnabled(true); output->setLayerFilter({args.layerStack}); @@ -47,16 +51,16 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp .setHasWideColorGamut(true) .Build())); - const Rect& sourceCrop = args.renderArea.getSourceCrop(); + const Rect& sourceCrop = args.sourceCrop; const ui::Rotation orientation = ui::ROTATION_0; output->setDisplaySize({sourceCrop.getWidth(), sourceCrop.getHeight()}); output->setProjection(orientation, sourceCrop, - {args.renderArea.getReqWidth(), args.renderArea.getReqHeight()}); + {args.reqBufferSize.width, args.reqBufferSize.height}); { std::string name = args.regionSampling ? "RegionSampling" : "ScreenCaptureOutput"; - if (auto displayDevice = args.renderArea.getDisplayDevice()) { - base::StringAppendF(&name, " for %" PRIu64, displayDevice->getId().value); + if (args.displayId) { + base::StringAppendF(&name, " for %" PRIu64, args.displayId.value().value); } output->setName(name); } @@ -64,11 +68,14 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp } ScreenCaptureOutput::ScreenCaptureOutput( - const RenderArea& renderArea, const compositionengine::Output::ColorProfile& colorProfile, + const Rect sourceCrop, std::optional<DisplayId> displayId, + const compositionengine::Output::ColorProfile& colorProfile, float layerAlpha, bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots, bool enableLocalTonemapping) - : mRenderArea(renderArea), + : mSourceCrop(sourceCrop), + mDisplayId(displayId), mColorProfile(colorProfile), + mLayerAlpha(layerAlpha), mRegionSampling(regionSampling), mDimInGammaSpaceForEnhancedScreenshots(dimInGammaSpaceForEnhancedScreenshots), mEnableLocalTonemapping(enableLocalTonemapping) {} @@ -83,7 +90,7 @@ renderengine::DisplaySettings ScreenCaptureOutput::generateClientCompositionDisp const std::shared_ptr<renderengine::ExternalTexture>& buffer) const { auto clientCompositionDisplay = compositionengine::impl::Output::generateClientCompositionDisplaySettings(buffer); - clientCompositionDisplay.clip = mRenderArea.getSourceCrop(); + clientCompositionDisplay.clip = mSourceCrop; auto renderIntent = static_cast<ui::RenderIntent>(clientCompositionDisplay.renderIntent); if (mDimInGammaSpaceForEnhancedScreenshots && renderIntent != ui::RenderIntent::COLORIMETRIC && @@ -130,8 +137,8 @@ ScreenCaptureOutput::generateLuts() { } std::vector<aidl::android::hardware::graphics::composer3::Luts> luts; - if (auto displayDevice = mRenderArea.getDisplayDevice()) { - const auto id = PhysicalDisplayId::tryCast(displayDevice->getId()); + if (mDisplayId) { + const auto id = PhysicalDisplayId::tryCast(mDisplayId.value()); if (id) { auto& hwc = getCompositionEngine().getHwComposer(); hwc.getLuts(*id, buffers, &luts); @@ -201,14 +208,15 @@ ScreenCaptureOutput::generateClientCompositionRequests( } } - Rect sourceCrop = mRenderArea.getSourceCrop(); compositionengine::LayerFE::LayerSettings fillLayer; fillLayer.source.buffer.buffer = nullptr; fillLayer.source.solidColor = half3(0.0f, 0.0f, 0.0f); fillLayer.geometry.boundaries = - FloatRect(static_cast<float>(sourceCrop.left), static_cast<float>(sourceCrop.top), - static_cast<float>(sourceCrop.right), static_cast<float>(sourceCrop.bottom)); - fillLayer.alpha = half(RenderArea::getCaptureFillValue(mRenderArea.getCaptureFill())); + FloatRect(static_cast<float>(mSourceCrop.left), static_cast<float>(mSourceCrop.top), + static_cast<float>(mSourceCrop.right), + static_cast<float>(mSourceCrop.bottom)); + + fillLayer.alpha = half(mLayerAlpha); clientCompositionLayers.insert(clientCompositionLayers.begin(), fillLayer); return clientCompositionLayers; diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h index 444a28fbf0..b3e98b1a32 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.h +++ b/services/surfaceflinger/ScreenCaptureOutput.h @@ -22,23 +22,25 @@ #include <ui/Rect.h> #include <unordered_map> -#include "RenderArea.h" - namespace android { struct ScreenCaptureOutputArgs { const compositionengine::CompositionEngine& compositionEngine; const compositionengine::Output::ColorProfile& colorProfile; - const RenderArea& renderArea; ui::LayerStack layerStack; + Rect sourceCrop; std::shared_ptr<renderengine::ExternalTexture> buffer; + std::optional<DisplayId> displayId; + ui::Size reqBufferSize; float sdrWhitePointNits; float displayBrightnessNits; // Counterintuitively, when targetBrightness > 1.0 then dim the scene. float targetBrightness; + float layerAlpha; bool regionSampling; bool treat170mAsSrgb; bool dimInGammaSpaceForEnhancedScreenshots; + bool isSecure = false; bool isProtected = false; bool enableLocalTonemapping = false; }; @@ -49,10 +51,10 @@ struct ScreenCaptureOutputArgs { // SurfaceFlinger::captureLayers and SurfaceFlinger::captureDisplay. class ScreenCaptureOutput : public compositionengine::impl::Output { public: - ScreenCaptureOutput(const RenderArea& renderArea, + ScreenCaptureOutput(const Rect sourceCrop, std::optional<DisplayId> displayId, const compositionengine::Output::ColorProfile& colorProfile, - bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots, - bool enableLocalTonemapping); + float layerAlpha, bool regionSampling, + bool dimInGammaSpaceForEnhancedScreenshots, bool enableLocalTonemapping); void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override; @@ -67,8 +69,10 @@ protected: private: std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> generateLuts(); - const RenderArea& mRenderArea; + const Rect mSourceCrop; + const std::optional<DisplayId> mDisplayId; const compositionengine::Output::ColorProfile& mColorProfile; + const float mLayerAlpha; const bool mRegionSampling; const bool mDimInGammaSpaceForEnhancedScreenshots; const bool mEnableLocalTonemapping; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d117753b4b..7e3d1091dc 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -137,7 +137,6 @@ #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/VirtualDisplaySurface.h" -#include "DisplayRenderArea.h" #include "Effects/Daltonizer.h" #include "FpsReporter.h" #include "FrameTimeline/FrameTimeline.h" @@ -151,14 +150,12 @@ #include "Jank/JankTracker.h" #include "Layer.h" #include "LayerProtoHelper.h" -#include "LayerRenderArea.h" #include "LayerVector.h" #include "MutexUtils.h" #include "NativeWindowSurface.h" #include "PowerAdvisor/PowerAdvisor.h" #include "PowerAdvisor/Workload.h" #include "RegionSamplingThread.h" -#include "RenderAreaBuilder.h" #include "Scheduler/EventThread.h" #include "Scheduler/LayerHistory.h" #include "Scheduler/Scheduler.h" @@ -7209,9 +7206,13 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, } wp<const DisplayDevice> displayWeak; + DisplayId displayId; ui::LayerStack layerStack; ui::Size reqSize(args.width, args.height); std::unordered_set<uint32_t> excludeLayerIds; + Rect layerStackSpaceRect; + bool displayIsSecure; + { Mutex::Autolock lock(mStateLock); sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); @@ -7221,11 +7222,14 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, return; } displayWeak = display; + displayId = display->getId(); layerStack = display->getLayerStack(); + displayIsSecure = display->isSecure(); + layerStackSpaceRect = display->getLayerStackSpaceRect(); // set the requested width/height to the logical display layer stack rect size by default if (args.width == 0 || args.height == 0) { - reqSize = display->getLayerStackSpaceRect().getSize(); + reqSize = layerStackSpaceRect.getSize(); } for (const auto& handle : captureArgs.excludeHandles) { @@ -7244,16 +7248,19 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, getLayerSnapshotsForScreenshots(layerStack, captureArgs.uid, std::move(excludeLayerIds)); - ftl::Flags<RenderArea::Options> options; - if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; - if (captureArgs.hintForSeamlessTransition) - options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; - captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>, - gui::aidl_utils::fromARect(captureArgs.sourceCrop), - reqSize, - static_cast<ui::Dataspace>(captureArgs.dataspace), - displayWeak, options), - getLayerSnapshotsFn, reqSize, + ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = displayWeak; + screenshotArgs.displayId = displayId; + screenshotArgs.sourceCrop = gui::aidl_utils::fromARect(captureArgs.sourceCrop); + if (screenshotArgs.sourceCrop.isEmpty()) { + screenshotArgs.sourceCrop = layerStackSpaceRect; + } + screenshotArgs.reqSize = reqSize; + screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace); + screenshotArgs.isSecure = captureArgs.captureSecureLayers && displayIsSecure; + screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition; + + captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize, static_cast<ui::PixelFormat>(captureArgs.pixelFormat), captureArgs.allowProtected, captureArgs.grayscale, captureListener); } @@ -7263,6 +7270,9 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args ui::LayerStack layerStack; wp<const DisplayDevice> displayWeak; ui::Size size; + Rect layerStackSpaceRect; + bool displayIsSecure; + { Mutex::Autolock lock(mStateLock); @@ -7275,7 +7285,9 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args displayWeak = display; layerStack = display->getLayerStack(); + layerStackSpaceRect = display->getLayerStackSpaceRect(); size = display->getLayerStackSpaceRect().getSize(); + displayIsSecure = display->isSecure(); } size.width *= args.frameScaleX; @@ -7304,15 +7316,18 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args constexpr bool kAllowProtected = false; constexpr bool kGrayscale = false; - ftl::Flags<RenderArea::Options> options; - if (args.hintForSeamlessTransition) - options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; - captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>, - Rect(), size, - static_cast<ui::Dataspace>(args.dataspace), - displayWeak, options), - getLayerSnapshotsFn, size, static_cast<ui::PixelFormat>(args.pixelFormat), - kAllowProtected, kGrayscale, captureListener); + ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = displayWeak; + screenshotArgs.displayId = displayId; + screenshotArgs.sourceCrop = layerStackSpaceRect; + screenshotArgs.reqSize = size; + screenshotArgs.dataspace = static_cast<ui::Dataspace>(args.dataspace); + screenshotArgs.isSecure = args.captureSecureLayers && displayIsSecure; + screenshotArgs.seamlessTransition = args.hintForSeamlessTransition; + + captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, size, + static_cast<ui::PixelFormat>(args.pixelFormat), kAllowProtected, kGrayscale, + captureListener); } ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) { @@ -7414,14 +7429,16 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, return; } - ftl::Flags<RenderArea::Options> options; - if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS; - if (captureArgs.hintForSeamlessTransition) - options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION; - captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<LayerRenderAreaBuilder>, crop, - reqSize, dataspace, parent, args.childrenOnly, - options), - getLayerSnapshotsFn, reqSize, + ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = parent->getSequence(); + screenshotArgs.childrenOnly = args.childrenOnly; + screenshotArgs.sourceCrop = crop; + screenshotArgs.reqSize = reqSize; + screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace); + screenshotArgs.isSecure = captureArgs.captureSecureLayers; + screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition; + + captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize, static_cast<ui::PixelFormat>(captureArgs.pixelFormat), captureArgs.allowProtected, captureArgs.grayscale, captureListener); } @@ -7457,10 +7474,10 @@ bool SurfaceFlinger::layersHasProtectedLayer( // is reduced when grabbed from the main thread, thus also reducing // risk of deadlocks. std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapshotsFromMainThread( - RenderAreaBuilderVariant& renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, + ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn, std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) { return mScheduler - ->schedule([=, this, &renderAreaBuilder, &layers]() REQUIRES(kMainThreadContext) { + ->schedule([=, this, &args, &layers]() REQUIRES(kMainThreadContext) { SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Screenshot"); mPowerAdvisor->setScreenshotWorkload(); SFTRACE_NAME("getSnapshotsFromMainThread"); @@ -7475,12 +7492,12 @@ std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapsho ui::INVALID_LAYER_STACK); } } - return getDisplayStateFromRenderAreaBuilder(renderAreaBuilder); + return getDisplayStateOnMainThread(args); }) .get(); } -void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuilder, +void SurfaceFlinger::captureScreenCommon(ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, @@ -7496,7 +7513,11 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil } std::vector<std::pair<Layer*, sp<LayerFE>>> layers; - auto displayState = getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layers); + auto displayState = getSnapshotsFromMainThread(args, getLayerSnapshotsFn, layers); + if (!displayState) { + ALOGD("Display state not found"); + invokeScreenCaptureError(NO_MEMORY, captureListener); + } const bool hasHdrLayer = std::any_of(layers.cbegin(), layers.cend(), [this](const auto& layer) { return isHdrLayer(*(layer.second->mSnapshot.get())); @@ -7534,12 +7555,8 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil std::shared_ptr<renderengine::impl::ExternalTexture> hdrTexture; std::shared_ptr<renderengine::impl::ExternalTexture> gainmapTexture; - bool hintForSeamless = std::visit( - [](auto&& arg) { - return arg.options.test(RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION); - }, - renderAreaBuilder); - if (hasHdrLayer && !hintForSeamless && FlagManager::getInstance().true_hdr_screenshots()) { + if (hasHdrLayer && !args.seamlessTransition && + FlagManager::getInstance().true_hdr_screenshots()) { const auto hdrBuffer = getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */, @@ -7572,35 +7589,41 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil } } - auto futureFence = captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, - grayscale, isProtected, captureListener, displayState, - layers, hdrTexture, gainmapTexture); + auto futureFence = + captureScreenshot(args, texture, false /* regionSampling */, grayscale, isProtected, + captureListener, displayState, layers, hdrTexture, gainmapTexture); futureFence.get(); } -std::optional<SurfaceFlinger::OutputCompositionState> -SurfaceFlinger::getDisplayStateFromRenderAreaBuilder(RenderAreaBuilderVariant& renderAreaBuilder) { +std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getDisplayStateOnMainThread( + ScreenshotArgs& args) { sp<const DisplayDevice> display = nullptr; { Mutex::Autolock lock(mStateLock); - if (auto* layerRenderAreaBuilder = - std::get_if<LayerRenderAreaBuilder>(&renderAreaBuilder)) { + // Screenshot initiated through captureLayers + if (auto* layerSequence = std::get_if<int32_t>(&args.captureTypeVariant)) { // LayerSnapshotBuilder should only be accessed from the main thread. const frontend::LayerSnapshot* snapshot = - mLayerSnapshotBuilder.getSnapshot(layerRenderAreaBuilder->layer->getSequence()); + mLayerSnapshotBuilder.getSnapshot(*layerSequence); if (!snapshot) { - ALOGW("Couldn't find layer snapshot for %d", - layerRenderAreaBuilder->layer->getSequence()); + ALOGW("Couldn't find layer snapshot for %d", *layerSequence); } else { - layerRenderAreaBuilder->setLayerSnapshot(*snapshot); + if (!args.childrenOnly) { + args.transform = snapshot->localTransform.inverse(); + } + if (args.sourceCrop.isEmpty()) { + args.sourceCrop = snapshot->bufferSize; + } display = findDisplay( [layerStack = snapshot->outputFilter.layerStack](const auto& display) { return display.getLayerStack() == layerStack; }); } - } else if (auto* displayRenderAreaBuilder = - std::get_if<DisplayRenderAreaBuilder>(&renderAreaBuilder)) { - display = displayRenderAreaBuilder->displayWeak.promote(); + + // Screenshot initiated through captureDisplay + } else if (auto* displayWeak = + std::get_if<wp<const DisplayDevice>>(&args.captureTypeVariant)) { + display = displayWeak->promote(); } if (display == nullptr) { @@ -7615,9 +7638,9 @@ SurfaceFlinger::getDisplayStateFromRenderAreaBuilder(RenderAreaBuilderVariant& r } ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( - const RenderAreaBuilderVariant& renderAreaBuilder, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, + const ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + bool regionSampling, bool grayscale, bool isProtected, + const sp<IScreenCaptureListener>& captureListener, const std::optional<OutputCompositionState>& displayState, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers, const std::shared_ptr<renderengine::ExternalTexture>& hdrBuffer, @@ -7625,18 +7648,6 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( SFTRACE_CALL(); ScreenCaptureResults captureResults; - std::unique_ptr<const RenderArea> renderArea = - std::visit([](auto&& arg) -> std::unique_ptr<RenderArea> { return arg.build(); }, - renderAreaBuilder); - - 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<FenceResult>(base::unexpected(NO_ERROR)).share(); - } float displayBrightnessNits = displayState.value().displayBrightnessNits; float sdrWhitePointNits = displayState.value().sdrWhitePointNits; @@ -7645,8 +7656,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( if (hdrBuffer && gainmapBuffer) { ftl::SharedFuture<FenceResult> hdrRenderFuture = - renderScreenImpl(std::move(renderArea), hdrBuffer, regionSampling, grayscale, - isProtected, captureResults, displayState, layers); + renderScreenImpl(args, hdrBuffer, regionSampling, grayscale, isProtected, + captureResults, displayState, layers); captureResults.buffer = buffer->getBuffer(); captureResults.optionalGainMap = gainmapBuffer->getBuffer(); @@ -7669,8 +7680,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( }) .share(); } else { - renderFuture = renderScreenImpl(std::move(renderArea), buffer, regionSampling, grayscale, - isProtected, captureResults, displayState, layers); + renderFuture = renderScreenImpl(args, buffer, regionSampling, grayscale, isProtected, + captureResults, displayState, layers); } if (captureListener) { @@ -7690,8 +7701,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( } ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( - std::unique_ptr<const RenderArea> renderArea, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, + const ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults& captureResults, const std::optional<OutputCompositionState>& displayState, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) { @@ -7702,29 +7712,27 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure); captureResults.capturedHdrLayers |= isHdrLayer(*snapshot); layerFE->mSnapshot->geomLayerTransform = - renderArea->getTransform() * layerFE->mSnapshot->geomLayerTransform; + args.transform * layerFE->mSnapshot->geomLayerTransform; layerFE->mSnapshot->geomInverseLayerTransform = layerFE->mSnapshot->geomLayerTransform.inverse(); } auto capturedBuffer = buffer; - auto requestedDataspace = renderArea->getReqDataSpace(); - auto parent = renderArea->getParentLayer(); auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC; auto sdrWhitePointNits = DisplayDevice::sDefaultMaxLumiance; auto displayBrightnessNits = DisplayDevice::sDefaultMaxLumiance; - captureResults.capturedDataspace = requestedDataspace; + captureResults.capturedDataspace = args.dataspace; - const bool enableLocalTonemapping = FlagManager::getInstance().local_tonemap_screenshots() && - !renderArea->getHintForSeamlessTransition(); + const bool enableLocalTonemapping = + FlagManager::getInstance().local_tonemap_screenshots() && !args.seamlessTransition; if (displayState) { const auto& state = displayState.value(); captureResults.capturedDataspace = - pickBestDataspace(requestedDataspace, state, captureResults.capturedHdrLayers, - renderArea->getHintForSeamlessTransition()); + pickBestDataspace(args.dataspace, state, captureResults.capturedHdrLayers, + args.seamlessTransition); sdrWhitePointNits = state.sdrWhitePointNits; if (!captureResults.capturedHdrLayers) { @@ -7736,7 +7744,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( // Otherwise for seamless transitions it's important to match the current // display state as the buffer will be shown under these same conditions, and we // want to avoid any flickers - if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) { + if (sdrWhitePointNits > 1.0f && !args.seamlessTransition) { // Restrict the amount of HDR "headroom" in the screenshot to avoid // over-dimming the SDR portion. 2.0 chosen by experimentation constexpr float kMaxScreenshotHeadroom = 2.0f; @@ -7747,8 +7755,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( } // Screenshots leaving the device should be colorimetric - if (requestedDataspace == ui::Dataspace::UNKNOWN && - renderArea->getHintForSeamlessTransition()) { + if (args.dataspace == ui::Dataspace::UNKNOWN && args.seamlessTransition) { renderIntent = state.renderIntent; } } @@ -7763,7 +7770,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace, sdrWhitePointNits, displayBrightnessNits, grayscale, isProtected, layers, - layerStack, regionSampling, renderArea = std::move(renderArea), renderIntent, + layerStack, regionSampling, args, renderIntent, enableLocalTonemapping]() -> FenceResult { std::unique_ptr<compositionengine::CompositionEngine> compositionEngine = mFactory.createCompositionEngine(); @@ -7799,23 +7806,33 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( } } + // Capturing screenshots using layers have a clear capture fill (0 alpha). + // Capturing via display or displayId, which do not use args.layerSequence, + // has an opaque capture fill (1 alpha). + const float layerAlpha = + std::holds_alternative<int32_t>(args.captureTypeVariant) ? 0.0f : 1.0f; + // Screenshots leaving the device must not dim in gamma space. - const bool dimInGammaSpaceForEnhancedScreenshots = mDimInGammaSpaceForEnhancedScreenshots && - renderArea->getHintForSeamlessTransition(); + const bool dimInGammaSpaceForEnhancedScreenshots = + mDimInGammaSpaceForEnhancedScreenshots && args.seamlessTransition; std::shared_ptr<ScreenCaptureOutput> output = createScreenCaptureOutput( ScreenCaptureOutputArgs{.compositionEngine = *compositionEngine, .colorProfile = colorProfile, - .renderArea = *renderArea, .layerStack = layerStack, + .sourceCrop = args.sourceCrop, .buffer = std::move(buffer), + .displayId = args.displayId, + .reqBufferSize = args.reqSize, .sdrWhitePointNits = sdrWhitePointNits, .displayBrightnessNits = displayBrightnessNits, .targetBrightness = targetBrightness, + .layerAlpha = layerAlpha, .regionSampling = regionSampling, .treat170mAsSrgb = mTreat170mAsSrgb, .dimInGammaSpaceForEnhancedScreenshots = dimInGammaSpaceForEnhancedScreenshots, + .isSecure = args.isSecure, .isProtected = isProtected, .enableLocalTonemapping = enableLocalTonemapping}); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a99b39a953..fa255ea834 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -132,7 +132,6 @@ class Layer; class MessageBase; class RefreshRateOverlay; class RegionSamplingThread; -class RenderArea; class TimeStats; class FrameTracer; class ScreenCapturer; @@ -197,9 +196,6 @@ enum class LatchUnsignaledConfig { Always, }; -struct DisplayRenderAreaBuilder; -struct LayerRenderAreaBuilder; - using DisplayColorSetting = compositionengine::OutputColorSetting; class SurfaceFlinger : public BnSurfaceComposer, @@ -371,9 +367,7 @@ private: friend class Layer; friend class RefreshRateOverlay; friend class RegionSamplingThread; - friend class LayerRenderArea; friend class SurfaceComposerAIDL; - friend class DisplayRenderArea; // For unit tests friend class TestableSurfaceFlinger; @@ -382,7 +376,6 @@ private: using TransactionSchedule = scheduler::TransactionSchedule; using GetLayerSnapshotsFunction = std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>; - using RenderAreaBuilderVariant = std::variant<DisplayRenderAreaBuilder, LayerRenderAreaBuilder>; using DumpArgs = Vector<String16>; using Dumper = std::function<void(const DumpArgs&, bool asProto, std::string&)>; @@ -865,20 +858,56 @@ private: using OutputCompositionState = compositionengine::impl::OutputCompositionState; + /* + * Parameters used across screenshot methods. + */ + struct ScreenshotArgs { + // Contains the sequence ID of the parent layer if the screenshot is + // initiated though captureLayers(), or the display that the render + // result will be on if initiated through captureDisplay() + std::variant<int32_t, wp<const DisplayDevice>> captureTypeVariant; + + // Display ID of the display the result will be on + std::optional<DisplayId> displayId{std::nullopt}; + + // If true, transform is inverted from the parent layer snapshot + bool childrenOnly{false}; + + // Source crop of the render area + Rect sourceCrop; + + // Transform to be applied on the layers to transform them + // into the logical render area + ui::Transform transform; + + // Size of the physical render area + ui::Size reqSize; + + // Composition dataspace of the render area + ui::Dataspace dataspace; + + // If false, the secure layer is blacked out or skipped + // when rendered to an insecure render area + bool isSecure{false}; + + // If true, the render result may be used for system animations + // that must preserve the exact colors of the display + bool seamlessTransition{false}; + }; + std::optional<OutputCompositionState> getSnapshotsFromMainThread( - RenderAreaBuilderVariant& renderAreaBuilder, - GetLayerSnapshotsFunction getLayerSnapshotsFn, + ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn, std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); - void captureScreenCommon(RenderAreaBuilderVariant, GetLayerSnapshotsFunction, - ui::Size bufferSize, ui::PixelFormat, bool allowProtected, - bool grayscale, const sp<IScreenCaptureListener>&); + void captureScreenCommon(ScreenshotArgs& args, GetLayerSnapshotsFunction, ui::Size bufferSize, + ui::PixelFormat, bool allowProtected, bool grayscale, + const sp<IScreenCaptureListener>&); - std::optional<OutputCompositionState> getDisplayStateFromRenderAreaBuilder( - RenderAreaBuilderVariant& renderAreaBuilder) REQUIRES(kMainThreadContext); + std::optional<OutputCompositionState> getDisplayStateOnMainThread(ScreenshotArgs& args) + REQUIRES(kMainThreadContext); ftl::SharedFuture<FenceResult> captureScreenshot( - const RenderAreaBuilderVariant& renderAreaBuilder, + const ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, const std::optional<OutputCompositionState>& displayState, @@ -887,8 +916,7 @@ private: const std::shared_ptr<renderengine::ExternalTexture>& gainmapBuffer = nullptr); ftl::SharedFuture<FenceResult> renderScreenImpl( - std::unique_ptr<const RenderArea> renderArea, - const std::shared_ptr<renderengine::ExternalTexture>&, + const ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults&, const std::optional<OutputCompositionState>& displayState, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers); diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 71cafbfd64..9ece312850 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -36,7 +36,6 @@ #include <system/window.h> #include <utils/String8.h> -#include "DisplayRenderArea.h" #include "Layer.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" @@ -199,25 +198,21 @@ void CompositionTest::captureScreenComposition() { const Rect sourceCrop(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); constexpr bool regionSampling = false; - auto renderArea = - DisplayRenderArea::create(mDisplay, sourceCrop, sourceCrop.getSize(), - ui::Dataspace::V0_SRGB, - RenderArea::Options::CAPTURE_SECURE_LAYERS | - RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION); - auto getLayerSnapshotsFn = mFlinger.getLayerSnapshotsForScreenshotsFn(mDisplay->getLayerStack(), CaptureArgs::UNSET_UID); const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; mCaptureScreenBuffer = - std::make_shared<renderengine::mock::FakeExternalTexture>(renderArea->getReqWidth(), - renderArea->getReqHeight(), + std::make_shared<renderengine::mock::FakeExternalTexture>(sourceCrop.getSize().width, + sourceCrop.getSize().height, HAL_PIXEL_FORMAT_RGBA_8888, 1, usage); - auto future = mFlinger.renderScreenImpl(mDisplay, std::move(renderArea), getLayerSnapshotsFn, - mCaptureScreenBuffer, regionSampling); + auto future = mFlinger.renderScreenImpl(mDisplay, sourceCrop, ui::Dataspace::V0_SRGB, + getLayerSnapshotsFn, mCaptureScreenBuffer, + regionSampling, mDisplay->isSecure(), + /* seamlessTransition */ true); ASSERT_TRUE(future.valid()); const auto fenceResult = future.get(); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 2353ef8db6..9a2e254ad9 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -42,7 +42,6 @@ #include "FrontEnd/RequestedLayerState.h" #include "Layer.h" #include "NativeWindowSurface.h" -#include "RenderArea.h" #include "Scheduler/RefreshRateSelector.h" #include "Scheduler/VSyncTracker.h" #include "Scheduler/VsyncController.h" @@ -461,11 +460,11 @@ public: return mFlinger->setPowerModeInternal(display, mode); } - auto renderScreenImpl(const sp<DisplayDevice> display, - std::unique_ptr<const RenderArea> renderArea, + auto renderScreenImpl(const sp<DisplayDevice> display, const Rect sourceCrop, + ui::Dataspace dataspace, SurfaceFlinger::GetLayerSnapshotsFunction getLayerSnapshotsFn, const std::shared_ptr<renderengine::ExternalTexture>& buffer, - bool regionSampling) { + bool regionSampling, bool isSecure, bool seamlessTransition) { Mutex::Autolock lock(mFlinger->mStateLock); ftl::FakeGuard guard(kMainThreadContext); @@ -473,7 +472,16 @@ public: auto displayState = std::optional{display->getCompositionDisplay()->getState()}; auto layers = getLayerSnapshotsFn(); - return mFlinger->renderScreenImpl(std::move(renderArea), buffer, regionSampling, + SurfaceFlinger::ScreenshotArgs screenshotArgs; + screenshotArgs.captureTypeVariant = display; + screenshotArgs.displayId = std::nullopt; + screenshotArgs.sourceCrop = sourceCrop; + screenshotArgs.reqSize = sourceCrop.getSize(); + screenshotArgs.dataspace = dataspace; + screenshotArgs.isSecure = isSecure; + screenshotArgs.seamlessTransition = seamlessTransition; + + return mFlinger->renderScreenImpl(screenshotArgs, buffer, regionSampling, false /* grayscale */, false /* isProtected */, captureResults, displayState, layers); } |