diff options
| -rw-r--r-- | libs/renderengine/gl/GLESRenderEngine.cpp | 5 | ||||
| -rw-r--r-- | libs/renderengine/include/renderengine/DisplaySettings.h | 12 | ||||
| -rw-r--r-- | libs/renderengine/tests/RenderEngineTest.cpp | 19 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 33 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 10 | ||||
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 75 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 13 | ||||
| -rw-r--r-- | services/surfaceflinger/RenderArea.h | 7 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 76 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp | 4 |
12 files changed, 133 insertions, 125 deletions
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp index e73f245fab..d56a82f4d7 100644 --- a/libs/renderengine/gl/GLESRenderEngine.cpp +++ b/libs/renderengine/gl/GLESRenderEngine.cpp @@ -795,6 +795,7 @@ void GLESRenderEngine::handleRoundedCorners(const DisplaySettings& display, // Firstly, we need to convert the coordination from layer native coordination space to // device coordination space. + // TODO(143929254): Verify that this transformation is correct const auto transformMatrix = display.globalTransform * layer.geometry.positionTransform; const vec4 leftTopCoordinate(bounds.left, bounds.top, 1.0, 1.0); const vec4 rightBottomCoordinate(bounds.right, bounds.bottom, 1.0, 1.0); @@ -1015,8 +1016,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, setOutputDataSpace(display.outputDataspace); setDisplayMaxLuminance(display.maxLuminance); - mat4 projectionMatrix = mState.projectionMatrix * display.globalTransform; - mState.projectionMatrix = projectionMatrix; + const mat4 projectionMatrix = + ui::Transform(display.orientation).asMatrix4() * mState.projectionMatrix; if (!display.clearRegion.isEmpty()) { glDisable(GL_BLEND); fillRegionWithColor(display.clearRegion, 0.0, 0.0, 0.0, 1.0); diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h index c4a29a9c51..c0766ab5b3 100644 --- a/libs/renderengine/include/renderengine/DisplaySettings.h +++ b/libs/renderengine/include/renderengine/DisplaySettings.h @@ -41,6 +41,13 @@ struct DisplaySettings { Rect clip = Rect::INVALID_RECT; // Global transform to apply to all layers. + // The global transform is assumed to automatically apply when projecting + // the clip rectangle onto the physical display; however, this should be + // explicitly provided to perform CPU-side optimizations such as computing + // scissor rectangles for rounded corners which require transformation to + // the phsical display space. + // + // This transform is also assumed to include the orientation flag below. mat4 globalTransform = mat4(); // Maximum luminance pulled from the display's HDR capabilities. @@ -60,7 +67,10 @@ struct DisplaySettings { // rendered layers. Region clearRegion = Region::INVALID_REGION; - // The orientation of the physical display. + // An additional orientation flag to be applied after clipping the output. + // By way of example, this may be used for supporting fullscreen screenshot + // capture of a device in landscape while the buffer is in portrait + // orientation. uint32_t orientation = ui::Transform::ROT_0; }; diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index afcbc50584..ce9131d890 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -298,7 +298,7 @@ struct RenderEngineTest : public ::testing::Test { void fillBufferPhysicalOffset(); template <typename SourceVariant> - void fillBufferCheckers(mat4 transform); + void fillBufferCheckers(uint32_t rotation); template <typename SourceVariant> void fillBufferCheckersRotate0(); @@ -509,12 +509,12 @@ void RenderEngineTest::fillBufferPhysicalOffset() { } template <typename SourceVariant> -void RenderEngineTest::fillBufferCheckers(mat4 transform) { +void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) { renderengine::DisplaySettings settings; settings.physicalDisplay = fullscreenRect(); // Here logical space is 2x2 settings.clip = Rect(2, 2); - settings.globalTransform = transform; + settings.orientation = orientationFlag; std::vector<const renderengine::LayerSettings*> layers; @@ -545,7 +545,7 @@ void RenderEngineTest::fillBufferCheckers(mat4 transform) { template <typename SourceVariant> void RenderEngineTest::fillBufferCheckersRotate0() { - fillBufferCheckers<SourceVariant>(mat4()); + fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0); expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH, @@ -561,8 +561,7 @@ void RenderEngineTest::fillBufferCheckersRotate0() { template <typename SourceVariant> void RenderEngineTest::fillBufferCheckersRotate90() { - mat4 matrix = mat4(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1); - fillBufferCheckers<SourceVariant>(matrix); + fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90); expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0, 255); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH, @@ -578,8 +577,7 @@ void RenderEngineTest::fillBufferCheckersRotate90() { template <typename SourceVariant> void RenderEngineTest::fillBufferCheckersRotate180() { - mat4 matrix = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 2, 2, 0, 1); - fillBufferCheckers<SourceVariant>(matrix); + fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180); expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH, @@ -595,8 +593,7 @@ void RenderEngineTest::fillBufferCheckersRotate180() { template <typename SourceVariant> void RenderEngineTest::fillBufferCheckersRotate270() { - mat4 matrix = mat4(0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1); - fillBufferCheckers<SourceVariant>(matrix); + fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270); expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255, 255); expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH, @@ -928,7 +925,7 @@ void RenderEngineTest::clearLeftRegion() { // Here logical space is 4x4 settings.clip = Rect(4, 4); settings.globalTransform = mat4::scale(vec4(2, 4, 0, 1)); - settings.clearRegion = Region(Rect(1, 1)); + settings.clearRegion = Region(Rect(2, 4)); std::vector<const renderengine::LayerSettings*> layers; // dummy layer, without bounds should not render anything renderengine::LayerSettings layer; diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index a32bc2b6ce..5f90566df2 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -618,6 +618,39 @@ bool BufferLayer::needsFiltering(const sp<const DisplayDevice>& displayDevice) c sourceCrop.getWidth() != displayFrame.getWidth(); } +bool BufferLayer::needsFilteringForScreenshots(const sp<const DisplayDevice>& displayDevice, + const ui::Transform& inverseParentTransform) const { + // If we are not capturing based on the state of a known display device, + // just return false. + if (displayDevice == nullptr) { + return false; + } + + const auto outputLayer = findOutputLayerForDisplay(displayDevice); + if (outputLayer == nullptr) { + return false; + } + + // We need filtering if the sourceCrop rectangle size does not match the + // viewport rectangle size (not a 1:1 render) + const auto& compositionState = outputLayer->getState(); + const ui::Transform& displayTransform = displayDevice->getTransform(); + const ui::Transform inverseTransform = inverseParentTransform * displayTransform.inverse(); + // Undo the transformation of the displayFrame so that we're back into + // layer-stack space. + const Rect frame = inverseTransform.transform(compositionState.displayFrame); + const FloatRect sourceCrop = compositionState.sourceCrop; + + int32_t frameHeight = frame.getHeight(); + int32_t frameWidth = frame.getWidth(); + // If the display transform had a rotational component then undo the + // rotation so that the orientation matches the source crop. + if (displayTransform.getOrientation() & ui::Transform::ROT_90) { + std::swap(frameHeight, frameWidth); + } + return sourceCrop.getHeight() != frameHeight || sourceCrop.getWidth() != frameWidth; +} + uint64_t BufferLayer::getHeadFrameNumber(nsecs_t expectedPresentTime) const { if (hasFrameUpdate()) { return getFrameNumber(expectedPresentTime); diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index fbec6ee9d9..56bab1bbbe 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -208,6 +208,8 @@ protected: private: // Returns true if this layer requires filtering bool needsFiltering(const sp<const DisplayDevice>& displayDevice) const override; + bool needsFilteringForScreenshots(const sp<const DisplayDevice>& displayDevice, + const ui::Transform& inverseParentTransform) const override; // BufferStateLayers can return Rect::INVALID_RECT if the layer does not have a display frame // and its parent layer is not bounded diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index b72214d307..b81eb181ae 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -220,13 +220,11 @@ void DisplayDevice::setProjection(ui::Rotation orientation, Rect viewport, Rect const bool needsFiltering = (!globalTransform.preserveRects() || (type >= ui::Transform::SCALE)); - Rect sourceClip = globalTransform.transform(viewport); - if (sourceClip.isEmpty()) { - sourceClip = displayBounds; + const Rect& sourceClip = viewport; + Rect destinationClip = globalTransform.transform(viewport); + if (destinationClip.isEmpty()) { + destinationClip = displayBounds; } - // For normal display use we always set the source and destination clip - // rectangles to the same values. - const Rect& destinationClip = sourceClip; uint32_t transformOrientation; diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 397fedcb88..e670d78126 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -244,14 +244,12 @@ public: uint32_t reqHeight, ui::Dataspace reqDataSpace, RotationFlags rotation, bool allowSecureLayers = true) : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace, - display->getViewport(), - applyInversePhysicalOrientation(rotation, - display->getPhysicalOrientation())), + display->getViewport(), applyDeviceOrientation(rotation, display)), mDisplay(std::move(display)), mSourceCrop(sourceCrop), mAllowSecureLayers(allowSecureLayers) {} - const ui::Transform& getTransform() const override { return mDisplay->getTransform(); } + const ui::Transform& getTransform() const override { return mTransform; } Rect getBounds() const override { return mDisplay->getBounds(); } int getHeight() const override { return mDisplay->getHeight(); } int getWidth() const override { return mDisplay->getWidth(); } @@ -259,15 +257,9 @@ public: sp<const DisplayDevice> getDisplayDevice() const override { return mDisplay; } bool needsFiltering() const override { - // check if the projection from the logical display to the physical - // display needs filtering - if (mDisplay->needsFiltering()) { - return true; - } - - // check if the projection from the logical render area (i.e., the - // physical display) to the physical render area requires filtering - const Rect sourceCrop = getSourceCrop(); + // check if the projection from the logical render area + // to the physical render area requires filtering + const Rect& sourceCrop = getSourceCrop(); int width = sourceCrop.width(); int height = sourceCrop.height(); if (getRotationFlags() & ui::Transform::ROT_90) { @@ -282,36 +274,44 @@ public: return mDisplay->getSourceClip(); } - // Recompute the device transformation for the source crop. + // If there is a source crop provided then it is assumed that the device + // was in portrait orientation. This may not logically be true, so + // correct for the orientation error by undoing the rotation + + ui::Rotation logicalOrientation = mDisplay->getOrientation(); + if (logicalOrientation == ui::Rotation::Rotation90) { + logicalOrientation = ui::Rotation::Rotation270; + } else if (logicalOrientation == ui::Rotation::Rotation270) { + logicalOrientation = ui::Rotation::Rotation90; + } + + const auto flags = ui::Transform::toRotationFlags(logicalOrientation); + int width = mDisplay->getSourceClip().getWidth(); + int height = mDisplay->getSourceClip().getHeight(); ui::Transform rotation; - ui::Transform translatePhysical; - ui::Transform translateLogical; - ui::Transform scale; - const Rect& viewport = mDisplay->getViewport(); - const Rect& sourceClip = mDisplay->getSourceClip(); - const Rect& frame = mDisplay->getFrame(); - - const auto flags = ui::Transform::toRotationFlags(mDisplay->getPhysicalOrientation()); - rotation.set(flags, getWidth(), getHeight()); - - translateLogical.set(-viewport.left, -viewport.top); - translatePhysical.set(sourceClip.left, sourceClip.top); - scale.set(frame.getWidth() / float(viewport.getWidth()), 0, 0, - frame.getHeight() / float(viewport.getHeight())); - const ui::Transform finalTransform = - rotation * translatePhysical * scale * translateLogical; - return finalTransform.transform(mSourceCrop); + rotation.set(flags, width, height); + return rotation.transform(mSourceCrop); } private: - static RotationFlags applyInversePhysicalOrientation(RotationFlags orientation, - ui::Rotation physicalOrientation) { + static RotationFlags applyDeviceOrientation(RotationFlags orientationFlag, + const sp<const DisplayDevice>& device) { uint32_t inverseRotate90 = 0; uint32_t inverseReflect = 0; - switch (physicalOrientation) { + // Reverse the logical orientation. + ui::Rotation logicalOrientation = device->getOrientation(); + if (logicalOrientation == ui::Rotation::Rotation90) { + logicalOrientation = ui::Rotation::Rotation270; + } else if (logicalOrientation == ui::Rotation::Rotation270) { + logicalOrientation = ui::Rotation::Rotation90; + } + + const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation; + + switch (orientation) { case ui::ROTATION_0: - return orientation; + return orientationFlag; case ui::ROTATION_90: inverseRotate90 = ui::Transform::ROT_90; @@ -327,8 +327,8 @@ private: break; } - const uint32_t rotate90 = orientation & ui::Transform::ROT_90; - uint32_t reflect = orientation & ui::Transform::ROT_180; + const uint32_t rotate90 = orientationFlag & ui::Transform::ROT_90; + uint32_t reflect = orientationFlag & ui::Transform::ROT_180; // Apply reflection for double rotation. if (rotate90 & inverseRotate90) { @@ -342,6 +342,7 @@ private: const sp<const DisplayDevice> mDisplay; const Rect mSourceCrop; const bool mAllowSecureLayers; + const ui::Transform mTransform = ui::Transform(); }; } // namespace android diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index be80f7821f..92ac015005 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -535,6 +535,19 @@ public: } virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; } virtual bool needsFiltering(const sp<const DisplayDevice>&) const { return false; } + // True if this layer requires filtering + // This method is distinct from needsFiltering() in how the filter + // requirement is computed. needsFiltering() compares displayFrame and crop, + // where as this method transforms the displayFrame to layer-stack space + // first. This method should be used if there is no physical display to + // project onto when taking screenshots, as the filtering requirements are + // different. + // If the parent transform needs to be undone when capturing the layer, then + // the inverse parent transform is also required. + virtual bool needsFilteringForScreenshots(const sp<const DisplayDevice>&, + const ui::Transform&) const { + return false; + } // This layer is not a clone, but it's the parent to the cloned hierarchy. The // variable mClonedChild represents the top layer that will be cloned so this diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h index 9b3a9f4309..6b0455ae87 100644 --- a/services/surfaceflinger/RenderArea.h +++ b/services/surfaceflinger/RenderArea.h @@ -61,10 +61,9 @@ public: // render area. It can be larger than the logical render area. It can // also be optionally rotated. // - // Layers are first clipped to the source crop (in addition to being - // clipped to the logical render area already). The source crop and the - // layers are then rotated around the center of the source crop, and - // scaled to the physical render area linearly. + // The source crop is specified in layer space (when rendering a layer and + // its children), or in layer-stack space (when rendering all layers visible + // on the display). virtual Rect getSourceCrop() const = 0; // Returns the rotation of the source crop and the layers. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e22bc61d50..aa0005dfa6 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -5357,7 +5357,6 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken, DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, reqDataspace, renderAreaRotation, captureSecureLayers); - auto traverseLayers = std::bind(&SurfaceFlinger::traverseLayersInDisplay, this, display, std::placeholders::_1); return captureScreenCommon(renderArea, traverseLayers, outBuffer, reqPixelFormat, @@ -5485,10 +5484,7 @@ status_t SurfaceFlinger::captureLayers( mFlinger(flinger), mChildrenOnly(childrenOnly) {} const ui::Transform& getTransform() const override { return mTransform; } - Rect getBounds() const override { - const Layer::State& layerState(mLayer->getDrawingState()); - return mLayer->getBufferSize(layerState); - } + Rect getBounds() const override { return mLayer->getBufferSize(mLayer->getDrawingState()); } int getHeight() const override { return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight(); } @@ -5531,9 +5527,8 @@ status_t SurfaceFlinger::captureLayers( mTransform = mLayer->getTransform().inverse(); drawLayers(); } else { - Rect bounds = getBounds(); - uint32_t w = static_cast<uint32_t>(bounds.getWidth()); - uint32_t h = static_cast<uint32_t>(bounds.getHeight()); + uint32_t w = static_cast<uint32_t>(getWidth()); + uint32_t h = static_cast<uint32_t>(getHeight()); // In the "childrenOnly" case we reparent the children to a screenshot // layer which has no properties set and which does not draw. sp<ContainerLayer> screenshotParentLayer = @@ -5748,9 +5743,9 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, const auto reqWidth = renderArea.getReqWidth(); const auto reqHeight = renderArea.getReqHeight(); - const auto rotation = renderArea.getRotationFlags(); - const auto transform = renderArea.getTransform(); const auto sourceCrop = renderArea.getSourceCrop(); + const auto transform = renderArea.getTransform(); + const auto rotation = renderArea.getRotationFlags(); const auto& displayViewport = renderArea.getDisplayViewport(); renderengine::DisplaySettings clientCompositionDisplay; @@ -5760,55 +5755,8 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, // buffer bounds. clientCompositionDisplay.physicalDisplay = Rect(reqWidth, reqHeight); clientCompositionDisplay.clip = sourceCrop; - clientCompositionDisplay.globalTransform = transform.asMatrix4(); - - // Now take into account the rotation flag. We append a transform that - // rotates the layer stack about the origin, then translate by buffer - // boundaries to be in the right quadrant. - mat4 rotMatrix; - int displacementX = 0; - int displacementY = 0; - float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f; - switch (rotation) { - case ui::Transform::ROT_90: - rotMatrix = mat4::rotate(rot90InRadians, vec3(0, 0, 1)); - displacementX = renderArea.getBounds().getHeight(); - break; - case ui::Transform::ROT_180: - rotMatrix = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1)); - displacementY = renderArea.getBounds().getWidth(); - displacementX = renderArea.getBounds().getHeight(); - break; - case ui::Transform::ROT_270: - rotMatrix = mat4::rotate(rot90InRadians * 3.0f, vec3(0, 0, 1)); - displacementY = renderArea.getBounds().getWidth(); - break; - default: - break; - } - - // We need to transform the clipping window into the right spot. - // First, rotate the clipping rectangle by the rotation hint to get the - // right orientation - const vec4 clipTL = vec4(sourceCrop.left, sourceCrop.top, 0, 1); - const vec4 clipBR = vec4(sourceCrop.right, sourceCrop.bottom, 0, 1); - const vec4 rotClipTL = rotMatrix * clipTL; - const vec4 rotClipBR = rotMatrix * clipBR; - const int newClipLeft = std::min(rotClipTL[0], rotClipBR[0]); - const int newClipTop = std::min(rotClipTL[1], rotClipBR[1]); - const int newClipRight = std::max(rotClipTL[0], rotClipBR[0]); - const int newClipBottom = std::max(rotClipTL[1], rotClipBR[1]); - - // Now reposition the clipping rectangle with the displacement vector - // computed above. - const mat4 displacementMat = mat4::translate(vec4(displacementX, displacementY, 0, 1)); - clientCompositionDisplay.clip = - Rect(newClipLeft + displacementX, newClipTop + displacementY, - newClipRight + displacementX, newClipBottom + displacementY); - - mat4 clipTransform = displacementMat * rotMatrix; - clientCompositionDisplay.globalTransform = - clipTransform * clientCompositionDisplay.globalTransform; + clientCompositionDisplay.globalTransform = mat4(); + clientCompositionDisplay.orientation = rotation; clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace(); clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance; @@ -5818,7 +5766,8 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, compositionengine::LayerFE::LayerSettings fillLayer; fillLayer.source.buffer.buffer = nullptr; fillLayer.source.solidColor = half3(0.0, 0.0, 0.0); - fillLayer.geometry.boundaries = FloatRect(0.0, 0.0, 1.0, 1.0); + fillLayer.geometry.boundaries = + FloatRect(sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom); fillLayer.alpha = half(alpha); clientCompositionLayers.push_back(fillLayer); @@ -5830,7 +5779,8 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{ clip, useIdentityTransform, - layer->needsFiltering(renderArea.getDisplayDevice()) || renderArea.needsFiltering(), + layer->needsFilteringForScreenshots(renderArea.getDisplayDevice(), transform) || + renderArea.needsFiltering(), renderArea.isSecure(), supportProtectedContent, clearRegion, @@ -5842,6 +5792,10 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, std::vector<compositionengine::LayerFE::LayerSettings> results = layer->prepareClientCompositionList(targetSettings); if (results.size() > 0) { + for (auto& settings : results) { + settings.geometry.positionTransform = + transform.asMatrix4() * settings.geometry.positionTransform; + } clientCompositionLayers.insert(clientCompositionLayers.end(), std::make_move_iterator(results.begin()), std::make_move_iterator(results.end())); diff --git a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp index f8a5b4094d..06e8761d43 100644 --- a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp +++ b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp @@ -104,7 +104,7 @@ TEST_F(MultiDisplayLayerBoundsTest, RenderLayerInVirtualDisplay) { // Verify color layer renders correctly on virtual display. ScreenCapture::captureScreen(&sc, mVirtualDisplay); sc->expectColor(Rect(10, 10, 40, 50), mExpectedColor); - sc->expectColor(Rect(1, 1, 9, 9), {0, 0, 0, 0}); + sc->expectColor(Rect(1, 1, 9, 9), {0, 0, 0, 255}); } TEST_F(MultiDisplayLayerBoundsTest, RenderLayerInMirroredVirtualDisplay) { diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp index 24eeac70a4..ea3d744930 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp @@ -1504,7 +1504,7 @@ public: mHardwareDisplaySize.height), compositionState.transform); EXPECT_EQ(TRANSFORM_FLAGS_ROT_90, compositionState.orientation); - EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip); + EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip); EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip); // For 90, the frame and viewport have the hardware display size width and height swapped EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame); @@ -1531,7 +1531,7 @@ public: mHardwareDisplaySize.height), compositionState.transform); EXPECT_EQ(TRANSFORM_FLAGS_ROT_270, compositionState.orientation); - EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip); + EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip); EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip); // For 270, the frame and viewport have the hardware display size width and height swapped EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame); |