diff options
| author | 2019-03-28 21:42:24 -0700 | |
|---|---|---|
| committer | 2019-04-02 11:14:01 -0700 | |
| commit | adb75f485dbc4c9ff6620f87a4e438d25f573687 (patch) | |
| tree | 21bd865d7e6447f103ad20de990c7b46402cd027 | |
| parent | 945a7006f905b5f460668923b9875cd6637931a6 (diff) | |
Fix the source crop for screenshots for notch hide
* Orientation transform needs to be applied after the device transform
* Source crop needs to have a transform applied to it so that the
clipping window is in the right spot.
Bug: 129362302
Test: screenshots
Change-Id: I675be4d1fb2386f24ead69a77b08bec65d2f5d47
| -rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 28 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 27 |
2 files changed, 35 insertions, 20 deletions
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index c80925ee78..0067b505e3 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -288,16 +288,21 @@ public: } Rect getSourceCrop() const override { - // use the (projected) logical display viewport by default + // use the projected display viewport by default. if (mSourceCrop.isEmpty()) { return mDevice->getScissor(); } - const int orientation = mDevice->getInstallOrientation(); - if (orientation == DisplayState::eOrientationDefault) { - return mSourceCrop; - } + // Recompute the device transformation for the source crop. + ui::Transform rotation; + ui::Transform translatePhysical; + ui::Transform translateLogical; + ui::Transform scale; + const Rect& viewport = mDevice->getViewport(); + const Rect& scissor = mDevice->getScissor(); + const Rect& frame = mDevice->getFrame(); + const int orientation = mDevice->getInstallOrientation(); // Install orientation is transparent to the callers. Apply it now. uint32_t flags = 0x00; switch (orientation) { @@ -310,10 +315,17 @@ public: case DisplayState::eOrientation270: flags = ui::Transform::ROT_270; break; + default: + break; } - ui::Transform tr; - tr.set(flags, getWidth(), getHeight()); - return tr.transform(mSourceCrop); + rotation.set(flags, getWidth(), getHeight()); + translateLogical.set(-viewport.left, -viewport.top); + translatePhysical.set(scissor.left, scissor.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); } private: diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0345bafee6..93a5b57563 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -5671,8 +5671,9 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, const auto reqWidth = renderArea.getReqWidth(); const auto reqHeight = renderArea.getReqHeight(); - const auto sourceCrop = renderArea.getSourceCrop(); const auto rotation = renderArea.getRotationFlags(); + const auto transform = renderArea.getTransform(); + const auto sourceCrop = renderArea.getSourceCrop(); renderengine::DisplaySettings clientCompositionDisplay; std::vector<renderengine::LayerSettings> clientCompositionLayers; @@ -5680,31 +5681,34 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, // assume that bounds are never offset, and that they are the same as the // buffer bounds. clientCompositionDisplay.physicalDisplay = Rect(reqWidth, reqHeight); - ui::Transform transform = renderArea.getTransform(); + 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; - // Displacement for repositioning the clipping rectangle after rotating it - // with the rotation hint. 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 = reqWidth; + displacementX = renderArea.getBounds().getHeight(); break; case ui::Transform::ROT_180: rotMatrix = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1)); - displacementX = reqWidth; - displacementY = reqHeight; + 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 = reqHeight; + 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 @@ -5720,15 +5724,14 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, // 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); - // We need to perform the same transformation in layer space, so propagate - // it to the global transform. mat4 clipTransform = displacementMat * rotMatrix; - clientCompositionDisplay.globalTransform *= clipTransform; + clientCompositionDisplay.globalTransform = + clipTransform * clientCompositionDisplay.globalTransform; + clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace(); clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance; |