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

Commit 95f01f42 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[SurfaceFlinger] Accept data space and pixel format to take screenshot."

parents aeaf4087 0e003c90
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -103,11 +103,15 @@ public:
    }

    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
                                   bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
                                   const ui::Dataspace reqDataspace,
                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
                                   ISurfaceComposer::Rotation rotation) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeStrongBinder(display);
        data.writeInt32(static_cast<int32_t>(reqDataspace));
        data.writeInt32(static_cast<int32_t>(reqPixelFormat));
        data.write(sourceCrop);
        data.writeUint32(reqWidth);
        data.writeUint32(reqHeight);
@@ -126,15 +130,19 @@ public:

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

        return result;
    }

    virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
                                   sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
                                   sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace,
                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                   float frameScale, bool childrenOnly) {
        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.writeFloat(frameScale);
        data.writeBool(childrenOnly);
@@ -148,6 +156,7 @@ public:
            ALOGE("captureLayers failed to readInt32: %d", result);
            return result;
        }

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

@@ -645,6 +654,8 @@ status_t BnSurfaceComposer::onTransact(
        case CAPTURE_SCREEN: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> display = 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);
@@ -653,8 +664,8 @@ status_t BnSurfaceComposer::onTransact(
            bool useIdentityTransform = static_cast<bool>(data.readInt32());
            int32_t rotation = data.readInt32();

            status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight,
                                         useIdentityTransform,
            status_t res = captureScreen(display, &outBuffer, reqDataspace, reqPixelFormat,
                                         sourceCrop, reqWidth, reqHeight, useIdentityTransform,
                                         static_cast<ISurfaceComposer::Rotation>(rotation));
            reply->writeInt32(res);
            if (res == NO_ERROR) {
@@ -665,14 +676,16 @@ 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);
            float frameScale = data.readFloat();
            bool childrenOnly = data.readBool();

            status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale,
                                         childrenOnly);
            status_t res = captureLayers(layerHandleBinder, &outBuffer, reqDataspace,
                                         reqPixelFormat, sourceCrop, frameScale, childrenOnly);
            reply->writeInt32(res);
            if (res == NO_ERROR) {
                reply->write(*outBuffer);
+16 −11
Original line number Diff line number Diff line
@@ -887,13 +887,14 @@ status_t SurfaceComposerClient::getHdrCapabilities(const sp<IBinder>& display,

// ----------------------------------------------------------------------------

status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
                                   uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
                                   sp<GraphicBuffer>* outBuffer) {
status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
                                   uint32_t rotation, sp<GraphicBuffer>* outBuffer) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == nullptr) return NO_INIT;
    status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight,
                                    useIdentityTransform,
    status_t ret = s->captureScreen(display, outBuffer, reqDataSpace, reqPixelFormat, sourceCrop,
                                    reqWidth, reqHeight, useIdentityTransform,
                                    static_cast<ISurfaceComposer::Rotation>(rotation));
    if (ret != NO_ERROR) {
        return ret;
@@ -901,21 +902,25 @@ status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop,
    return ret;
}

status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
                                         const ui::Dataspace reqDataSpace,
                                         const ui::PixelFormat reqPixelFormat, 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, sourceCrop, frameScale,
                                    false /* childrenOnly */);
    status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat,
                                    sourceCrop, frameScale, false /* childrenOnly */);
    return ret;
}

status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle,
                                              const ui::Dataspace reqDataSpace,
                                              const ui::PixelFormat reqPixelFormat, 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, sourceCrop, frameScale,
                                    true /* childrenOnly */);
    status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat,
                                    sourceCrop, frameScale, true /* childrenOnly */);
    return ret;
}
// ----------------------------------------------------------------------------
+51 −2
Original line number Diff line number Diff line
@@ -180,6 +180,36 @@ public:
     * The subregion can be optionally rotated.  It will also be scaled to
     * match the size of the output buffer.
     *
     * 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.
     *
     * At the moment, sourceCrop is ignored and is always set to the visible
     * region (projected display viewport) of the screen.
     *
     * reqWidth and reqHeight specifies the size of the buffer.  When either
     * of them is 0, they are set to the size of the logical display viewport.
     *
     * When useIdentityTransform is true, layer transformations are disabled.
     *
     * rotation specifies the rotation of the source crop (and the pixels in
     * it) around its center.
     */
    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                   const ui::Dataspace reqDataspace,
                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
                                   Rotation rotation = eRotateNone) = 0;
    /**
     * Capture the specified screen. This requires READ_FRAME_BUFFER
     * permission.  This function will fail if there is a secure window on
     * screen.
     *
     * This function can capture a subregion (the source crop) of the screen
     * into an sRGB buffer with RGBA_8888 pixel format.
     * The subregion can be optionally rotated.  It will also be scaled to
     * match the size of the output buffer.
     *
     * At the moment, sourceCrop is ignored and is always set to the visible
     * region (projected display viewport) of the screen.
     *
@@ -193,15 +223,34 @@ public:
     */
    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
                                   bool useIdentityTransform, Rotation rotation = eRotateNone) = 0;
                                   bool useIdentityTransform, Rotation rotation = eRotateNone) {
        return captureScreen(display, outBuffer, ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
                             sourceCrop, reqWidth, reqHeight, useIdentityTransform, rotation);
    }

    /**
     * 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.
     */
    virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
                                   sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
                                   sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace,
                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                   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);
    }

    /* Clears the frame statistics for animations.
     *
     * Requires the ACCESS_SURFACE_FLINGER permission.
+10 −6
Original line number Diff line number Diff line
@@ -329,12 +329,16 @@ class ScreenshotClient {
public:
    // if cropping isn't required, callers may pass in a default Rect, e.g.:
    //   capture(display, producer, Rect(), reqWidth, ...);
    static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
                            uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
                            sp<GraphicBuffer>* outBuffer);
    static status_t captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale,
                                  sp<GraphicBuffer>* outBuffer);
    static status_t captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
    static status_t capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
                            const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                            uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
                            uint32_t rotation, sp<GraphicBuffer>* outBuffer);
    static status_t captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
                                  const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                  float frameScale, sp<GraphicBuffer>* outBuffer);
    static status_t captureChildLayers(const sp<IBinder>& layerHandle,
                                       const ui::Dataspace reqDataSpace,
                                       const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                       float frameScale, sp<GraphicBuffer>* outBuffer);
};

+18 −11
Original line number Diff line number Diff line
@@ -134,8 +134,9 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
    sp<IBinder> display(sf->getBuiltInDisplay(
            ISurfaceComposer::eDisplayIdMain));
    sp<GraphicBuffer> outBuffer;
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
            64, 64, false));
    ASSERT_EQ(NO_ERROR,
              sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB,
                                ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false));

    ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
            NATIVE_WINDOW_API_CPU));
@@ -165,8 +166,9 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
                &buf));
        ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
    }
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
            64, 64, false));
    ASSERT_EQ(NO_ERROR,
              sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB,
                                ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false));
}

TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
@@ -596,14 +598,19 @@ public:
    }
    status_t setActiveColorMode(const sp<IBinder>& /*display*/,
        ColorMode /*colorMode*/) override { return NO_ERROR; }
    status_t captureScreen(const sp<IBinder>& /*display*/,
            sp<GraphicBuffer>* /*outBuffer*/,
            Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
            bool /*useIdentityTransform*/,
            Rotation /*rotation*/) override { return NO_ERROR; }
    status_t captureScreen(const sp<IBinder>& /*display*/, sp<GraphicBuffer>* /*outBuffer*/,
                           const ui::Dataspace /*reqDataspace*/,
                           const ui::PixelFormat /*reqPixelFormat*/, Rect /*sourceCrop*/,
                           uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
                           bool /*useIdentityTransform*/, Rotation /*rotation*/) override {
        return NO_ERROR;
    }
    virtual status_t captureLayers(const sp<IBinder>& /*parentHandle*/,
                                   sp<GraphicBuffer>* /*outBuffer*/, const Rect& /*sourceCrop*/,
                                   float /*frameScale*/, bool /*childrenOnly*/) override {
                                   sp<GraphicBuffer>* /*outBuffer*/,
                                   const ui::Dataspace /*reqDataspace*/,
                                   const ui::PixelFormat /*reqPixelFormat*/,
                                   const Rect& /*sourceCrop*/, float /*frameScale*/,
                                   bool /*childrenOnly*/) override {
        return NO_ERROR;
    }
    status_t clearAnimationFrameStats() override { return NO_ERROR; }
Loading