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

Commit 50da5043 authored by chaviw's avatar chaviw Committed by Chavi Weingarten
Browse files

Set window to transparent when screenshotting layer.

Set the screenshot to transparent instead of black. This allows the
system to draw a color behind without having to crop out the area that
may not be drawn into.

Bug: 76442549
Test: When going to recents, area not drawn from layers is now
transparent instead of black.
Test: Transaction_test#CaptureTransparent

Change-Id: Id535eb753d3d1cae82658cd33423ce588aaa62f8
parent 2788edd1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -281,7 +281,8 @@ public:
                              rotation) {}
    DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqHeight,
                      uint32_t reqWidth, ISurfaceComposer::Rotation rotation)
          : RenderArea(reqHeight, reqWidth, rotation), mDevice(device), mSourceCrop(sourceCrop) {}
          : RenderArea(reqHeight, reqWidth, CaptureFill::OPAQUE, rotation), mDevice(device),
                              mSourceCrop(sourceCrop) {}

    const Transform& getTransform() const override { return mDevice->getTransform(); }
    Rect getBounds() const override { return mDevice->getBounds(); }
+9 −0
Original line number Diff line number Diff line
@@ -2,6 +2,15 @@

namespace android {

float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
    switch(captureFill) {
        case CaptureFill::CLEAR:
            return 0.0f;
        case CaptureFill::OPAQUE:
        default:
            return 1.0f;
    }
}
/*
 * Checks that the requested width and height are valid and updates them to the render area
 * dimensions if they are set to 0
+10 −2
Original line number Diff line number Diff line
@@ -9,10 +9,15 @@
namespace android {

class RenderArea {

public:
    RenderArea(uint32_t reqHeight, uint32_t reqWidth,
    enum class CaptureFill {CLEAR, OPAQUE};

    static float getCaptureFillValue(CaptureFill captureFill);

    RenderArea(uint32_t reqHeight, uint32_t reqWidth, CaptureFill captureFill,
               ISurfaceComposer::Rotation rotation = ISurfaceComposer::eRotateNone)
          : mReqHeight(reqHeight), mReqWidth(reqWidth) {
          : mReqHeight(reqHeight), mReqWidth(reqWidth), mCaptureFill(captureFill) {
        mRotationFlags = Transform::fromRotation(rotation);
    }

@@ -36,10 +41,13 @@ public:

    status_t updateDimensions();

    CaptureFill getCaptureFill() const { return mCaptureFill; };

private:
    uint32_t mReqHeight;
    uint32_t mReqWidth;
    Transform::orientation_flags mRotationFlags;
    CaptureFill mCaptureFill;
};

} // namespace android
+3 −2
Original line number Diff line number Diff line
@@ -4597,7 +4597,7 @@ status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
    public:
        LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
                        int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
              : RenderArea(reqHeight, reqWidth),
              : RenderArea(reqHeight, reqWidth, CaptureFill::CLEAR),
                mLayer(layer),
                mCrop(crop),
                mFlinger(flinger),
@@ -4834,8 +4834,9 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
                                    renderArea.getRotationFlags());
    engine.disableTexturing();

    const float alpha = RenderArea::getCaptureFillValue(renderArea.getCaptureFill());
    // redraw the screen entirely...
    engine.clearWithColor(0, 0, 0, 1);
    engine.clearWithColor(0, 0, 0, alpha);

    traverseLayers([&](Layer* layer) {
        if (filtering) layer->setFiltering(true);
+18 −0
Original line number Diff line number Diff line
@@ -2358,6 +2358,24 @@ TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
    mCapture->expectChildColor(0, 0);
}

TEST_F(ScreenCaptureTest, CaptureTransparent) {
    sp<SurfaceControl> child =
            mComposerClient->createSurface(String8("Child surface"), 10, 10, PIXEL_FORMAT_RGBA_8888,
                                           0, mFGSurfaceControl.get());

    fillSurfaceRGBA8(child, 200, 200, 200);

    SurfaceComposerClient::Transaction().show(child).apply(true);

    auto childHandle = child->getHandle();

    // Captures child
    ScreenCapture::captureLayers(&mCapture, childHandle, {0, 0, 10, 20});
    mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
    // Area outside of child's bounds is transparent.
    mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
}


// In the following tests we verify successful skipping of a parent layer,
// so we use the same verification logic and only change how we mutate