diff options
| -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 bedf76589f..b8a890679e 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -287,7 +287,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 4f812fc81b..36306773f7 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); } @@ -35,10 +40,13 @@ public: Transform::orientation_flags getRotationFlags() const { return mRotationFlags; }; 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 a8680e2dd8..dfde30bb32 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4694,7 +4694,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), @@ -4929,8 +4929,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 |