diff options
author | 2018-04-09 13:49:37 -0700 | |
---|---|---|
committer | 2018-04-12 19:34:58 +0000 | |
commit | 50da5043ad224fd6b6024ed73785a9502bf7978d (patch) | |
tree | b6be4ec360db2ef03904fb9c7eb2007076e79fa4 | |
parent | 2788edd12f4f149dc8eadb561566edb66aa4f7e8 (diff) |
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
-rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/RenderArea.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/RenderArea.h | 12 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 | ||||
-rw-r--r-- | services/surfaceflinger/tests/Transaction_test.cpp | 18 |
5 files changed, 42 insertions, 5 deletions
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index e844d115c2..61ce30ca86 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -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(); } diff --git a/services/surfaceflinger/RenderArea.cpp b/services/surfaceflinger/RenderArea.cpp index 6225df134d..46ec8e68ba 100644 --- a/services/surfaceflinger/RenderArea.cpp +++ b/services/surfaceflinger/RenderArea.cpp @@ -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 diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h index bf0707f13b..62a3d5b333 100644 --- a/services/surfaceflinger/RenderArea.h +++ b/services/surfaceflinger/RenderArea.h @@ -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 diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 183c1eb07c..781a30ccf5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -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); diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 176c691c6a..a0f12f1438 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -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 |