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

Commit b71b0625 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Added LayerCapture args to captureLayers functions"

parents 730be0e0 3efadb1d
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