diff options
author | 2023-04-04 00:25:56 +0000 | |
---|---|---|
committer | 2023-04-04 00:25:56 +0000 | |
commit | 40a0171d4da8607b007f285c2fb5d9dcd3ea496e (patch) | |
tree | 86fec72f6ae78470696679608f29409041a03500 | |
parent | c9c2647423d67c21bc971748361218c9c88e4702 (diff) | |
parent | 0284463f01bad248b39fce18b44a62551c91a070 (diff) |
Merge "Move exclude layer to CaptureArgs." into udc-dev
-rw-r--r-- | libs/gui/LayerState.cpp | 27 | ||||
-rw-r--r-- | libs/gui/include/gui/DisplayCaptureArgs.h | 4 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerCaptureArgs.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/RegionSamplingThread.cpp | 3 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 70 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 7 | ||||
-rw-r--r-- | services/surfaceflinger/tests/ScreenCapture_test.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/CompositionTest.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h | 4 |
9 files changed, 104 insertions, 24 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 196949682d..fee91a40c2 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -897,6 +897,11 @@ status_t CaptureArgs::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(dataspace)); SAFE_PARCEL(output->writeBool, allowProtected); SAFE_PARCEL(output->writeBool, grayscale); + + SAFE_PARCEL(output->writeInt32, excludeHandles.size()); + for (auto& excludeHandle : excludeHandles) { + SAFE_PARCEL(output->writeStrongBinder, excludeHandle); + } return NO_ERROR; } @@ -913,6 +918,15 @@ status_t CaptureArgs::readFromParcel(const Parcel* input) { dataspace = static_cast<ui::Dataspace>(value); SAFE_PARCEL(input->readBool, &allowProtected); SAFE_PARCEL(input->readBool, &grayscale); + + int32_t numExcludeHandles = 0; + SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize()); + excludeHandles.reserve(numExcludeHandles); + for (int i = 0; i < numExcludeHandles; i++) { + sp<IBinder> binder; + SAFE_PARCEL(input->readStrongBinder, &binder); + excludeHandles.emplace(binder); + } return NO_ERROR; } @@ -940,10 +954,6 @@ status_t LayerCaptureArgs::writeToParcel(Parcel* output) const { SAFE_PARCEL(CaptureArgs::writeToParcel, output); SAFE_PARCEL(output->writeStrongBinder, layerHandle); - SAFE_PARCEL(output->writeInt32, excludeHandles.size()); - for (auto el : excludeHandles) { - SAFE_PARCEL(output->writeStrongBinder, el); - } SAFE_PARCEL(output->writeBool, childrenOnly); return NO_ERROR; } @@ -953,15 +963,6 @@ status_t LayerCaptureArgs::readFromParcel(const Parcel* input) { SAFE_PARCEL(input->readStrongBinder, &layerHandle); - int32_t numExcludeHandles = 0; - SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize()); - excludeHandles.reserve(numExcludeHandles); - for (int i = 0; i < numExcludeHandles; i++) { - sp<IBinder> binder; - SAFE_PARCEL(input->readStrongBinder, &binder); - excludeHandles.emplace(binder); - } - SAFE_PARCEL(input->readBool, &childrenOnly); return NO_ERROR; } diff --git a/libs/gui/include/gui/DisplayCaptureArgs.h b/libs/gui/include/gui/DisplayCaptureArgs.h index c826c17d2c..5c794aea37 100644 --- a/libs/gui/include/gui/DisplayCaptureArgs.h +++ b/libs/gui/include/gui/DisplayCaptureArgs.h @@ -22,9 +22,11 @@ #include <binder/IBinder.h> #include <binder/Parcel.h> #include <binder/Parcelable.h> +#include <gui/SpHash.h> #include <ui/GraphicTypes.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> +#include <unordered_set> namespace android::gui { @@ -55,6 +57,8 @@ struct CaptureArgs : public Parcelable { bool grayscale = false; + std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles; + virtual status_t writeToParcel(Parcel* output) const; virtual status_t readFromParcel(const Parcel* input); }; diff --git a/libs/gui/include/gui/LayerCaptureArgs.h b/libs/gui/include/gui/LayerCaptureArgs.h index 05ff9d5b7b..fae2bcc787 100644 --- a/libs/gui/include/gui/LayerCaptureArgs.h +++ b/libs/gui/include/gui/LayerCaptureArgs.h @@ -20,14 +20,11 @@ #include <sys/types.h> #include <gui/DisplayCaptureArgs.h> -#include <gui/SpHash.h> -#include <unordered_set> namespace android::gui { struct LayerCaptureArgs : CaptureArgs { sp<IBinder> layerHandle; - std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles; bool childrenOnly{false}; status_t writeToParcel(Parcel* output) const override; diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index 327ca3f0aa..531d277ffc 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -347,7 +347,8 @@ void RegionSamplingThread::captureSample() { } visitor(layer); }; - mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor); + mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, {}, + filterVisitor); }; getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 6e7f43a22e..145fd46187 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -6882,6 +6882,7 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, wp<const DisplayDevice> displayWeak; ui::LayerStack layerStack; ui::Size reqSize(args.width, args.height); + std::unordered_set<uint32_t> excludeLayerIds; ui::Dataspace dataspace; { Mutex::Autolock lock(mStateLock); @@ -6895,6 +6896,16 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, reqSize = display->getLayerStackSpaceRect().getSize(); } + for (const auto& handle : args.excludeHandles) { + uint32_t excludeLayer = LayerHandle::getLayerId(handle); + if (excludeLayer != UNASSIGNED_LAYER_ID) { + excludeLayerIds.emplace(excludeLayer); + } else { + ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay"); + return NAME_NOT_FOUND; + } + } + // Allow the caller to specify a dataspace regardless of the display's color mode, e.g. if // it wants sRGB regardless of the display's wide color mode. dataspace = args.dataspace == ui::Dataspace::UNKNOWN @@ -6910,10 +6921,11 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, GetLayerSnapshotsFunction getLayerSnapshots; if (mLayerLifecycleManagerEnabled) { getLayerSnapshots = - getLayerSnapshotsForScreenshots(layerStack, args.uid, /*snapshotFilterFn=*/nullptr); + getLayerSnapshotsForScreenshots(layerStack, args.uid, std::move(excludeLayerIds)); } else { - auto traverseLayers = [this, args, layerStack](const LayerVector::Visitor& visitor) { - traverseLayersInLayerStack(layerStack, args.uid, visitor); + auto traverseLayers = [this, args, excludeLayerIds, + layerStack](const LayerVector::Visitor& visitor) { + traverseLayersInLayerStack(layerStack, args.uid, std::move(excludeLayerIds), visitor); }; getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); } @@ -6956,7 +6968,7 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, /*snapshotFilterFn=*/nullptr); } else { auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) { - traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor); + traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, {}, visitor); }; getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); } @@ -7380,6 +7392,7 @@ void SurfaceFlinger::State::traverseInReverseZOrder(const LayerVector::Visitor& } void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const int32_t uid, + std::unordered_set<uint32_t> excludeLayerIds, const LayerVector::Visitor& visitor) { // We loop through the first level of layers without traversing, // as we need to determine which layers belong to the requested display. @@ -7398,6 +7411,17 @@ void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const if (uid != CaptureArgs::UNSET_UID && layer->getOwnerUid() != uid) { return; } + + if (!excludeLayerIds.empty()) { + auto p = sp<Layer>::fromExisting(layer); + while (p != nullptr) { + if (excludeLayerIds.count(p->sequence) != 0) { + return; + } + p = p->getParent(); + } + } + visitor(layer); }); } @@ -8060,6 +8084,44 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots( } std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> +SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack, + uint32_t uid, + std::unordered_set<uint32_t> excludeLayerIds) { + return [&, layerStack, uid, excludeLayerIds = std::move(excludeLayerIds)]() { + if (excludeLayerIds.empty()) { + auto getLayerSnapshotsFn = + getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr); + std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn(); + return layers; + } + + frontend::LayerSnapshotBuilder::Args + args{.root = mLayerHierarchyBuilder.getHierarchy(), + .layerLifecycleManager = mLayerLifecycleManager, + .forceUpdate = frontend::LayerSnapshotBuilder::ForceUpdateFlags::HIERARCHY, + .displays = mFrontEndDisplayInfos, + .displayChanges = true, + .globalShadowSettings = mDrawingState.globalShadowSettings, + .supportsBlur = mSupportsBlur, + .forceFullDamage = mForceFullDamage, + .excludeLayerIds = std::move(excludeLayerIds), + .supportedLayerGenericMetadata = + getHwComposer().getSupportedLayerGenericMetadata(), + .genericLayerMetadataKeyMap = getGenericLayerMetadataKeyMap()}; + mLayerSnapshotBuilder.update(args); + + auto getLayerSnapshotsFn = + getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr); + std::vector<std::pair<Layer*, sp<LayerFE>>> layers = getLayerSnapshotsFn(); + + args.excludeLayerIds.clear(); + mLayerSnapshotBuilder.update(args); + + return layers; + }; +} + +std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds, bool childrenOnly, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a8acfc8979..35707a2682 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -826,7 +826,9 @@ private: // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a // matching ownerUid - void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid, const LayerVector::Visitor&); + void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid, + std::unordered_set<uint32_t> excludeLayerIds, + const LayerVector::Visitor&); void readPersistentProperties(); @@ -1381,6 +1383,9 @@ private: std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)> snapshotFilterFn); std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> getLayerSnapshotsForScreenshots( + std::optional<ui::LayerStack> layerStack, uint32_t uid, + std::unordered_set<uint32_t> excludeLayerIds); + 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 std::optional<FloatRect>& optionalParentCrop); diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp index 976ee3519c..013694fd47 100644 --- a/services/surfaceflinger/tests/ScreenCapture_test.cpp +++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp @@ -222,6 +222,14 @@ TEST_F(ScreenCaptureTest, CaptureLayerExclude) { mCapture->checkPixel(0, 0, 200, 200, 200); } +TEST_F(ScreenCaptureTest, CaptureLayerExcludeThroughDisplayArgs) { + mCaptureArgs.excludeHandles = {mFGSurfaceControl->getHandle()}; + ScreenCapture::captureDisplay(&mCapture, mCaptureArgs); + mCapture->expectBGColor(0, 0); + // Doesn't capture FG layer which is at 64, 64 + mCapture->expectBGColor(64, 64); +} + // Like the last test but verifies that children are also exclude. TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) { auto fgHandle = mFGSurfaceControl->getHandle(); diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 19a93e1820..f5960614b0 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -204,7 +204,7 @@ void CompositionTest::captureScreenComposition() { auto traverseLayers = [this](const LayerVector::Visitor& visitor) { return mFlinger.traverseLayersInLayerStack(mDisplay->getLayerStack(), - CaptureArgs::UNSET_UID, visitor); + CaptureArgs::UNSET_UID, {}, visitor); }; auto getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index bbb355469c..6f48df8be2 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -442,8 +442,10 @@ public: } auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid, + std::unordered_set<uint32_t> excludeLayerIds, const LayerVector::Visitor& visitor) { - return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid, visitor); + return mFlinger->SurfaceFlinger::traverseLayersInLayerStack(layerStack, uid, + excludeLayerIds, visitor); } auto getDisplayNativePrimaries(const sp<IBinder>& displayToken, |