diff options
| -rw-r--r-- | services/surfaceflinger/ScreenCaptureOutput.cpp | 26 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/ScreenCapture_test.cpp | 52 |
2 files changed, 70 insertions, 8 deletions
diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp index 09dac23410..b3459134cc 100644 --- a/services/surfaceflinger/ScreenCaptureOutput.cpp +++ b/services/surfaceflinger/ScreenCaptureOutput.cpp @@ -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"; diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp index 013694fd47..96cc333a08 100644 --- a/services/surfaceflinger/tests/ScreenCapture_test.cpp +++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp @@ -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, |