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

Commit 3efadb1d authored by chaviw's avatar chaviw
Browse files

Added LayerCapture args to captureLayers functions

Pass LayerCaptureArgs and ScreenCaptureResults to captureLayers
functions.

Test: Recents takes screenshot
Test: SurfaceFlinger_test
Bug: 162367424

Change-Id: Ib4cfeb0e60c12009ffe271578f04522970a1f769
parent 8f9a7705
Loading
Loading
Loading
Loading
+20 −42
Original line number Diff line number Diff line
@@ -157,25 +157,18 @@ public:
        return result;
    }

    virtual status_t captureLayers(
            const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
            const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat,
            const Rect& sourceCrop,
            const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& excludeLayers, float frameScale,
            bool childrenOnly) {
    virtual status_t captureLayers(const LayerCaptureArgs& args,
                                   ScreenCaptureResults& captureResults) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeStrongBinder(layerHandleBinder);
        data.writeInt32(static_cast<int32_t>(reqDataspace));
        data.writeInt32(static_cast<int32_t>(reqPixelFormat));
        data.write(sourceCrop);
        data.writeInt32(excludeLayers.size());
        for (auto el : excludeLayers) {
            data.writeStrongBinder(el);
        }
        data.writeFloat(frameScale);
        data.writeBool(childrenOnly);
        status_t result = remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);

        status_t result = args.write(data);
        if (result != NO_ERROR) {
            ALOGE("captureLayers failed to parcel args: %d", result);
            return result;
        }

        result = remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("captureLayers failed to transact: %d", result);
            return result;
@@ -186,9 +179,7 @@ public:
            return result;
        }

        *outBuffer = new GraphicBuffer();
        reply.read(**outBuffer);

        captureResults.read(reply);
        return result;
    }

@@ -1315,32 +1306,19 @@ status_t BnSurfaceComposer::onTransact(
        }
        case CAPTURE_LAYERS: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> layerHandleBinder = data.readStrongBinder();
            ui::Dataspace reqDataspace = static_cast<ui::Dataspace>(data.readInt32());
            ui::PixelFormat reqPixelFormat = static_cast<ui::PixelFormat>(data.readInt32());
            sp<GraphicBuffer> outBuffer;
            Rect sourceCrop(Rect::EMPTY_RECT);
            data.read(sourceCrop);

            std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;
            int numExcludeHandles = data.readInt32();
            if (numExcludeHandles >= static_cast<int>(MAX_LAYERS)) {
                return BAD_VALUE;
            }
            excludeHandles.reserve(numExcludeHandles);
            for (int i = 0; i < numExcludeHandles; i++) {
                excludeHandles.emplace(data.readStrongBinder());
            }
            LayerCaptureArgs args;
            ScreenCaptureResults captureResults;

            float frameScale = data.readFloat();
            bool childrenOnly = data.readBool();
            status_t res = args.read(data);
            if (res != NO_ERROR) {
                reply->writeInt32(res);
                return NO_ERROR;
            }

            status_t res =
                    captureLayers(layerHandleBinder, &outBuffer, reqDataspace, reqPixelFormat,
                                  sourceCrop, excludeHandles, frameScale, childrenOnly);
            res = captureLayers(args, captureResults);
            reply->writeInt32(res);
            if (res == NO_ERROR) {
                reply->write(*outBuffer);
                captureResults.write(*reply);
            }
            return NO_ERROR;
        }
+30 −10
Original line number Diff line number Diff line
@@ -1950,12 +1950,12 @@ status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace /*
    return ret;
}

status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace,
status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace reqDataspace,
                                   ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
                                   ui::Rotation rotation, sp<GraphicBuffer>* outBuffer) {
    bool ignored;
    return capture(display, reqDataSpace, reqPixelFormat, sourceCrop, reqWidth, reqHeight,
    return capture(display, reqDataspace, reqPixelFormat, sourceCrop, reqWidth, reqHeight,
                   useIdentityTransform, rotation, false, outBuffer, ignored);
}

@@ -1970,26 +1970,46 @@ status_t ScreenshotClient::capture(uint64_t displayOrLayerStack, ui::Dataspace*
    return ret;
}

status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace,
status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
                                         ui::Dataspace /* reqDataspace */,
                                         ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                         float frameScale, sp<GraphicBuffer>* outBuffer) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == nullptr) return NO_INIT;
    status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat,
                                    sourceCrop, {}, frameScale, false /* childrenOnly */);

    LayerCaptureArgs args;
    args.layerHandle = layerHandle;
    args.pixelFormat = reqPixelFormat;
    args.sourceCrop = sourceCrop;
    args.frameScale = frameScale;

    ScreenCaptureResults captureResults;
    status_t ret = s->captureLayers(args, captureResults);

    *outBuffer = captureResults.buffer;
    return ret;
}

status_t ScreenshotClient::captureChildLayers(
        const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace, ui::PixelFormat reqPixelFormat,
        const Rect& sourceCrop,
        const sp<IBinder>& layerHandle, ui::Dataspace /* reqDataspace */,
        ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
        const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& excludeHandles,
        float frameScale, sp<GraphicBuffer>* outBuffer) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == nullptr) return NO_INIT;
    status_t ret =
            s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat, sourceCrop,
                             excludeHandles, frameScale, true /* childrenOnly */);

    LayerCaptureArgs args;
    args.layerHandle = layerHandle;
    args.pixelFormat = reqPixelFormat;
    args.sourceCrop = sourceCrop;
    args.frameScale = frameScale;
    args.excludeHandles = excludeHandles;
    args.childrenOnly = true;

    ScreenCaptureResults captureResults;
    status_t ret = s->captureLayers(args, captureResults);

    *outBuffer = captureResults.buffer;
    return ret;
}

+4 −20
Original line number Diff line number Diff line
@@ -268,27 +268,11 @@ public:

    /**
     * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
     *
     * reqDataspace and reqPixelFormat specify the data space and pixel format
     * of the buffer. The caller should pick the data space and pixel format
     * that it can consume.
     * This requires READ_FRAME_BUFFER permission. This function will fail if there
     * is a secure window on screen
     */
    virtual status_t captureLayers(
            const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
            ui::Dataspace reqDataspace, ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
            const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& excludeHandles,
            float frameScale = 1.0, bool childrenOnly = false) = 0;

    /**
     * Capture a subtree of the layer hierarchy into an sRGB buffer with RGBA_8888 pixel format,
     * potentially ignoring the root node.
     */
    status_t captureLayers(const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
                           const Rect& sourceCrop, float frameScale = 1.0,
                           bool childrenOnly = false) {
        return captureLayers(layerHandleBinder, outBuffer, ui::Dataspace::V0_SRGB,
                             ui::PixelFormat::RGBA_8888, sourceCrop, {}, frameScale, childrenOnly);
    }
    virtual status_t captureLayers(const LayerCaptureArgs& args,
                                   ScreenCaptureResults& captureResults) = 0;

    /* Clears the frame statistics for animations.
     *
+2 −7
Original line number Diff line number Diff line
@@ -760,13 +760,8 @@ public:
                            ScreenCaptureResults& /* captureResults */) override {
        return NO_ERROR;
    }
    virtual status_t captureLayers(
            const sp<IBinder>& /*parentHandle*/, sp<GraphicBuffer>* /*outBuffer*/,
            ui::Dataspace /*reqDataspace*/, ui::PixelFormat /*reqPixelFormat*/,
            const Rect& /*sourceCrop*/,
            const std::unordered_set<sp<IBinder>,
                                     ISurfaceComposer::SpHash<IBinder>>& /*excludeHandles*/,
            float /*frameScale*/, bool /*childrenOnly*/) override {
    virtual status_t captureLayers(const LayerCaptureArgs& /* captureArgs */,
                                   ScreenCaptureResults& /* captureResults */) override {
        return NO_ERROR;
    }
    status_t clearAnimationFrameStats() override { return NO_ERROR; }
+20 −16
Original line number Diff line number Diff line
@@ -5585,22 +5585,20 @@ status_t SurfaceFlinger::captureDisplay(uint64_t displayOrLayerStack,
                               captureResults.capturedSecureLayers);
}

status_t SurfaceFlinger::captureLayers(
        const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
        const Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
        const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& excludeHandles,
        float frameScale, bool childrenOnly) {
status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
                                       ScreenCaptureResults& captureResults) {
    ATRACE_CALL();

    ui::Size reqSize;
    sp<Layer> parent;
    Rect crop(sourceCrop);
    Rect crop(args.sourceCrop);
    std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers;
    Rect displayViewport;
    ui::Dataspace dataspace;
    {
        Mutex::Autolock lock(mStateLock);

        parent = fromHandleLocked(layerHandleBinder).promote();
        parent = fromHandleLocked(args.layerHandle).promote();
        if (parent == nullptr || parent->isRemovedFromCurrentState()) {
            ALOGE("captureLayers called with an invalid or removed parent");
            return NAME_NOT_FOUND;
@@ -5614,24 +5612,24 @@ status_t SurfaceFlinger::captureLayers(
        }

        Rect parentSourceBounds = parent->getCroppedBufferSize(parent->getCurrentState());
        if (sourceCrop.width() <= 0) {
        if (args.sourceCrop.width() <= 0) {
            crop.left = 0;
            crop.right = parentSourceBounds.getWidth();
        }

        if (sourceCrop.height() <= 0) {
        if (args.sourceCrop.height() <= 0) {
            crop.top = 0;
            crop.bottom = parentSourceBounds.getHeight();
        }

        if (crop.isEmpty() || frameScale <= 0.0f) {
        if (crop.isEmpty() || args.frameScale <= 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;
        }
        reqSize = ui::Size(crop.width() * frameScale, crop.height() * frameScale);
        reqSize = ui::Size(crop.width() * args.frameScale, crop.height() * args.frameScale);

        for (const auto& handle : excludeHandles) {
        for (const auto& handle : args.excludeHandles) {
            sp<Layer> excludeLayer = fromHandleLocked(handle).promote();
            if (excludeLayer != nullptr) {
                excludeLayers.emplace(excludeLayer);
@@ -5647,6 +5645,9 @@ status_t SurfaceFlinger::captureLayers(
        }

        displayViewport = display->getViewport();

        const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
        dataspace = pickDataspaceFromColorMode(colorMode);
    } // mStateLock

    // really small crop or frameScale
@@ -5657,8 +5658,10 @@ status_t SurfaceFlinger::captureLayers(
        reqSize.height = 1;
    }

    bool childrenOnly = args.childrenOnly;

    RenderAreaFuture renderAreaFuture = promise::defer([=]() -> std::unique_ptr<RenderArea> {
        return std::make_unique<LayerRenderArea>(*this, parent, crop, reqSize, reqDataspace,
        return std::make_unique<LayerRenderArea>(*this, parent, crop, reqSize, dataspace,
                                                 childrenOnly, displayViewport);
    });

@@ -5683,9 +5686,10 @@ status_t SurfaceFlinger::captureLayers(
        });
    };

    bool outCapturedSecureLayers = false;
    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize, outBuffer,
                               reqPixelFormat, false, outCapturedSecureLayers);
    captureResults.capturedDataspace = dataspace;
    return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, reqSize,
                               &captureResults.buffer, args.pixelFormat, false,
                               captureResults.capturedSecureLayers);
}

status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
Loading