diff options
| author | 2023-08-04 20:10:58 +0000 | |
|---|---|---|
| committer | 2023-08-04 20:10:58 +0000 | |
| commit | 10d3ca60da03d21dd52d0635319147f334ab2b37 (patch) | |
| tree | d96bf01da32f0fb0d9cb306d61aa9e42245236da | |
| parent | e6c479a9f7ed8900bb99cfdff824ef4544c689f9 (diff) | |
| parent | 9be7d0c3ce3c17cfaab528db7203905eb40c6bf3 (diff) | |
Merge "Make screenCapture calls to SF async" into main
| -rw-r--r-- | libs/gui/aidl/android/gui/ISurfaceComposer.aidl | 6 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 116 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 13 |
3 files changed, 78 insertions, 57 deletions
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index 539a1c140e..5e8e9043c1 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -230,20 +230,20 @@ interface ISurfaceComposer { * The subregion can be optionally rotated. It will also be scaled to * match the size of the output buffer. */ - void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener); + oneway void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener); /** * Capture the specified screen. This requires the READ_FRAME_BUFFER * permission. */ - void captureDisplayById(long displayId, IScreenCaptureListener listener); + oneway void captureDisplayById(long displayId, IScreenCaptureListener listener); /** * Capture a subtree of the layer hierarchy, potentially ignoring the root node. * This requires READ_FRAME_BUFFER permission. This function will fail if there * is a secure window on screen */ - void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener); + oneway void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener); /** * Clears the frame statistics for animations. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ef483f673d..f114b28506 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -7332,16 +7332,27 @@ ui::Dataspace pickBestDataspace(ui::Dataspace requestedDataspace, const DisplayD } // namespace -status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, - const sp<IScreenCaptureListener>& captureListener) { +static void invokeScreenCaptureError(const status_t status, + const sp<IScreenCaptureListener>& captureListener) { + ScreenCaptureResults captureResults; + captureResults.fenceResult = base::unexpected(status); + captureListener->onScreenCaptureCompleted(captureResults); +} + +void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, + const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); status_t validate = validateScreenshotPermissions(args); if (validate != OK) { - return validate; + invokeScreenCaptureError(validate, captureListener); + return; } - if (!args.displayToken) return BAD_VALUE; + if (!args.displayToken) { + invokeScreenCaptureError(BAD_VALUE, captureListener); + return; + } wp<const DisplayDevice> displayWeak; ui::LayerStack layerStack; @@ -7350,7 +7361,10 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, { Mutex::Autolock lock(mStateLock); sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken); - if (!display) return NAME_NOT_FOUND; + if (!display) { + invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); + return; + } displayWeak = display; layerStack = display->getLayerStack(); @@ -7365,7 +7379,8 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, excludeLayerIds.emplace(excludeLayer); } else { ALOGW("Invalid layer handle passed as excludeLayer to captureDisplay"); - return NAME_NOT_FOUND; + invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); + return; } } } @@ -7388,14 +7403,12 @@ status_t SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, getLayerSnapshots = RenderArea::fromTraverseLayersLambda(traverseLayers); } - auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, - args.pixelFormat, args.allowProtected, args.grayscale, - captureListener); - return fenceStatus(future.get()); + captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, args.pixelFormat, + args.allowProtected, args.grayscale, captureListener); } -status_t SurfaceFlinger::captureDisplay(DisplayId displayId, - const sp<IScreenCaptureListener>& captureListener) { +void SurfaceFlinger::captureDisplay(DisplayId displayId, + const sp<IScreenCaptureListener>& captureListener) { ui::LayerStack layerStack; wp<const DisplayDevice> displayWeak; ui::Size size; @@ -7404,7 +7417,8 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, const auto display = getDisplayDeviceLocked(displayId); if (!display) { - return NAME_NOT_FOUND; + invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); + return; } displayWeak = display; @@ -7432,25 +7446,25 @@ status_t SurfaceFlinger::captureDisplay(DisplayId displayId, if (captureListener == nullptr) { ALOGE("capture screen must provide a capture listener callback"); - return BAD_VALUE; + invokeScreenCaptureError(BAD_VALUE, captureListener); + return; } constexpr bool kAllowProtected = false; constexpr bool kGrayscale = false; - auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, size, - ui::PixelFormat::RGBA_8888, kAllowProtected, kGrayscale, - captureListener); - return fenceStatus(future.get()); + captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, size, + ui::PixelFormat::RGBA_8888, kAllowProtected, kGrayscale, captureListener); } -status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, - const sp<IScreenCaptureListener>& captureListener) { +void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, + const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); status_t validate = validateScreenshotPermissions(args); if (validate != OK) { - return validate; + invokeScreenCaptureError(validate, captureListener); + return; } ui::Size reqSize; @@ -7468,13 +7482,15 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, parent = LayerHandle::getLayer(args.layerHandle); if (parent == nullptr) { ALOGE("captureLayers called with an invalid or removed parent"); - return NAME_NOT_FOUND; + invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); + return; } if (!canCaptureBlackoutContent && parent->getDrawingState().flags & layer_state_t::eLayerSecure) { ALOGW("Attempting to capture secure layer: PERMISSION_DENIED"); - return PERMISSION_DENIED; + invokeScreenCaptureError(PERMISSION_DENIED, captureListener); + return; } Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getDrawingState()); @@ -7491,7 +7507,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, if (crop.isEmpty() || args.frameScaleX <= 0.0f || args.frameScaleY <= 0.0f) { // Error out if the layer has no source bounds (i.e. they are boundless) and a source // crop was not specified, or an invalid frame scale was provided. - return BAD_VALUE; + invokeScreenCaptureError(BAD_VALUE, captureListener); + return; } reqSize = ui::Size(crop.width() * args.frameScaleX, crop.height() * args.frameScaleY); @@ -7501,7 +7518,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, excludeLayerIds.emplace(excludeLayer); } else { ALOGW("Invalid layer handle passed as excludeLayer to captureLayers"); - return NAME_NOT_FOUND; + invokeScreenCaptureError(NAME_NOT_FOUND, captureListener); + return; } } } // mStateLock @@ -7509,7 +7527,8 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, // really small crop or frameScale if (reqSize.width <= 0 || reqSize.height <= 0) { ALOGW("Failed to captureLayes: crop or scale too small"); - return BAD_VALUE; + invokeScreenCaptureError(BAD_VALUE, captureListener); + return; } bool childrenOnly = args.childrenOnly; @@ -7573,26 +7592,27 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, if (captureListener == nullptr) { ALOGE("capture screen must provide a capture listener callback"); - return BAD_VALUE; + invokeScreenCaptureError(BAD_VALUE, captureListener); + return; } - auto future = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, - args.pixelFormat, args.allowProtected, args.grayscale, - captureListener); - return fenceStatus(future.get()); + captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, reqSize, args.pixelFormat, + args.allowProtected, args.grayscale, captureListener); } -ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( - RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots, - ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool grayscale, - const sp<IScreenCaptureListener>& captureListener) { +void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, + GetLayerSnapshotsFunction getLayerSnapshots, + ui::Size bufferSize, ui::PixelFormat reqPixelFormat, + bool allowProtected, bool grayscale, + const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) { ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32 ") that exceeds render target size limit.", bufferSize.getWidth(), bufferSize.getHeight()); - return ftl::yield<FenceResult>(base::unexpected(BAD_VALUE)).share(); + invokeScreenCaptureError(BAD_VALUE, captureListener); + return; } // Loop over all visible layers to see whether there's any protected layer. A protected layer is @@ -7632,14 +7652,16 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( // Otherwise an irreponsible process may cause an SF crash by allocating // too much. ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus); - return ftl::yield<FenceResult>(base::unexpected(bufferStatus)).share(); + invokeScreenCaptureError(bufferStatus, captureListener); + return; } const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared< renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture::Usage:: WRITEABLE); - return captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture, - false /* regionSampling */, grayscale, captureListener); + auto fence = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture, + false /* regionSampling */, grayscale, captureListener); + fence.get(); } ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon( @@ -9079,28 +9101,28 @@ binder::Status SurfaceComposerAIDL::setGameContentType(const sp<IBinder>& displa binder::Status SurfaceComposerAIDL::captureDisplay( const DisplayCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { - status_t status = mFlinger->captureDisplay(args, captureListener); - return binderStatusFromStatusT(status); + mFlinger->captureDisplay(args, captureListener); + return binderStatusFromStatusT(NO_ERROR); } binder::Status SurfaceComposerAIDL::captureDisplayById( int64_t displayId, const sp<IScreenCaptureListener>& captureListener) { - status_t status; + // status_t status; IPCThreadState* ipc = IPCThreadState::self(); const int uid = ipc->getCallingUid(); if (uid == AID_ROOT || uid == AID_GRAPHICS || uid == AID_SYSTEM || uid == AID_SHELL) { std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId)); - status = mFlinger->captureDisplay(*id, captureListener); + mFlinger->captureDisplay(*id, captureListener); } else { - status = PERMISSION_DENIED; + invokeScreenCaptureError(PERMISSION_DENIED, captureListener); } - return binderStatusFromStatusT(status); + return binderStatusFromStatusT(NO_ERROR); } binder::Status SurfaceComposerAIDL::captureLayers( const LayerCaptureArgs& args, const sp<IScreenCaptureListener>& captureListener) { - status_t status = mFlinger->captureLayers(args, captureListener); - return binderStatusFromStatusT(status); + mFlinger->captureLayers(args, captureListener); + return binderStatusFromStatusT(NO_ERROR); } binder::Status SurfaceComposerAIDL::overrideHdrTypes(const sp<IBinder>& display, diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index f61f9a2345..93560bdbcf 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -535,9 +535,9 @@ private: EventRegistrationFlags eventRegistration = {}, const sp<IBinder>& layerHandle = nullptr); - status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&); - status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&); - status_t captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&); + void captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&); + void captureDisplay(DisplayId, const sp<IScreenCaptureListener>&); + void captureLayers(const LayerCaptureArgs&, const sp<IScreenCaptureListener>&); status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats); status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) @@ -836,10 +836,9 @@ private: // Boot animation, on/off animations and screen capture void startBootAnim(); - ftl::SharedFuture<FenceResult> captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, - ui::Size bufferSize, ui::PixelFormat, - bool allowProtected, bool grayscale, - const sp<IScreenCaptureListener>&); + void captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, ui::Size bufferSize, + ui::PixelFormat, bool allowProtected, bool grayscale, + const sp<IScreenCaptureListener>&); ftl::SharedFuture<FenceResult> captureScreenCommon( RenderAreaFuture, GetLayerSnapshotsFunction, const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling, |