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

Commit c1879001 authored by Dan Stoza's avatar Dan Stoza
Browse files

SurfaceFlinger: Add sourceCrop to screenshot

Adds a sourceCrop Rect parameter to screenshot commands, which allows
clients to capture only a portion of the screen instead of the whole
screen.

Bug: 15137922
Change-Id: I629447573cd34ffb96334cde7ba02490b9ea06d8
parent 9bf29a81
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ class DisplayState;
class DisplayInfo;
class IDisplayEventConnection;
class IMemoryHeap;
class Rect;

/*
 * This class defines the Binder IPC interface for accessing various
@@ -131,11 +132,10 @@ public:
     */
    virtual status_t captureScreen(const sp<IBinder>& display,
            const sp<IGraphicBufferProducer>& producer,
            uint32_t reqWidth, uint32_t reqHeight,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            uint32_t minLayerZ, uint32_t maxLayerZ,
            bool useIdentityTransform) = 0;


    /* Clears the frame statistics for animations.
     *
     * Requires the ACCESS_SURFACE_FLINGER permission.
+10 −5
Original line number Diff line number Diff line
@@ -180,10 +180,12 @@ private:
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,
            const sp<IGraphicBufferProducer>& producer,
            uint32_t reqWidth, uint32_t reqHeight,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            uint32_t minLayerZ, uint32_t maxLayerZ,
            bool useIdentityTransform);

@@ -197,13 +199,16 @@ public:
    ScreenshotClient();
    ~ScreenshotClient();

    // frees the previous screenshot and capture a new one
    status_t update(const sp<IBinder>& display, bool useIdentityTransform);
    // frees the previous screenshot and captures a new one
    // if cropping isn't required, callers may pass in a default Rect, e.g.:
    //   update(display, Rect(), useIdentityTransform);
    status_t update(const sp<IBinder>& display,
            uint32_t reqWidth, uint32_t reqHeight,
            Rect sourceCrop, bool useIdentityTransform);
    status_t update(const sp<IBinder>& display,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            bool useIdentityTransform);
    status_t update(const sp<IBinder>& display,
            uint32_t reqWidth, uint32_t reqHeight,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            uint32_t minLayerZ, uint32_t maxLayerZ,
            bool useIdentityTransform);

+5 −2
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ public:

    virtual status_t captureScreen(const sp<IBinder>& display,
            const sp<IGraphicBufferProducer>& producer,
            uint32_t reqWidth, uint32_t reqHeight,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            uint32_t minLayerZ, uint32_t maxLayerZ,
            bool useIdentityTransform)
    {
@@ -112,6 +112,7 @@ public:
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeStrongBinder(display);
        data.writeStrongBinder(producer->asBinder());
        data.write(sourceCrop);
        data.writeInt32(reqWidth);
        data.writeInt32(reqHeight);
        data.writeInt32(minLayerZ);
@@ -328,6 +329,8 @@ status_t BnSurfaceComposer::onTransact(
            sp<IBinder> display = data.readStrongBinder();
            sp<IGraphicBufferProducer> producer =
                    interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
            Rect sourceCrop;
            data.read(sourceCrop);
            uint32_t reqWidth = data.readInt32();
            uint32_t reqHeight = data.readInt32();
            uint32_t minLayerZ = data.readInt32();
@@ -335,7 +338,7 @@ status_t BnSurfaceComposer::onTransact(
            bool useIdentityTransform = static_cast<bool>(data.readInt32());

            status_t res = captureScreen(display, producer,
                    reqWidth, reqHeight, minLayerZ, maxLayerZ,
                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
                    useIdentityTransform);
            reply->writeInt32(res);
            return NO_ERROR;
+9 −9
Original line number Diff line number Diff line
@@ -676,11 +676,11 @@ status_t SurfaceComposerClient::getAnimationFrameStats(FrameStats* outStats) {
status_t ScreenshotClient::capture(
        const sp<IBinder>& display,
        const sp<IGraphicBufferProducer>& producer,
        uint32_t reqWidth, uint32_t reqHeight,
        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
        uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
    return s->captureScreen(display, producer,
    return s->captureScreen(display, producer, sourceCrop,
            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
}

@@ -704,7 +704,7 @@ sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
}

status_t ScreenshotClient::update(const sp<IBinder>& display,
        uint32_t reqWidth, uint32_t reqHeight,
        Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
        uint32_t minLayerZ, uint32_t maxLayerZ,
        bool useIdentityTransform) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
@@ -717,7 +717,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
        mHaveBuffer = false;
    }

    status_t err = s->captureScreen(display, mProducer,
    status_t err = s->captureScreen(display, mProducer, sourceCrop,
            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);

    if (err == NO_ERROR) {
@@ -729,16 +729,16 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
    return err;
}

status_t ScreenshotClient::update(const sp<IBinder>& display,
status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
        bool useIdentityTransform) {
    return ScreenshotClient::update(display, 0, 0, 0, -1UL,
    return ScreenshotClient::update(display, sourceCrop, 0, 0, 0, -1UL,
            useIdentityTransform);
}

status_t ScreenshotClient::update(const sp<IBinder>& display,
status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
        uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) {
    return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL,
            useIdentityTransform);
    return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight,
            0, -1UL, useIdentityTransform);
}

void ScreenshotClient::release() {
+3 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/BufferItemConsumer.h>
#include <ui/Rect.h>
#include <utils/String8.h>

#include <private/gui/ComposerService.h>
@@ -94,7 +95,7 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
    sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer,
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(),
            64, 64, 0, 0x7fffffff, false));

    // Set the PROTECTED usage bit and verify that the screenshot fails.  Note
@@ -123,7 +124,7 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
                &buf));
        ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
    }
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer,
    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(),
            64, 64, 0, 0x7fffffff, false));
}

Loading