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

Commit 1c8d8425 authored by Patrick Williams's avatar Patrick Williams
Browse files

Fix captureDisplay when the display is rotated

Bug: 288824234
Test: manual screenshots with temporary changes to use captureDisplay
Test: ScreenCaptureTest
Change-Id: I31591d6111303518776308a0dfaa195082a7950a
parent b410845c
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -24,6 +24,24 @@

namespace android {

namespace {

ui::Size getDisplaySize(ui::Rotation orientation, const Rect& sourceCrop) {
    if (orientation == ui::Rotation::Rotation90 || orientation == ui::Rotation::Rotation270) {
        return {sourceCrop.getHeight(), sourceCrop.getWidth()};
    }
    return {sourceCrop.getWidth(), sourceCrop.getHeight()};
}

Rect getOrientedDisplaySpaceRect(ui::Rotation orientation, int reqWidth, int reqHeight) {
    if (orientation == ui::Rotation::Rotation90 || orientation == ui::Rotation::Rotation270) {
        return {reqHeight, reqWidth};
    }
    return {reqWidth, reqHeight};
}

} // namespace

std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs args) {
    std::shared_ptr<ScreenCaptureOutput> output = compositionengine::impl::createOutputTemplated<
            ScreenCaptureOutput, compositionengine::CompositionEngine, const RenderArea&,
@@ -45,10 +63,10 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp

    const Rect& sourceCrop = args.renderArea.getSourceCrop();
    const ui::Rotation orientation = ui::Transform::toRotation(args.renderArea.getRotationFlags());
    const Rect orientedDisplaySpaceRect{args.renderArea.getReqWidth(),
                                        args.renderArea.getReqHeight()};
    output->setProjection(orientation, sourceCrop, orientedDisplaySpaceRect);
    output->setDisplaySize({sourceCrop.getWidth(), sourceCrop.getHeight()});
    output->setDisplaySize(getDisplaySize(orientation, sourceCrop));
    output->setProjection(orientation, sourceCrop,
                          getOrientedDisplaySpaceRect(orientation, args.renderArea.getReqWidth(),
                                                      args.renderArea.getReqHeight()));

    {
        std::string name = args.regionSampling ? "RegionSampling" : "ScreenCaptureOutput";
+48 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#pragma clang diagnostic ignored "-Wconversion"

#include <private/android_filesystem_config.h>
#include <ui/DisplayState.h>

#include "LayerTransactionTest.h"

@@ -32,11 +33,11 @@ protected:

        const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
        ASSERT_FALSE(ids.empty());
        const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
        ASSERT_FALSE(display == nullptr);
        mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
        ASSERT_FALSE(mDisplayToken == nullptr);

        ui::DisplayMode mode;
        ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
        ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
        const ui::Size& resolution = mode.resolution;

        mDisplaySize = resolution;
@@ -57,7 +58,7 @@ protected:
        TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);

        asTransaction([&](Transaction& t) {
            t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK);
            t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);

            t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);

@@ -71,11 +72,18 @@ protected:
        LayerTransactionTest::TearDown();
        mBGSurfaceControl = 0;
        mFGSurfaceControl = 0;

        // Restore display rotation
        asTransaction([&](Transaction& t) {
            Rect displayBounds{mDisplaySize};
            t.setDisplayProjection(mDisplayToken, ui::ROTATION_0, displayBounds, displayBounds);
        });
    }

    sp<SurfaceControl> mBGSurfaceControl;
    sp<SurfaceControl> mFGSurfaceControl;
    std::unique_ptr<ScreenCapture> mCapture;
    sp<IBinder> mDisplayToken;
    ui::Size mDisplaySize;
};

@@ -870,6 +878,42 @@ TEST_F(ScreenCaptureTest, CaptureOffscreen) {
    mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
}

TEST_F(ScreenCaptureTest, CaptureDisplayWith90DegRotation) {
    asTransaction([&](Transaction& t) {
        Rect newDisplayBounds{mDisplaySize.height, mDisplaySize.width};
        t.setDisplayProjection(mDisplayToken, ui::ROTATION_90, newDisplayBounds, newDisplayBounds);
    });

    DisplayCaptureArgs displayCaptureArgs;
    displayCaptureArgs.displayToken = mDisplayToken;
    displayCaptureArgs.width = mDisplaySize.width;
    displayCaptureArgs.height = mDisplaySize.height;
    displayCaptureArgs.useIdentityTransform = true;
    ScreenCapture::captureDisplay(&mCapture, displayCaptureArgs);

    mCapture->expectBGColor(0, 0);
    mCapture->expectFGColor(mDisplaySize.width - 65, 65);
}

TEST_F(ScreenCaptureTest, CaptureDisplayWith270DegRotation) {
    asTransaction([&](Transaction& t) {
        Rect newDisplayBounds{mDisplaySize.height, mDisplaySize.width};
        t.setDisplayProjection(mDisplayToken, ui::ROTATION_270, newDisplayBounds, newDisplayBounds);
    });

    DisplayCaptureArgs displayCaptureArgs;
    displayCaptureArgs.displayToken = mDisplayToken;
    displayCaptureArgs.width = mDisplaySize.width;
    displayCaptureArgs.height = mDisplaySize.height;
    displayCaptureArgs.useIdentityTransform = true;
    ScreenCapture::captureDisplay(&mCapture, displayCaptureArgs);

    std::this_thread::sleep_for(std::chrono::seconds{5});

    mCapture->expectBGColor(mDisplayWidth - 1, mDisplaySize.height - 1);
    mCapture->expectFGColor(65, mDisplaySize.height - 65);
}

TEST_F(ScreenCaptureTest, CaptureNonHdrLayer) {
    sp<SurfaceControl> layer;
    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,