summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alec Mouri <alecmouri@google.com> 2020-04-06 20:28:16 -0700
committer Alec Mouri <alecmouri@google.com> 2020-04-07 19:53:55 -0700
commitd4bf795effcc3cb719992d03b856ba6dfd34c8b6 (patch)
treee9aff7f2576b58f7497ffaff19b4baa77e653fbf
parent5a6d857f3361f46d58314ff45a074157b2600a92 (diff)
Remove DisplaySettings::globalTransform
The globalTransform can be described entirely in terms of the clip rectangle, physical display projection, and orientation, so the extra field isn't needed. We only need it when handling rounded corners so compute the transform there. Bug: 137209275 Bug: 143929254 Test: slow swipe to recents to visually check rounded corners Test: adb screencap during animations Test: above tests in portrait and landscape orientation Test: librenderengine_test Change-Id: I05f63cc6ccbe7403fe158c86a8a3db5bf932e812
-rw-r--r--libs/renderengine/gl/GLESRenderEngine.cpp67
-rw-r--r--libs/renderengine/include/renderengine/DisplaySettings.h18
-rw-r--r--libs/renderengine/tests/RenderEngineTest.cpp1
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp1
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp19
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp1
6 files changed, 59 insertions, 48 deletions
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index d56a82f4d7..36a54a7464 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -793,35 +793,66 @@ void GLESRenderEngine::handleRoundedCorners(const DisplaySettings& display,
// top rectangle and the bottom rectangle, and turn off blending for the middle rectangle.
FloatRect bounds = layer.geometry.roundedCornersCrop;
- // 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);
- const vec4 leftTopCoordinateInBuffer = transformMatrix * leftTopCoordinate;
- const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate;
- bounds = FloatRect(leftTopCoordinateInBuffer[0], leftTopCoordinateInBuffer[1],
- rightBottomCoordinateInBuffer[0], rightBottomCoordinateInBuffer[1]);
-
- // Secondly, if the display is rotated, we need to undo the rotation on coordination and
- // align the (left, top) and (right, bottom) coordination with the device coordination
- // space.
+ // Explicitly compute the transform from the clip rectangle to the physical
+ // display. Normally, this is done in glViewport but we explicitly compute
+ // it here so that we can get the scissor bounds correct.
+ const Rect& source = display.clip;
+ const Rect& destination = display.physicalDisplay;
+ // Here we compute the following transform:
+ // 1. Translate the top left corner of the source clip to (0, 0)
+ // 2. Rotate the clip rectangle about the origin in accordance with the
+ // orientation flag
+ // 3. Translate the top left corner back to the origin.
+ // 4. Scale the clip rectangle to the destination rectangle dimensions
+ // 5. Translate the top left corner to the destination rectangle's top left
+ // corner.
+ const mat4 translateSource = mat4::translate(vec4(-source.left, -source.top, 0, 1));
+ mat4 rotation;
+ int displacementX = 0;
+ int displacementY = 0;
+ float destinationWidth = static_cast<float>(destination.getWidth());
+ float destinationHeight = static_cast<float>(destination.getHeight());
+ float sourceWidth = static_cast<float>(source.getWidth());
+ float sourceHeight = static_cast<float>(source.getHeight());
+ const float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
switch (display.orientation) {
case ui::Transform::ROT_90:
- std::swap(bounds.left, bounds.right);
+ rotation = mat4::rotate(rot90InRadians, vec3(0, 0, 1));
+ displacementX = source.getHeight();
+ std::swap(sourceHeight, sourceWidth);
break;
case ui::Transform::ROT_180:
- std::swap(bounds.left, bounds.right);
- std::swap(bounds.top, bounds.bottom);
+ rotation = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1));
+ displacementY = source.getHeight();
+ displacementX = source.getWidth();
break;
case ui::Transform::ROT_270:
- std::swap(bounds.top, bounds.bottom);
+ rotation = mat4::rotate(rot90InRadians * 3.0f, vec3(0, 0, 1));
+ displacementY = source.getWidth();
+ std::swap(sourceHeight, sourceWidth);
break;
default:
break;
}
+ const mat4 intermediateTranslation = mat4::translate(vec4(displacementX, displacementY, 0, 1));
+ const mat4 scale = mat4::scale(
+ vec4(destinationWidth / sourceWidth, destinationHeight / sourceHeight, 1, 1));
+ const mat4 translateDestination =
+ mat4::translate(vec4(destination.left, destination.top, 0, 1));
+ const mat4 globalTransform =
+ translateDestination * scale * intermediateTranslation * rotation * translateSource;
+
+ const mat4 transformMatrix = 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);
+ const vec4 leftTopCoordinateInBuffer = transformMatrix * leftTopCoordinate;
+ const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate;
+ bounds = FloatRect(std::min(leftTopCoordinateInBuffer[0], rightBottomCoordinateInBuffer[0]),
+ std::min(leftTopCoordinateInBuffer[1], rightBottomCoordinateInBuffer[1]),
+ std::max(leftTopCoordinateInBuffer[0], rightBottomCoordinateInBuffer[0]),
+ std::max(leftTopCoordinateInBuffer[1], rightBottomCoordinateInBuffer[1]));
+
// Finally, we cut the layer into 3 parts, with top and bottom parts having rounded corners
// and the middle part without rounded corners.
const int32_t radius = ceil(layer.geometry.roundedCornersRadius);
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index c0766ab5b3..ca16d2c727 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -40,16 +40,6 @@ struct DisplaySettings {
// z=1.
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.
float maxLuminance = 1.0f;
@@ -62,9 +52,7 @@ struct DisplaySettings {
mat4 colorTransform = mat4();
// Region that will be cleared to (0, 0, 0, 1) prior to rendering.
- // RenderEngine will transform the clearRegion passed in here, by
- // globalTransform, so that it will be in the same coordinate space as the
- // rendered layers.
+ // This is specified in layer-stack space.
Region clearRegion = Region::INVALID_REGION;
// An additional orientation flag to be applied after clipping the output.
@@ -76,8 +64,7 @@ struct DisplaySettings {
static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
return lhs.physicalDisplay == rhs.physicalDisplay && lhs.clip == rhs.clip &&
- lhs.globalTransform == rhs.globalTransform && lhs.maxLuminance == rhs.maxLuminance &&
- lhs.outputDataspace == rhs.outputDataspace &&
+ lhs.maxLuminance == rhs.maxLuminance && lhs.outputDataspace == rhs.outputDataspace &&
lhs.colorTransform == rhs.colorTransform &&
lhs.clearRegion.hasSameRects(rhs.clearRegion) && lhs.orientation == rhs.orientation;
}
@@ -89,7 +76,6 @@ static inline void PrintTo(const DisplaySettings& settings, ::std::ostream* os)
PrintTo(settings.physicalDisplay, os);
*os << "\n .clip = ";
PrintTo(settings.clip, os);
- *os << "\n .globalTransform = " << settings.globalTransform;
*os << "\n .maxLuminance = " << settings.maxLuminance;
*os << "\n .outputDataspace = ";
PrintTo(settings.outputDataspace, os);
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index ce9131d890..f5bf014db1 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -924,7 +924,6 @@ void RenderEngineTest::clearLeftRegion() {
settings.physicalDisplay = fullscreenRect();
// Here logical space is 4x4
settings.clip = Rect(4, 4);
- settings.globalTransform = mat4::scale(vec4(2, 4, 0, 1));
settings.clearRegion = Region(Rect(2, 4));
std::vector<const renderengine::LayerSettings*> layers;
// dummy layer, without bounds should not render anything
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 248933e8f0..34d0cb2b67 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -829,7 +829,6 @@ std::optional<base::unique_fd> Output::composeSurfaces(
renderengine::DisplaySettings clientCompositionDisplay;
clientCompositionDisplay.physicalDisplay = outputState.destinationClip;
clientCompositionDisplay.clip = outputState.sourceClip;
- clientCompositionDisplay.globalTransform = outputState.transform.asMatrix4();
clientCompositionDisplay.orientation = outputState.orientation;
clientCompositionDisplay.outputDataspace = mDisplayColorProfile->hasWideColorGamut()
? outputState.dataspace
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 63bb459dbe..1c9cd9c0c0 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3100,9 +3100,8 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposi
.andIfUsesHdr(true)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
- mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
- mat4(), Region::INVALID_REGION,
- kDefaultOutputOrientation})
+ kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+ Region::INVALID_REGION, kDefaultOutputOrientation})
.execute()
.expectAFenceWasReturned();
}
@@ -3112,9 +3111,8 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComp
.andIfUsesHdr(false)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
- mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
- mat4(), Region::INVALID_REGION,
- kDefaultOutputOrientation})
+ kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+ Region::INVALID_REGION, kDefaultOutputOrientation})
.execute()
.expectAFenceWasReturned();
}
@@ -3124,7 +3122,7 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientCo
.andIfUsesHdr(true)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
- mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
+ kDefaultMaxLuminance, kDefaultOutputDataspace,
kDefaultColorTransformMat, Region::INVALID_REGION,
kDefaultOutputOrientation})
.execute()
@@ -3136,7 +3134,7 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClien
.andIfUsesHdr(false)
.andIfSkipColorTransform(false)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
- mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
+ kDefaultMaxLuminance, kDefaultOutputDataspace,
kDefaultColorTransformMat, Region::INVALID_REGION,
kDefaultOutputOrientation})
.execute()
@@ -3149,9 +3147,8 @@ TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
.andIfUsesHdr(true)
.andIfSkipColorTransform(true)
.thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
- mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
- mat4(), Region::INVALID_REGION,
- kDefaultOutputOrientation})
+ kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+ Region::INVALID_REGION, kDefaultOutputOrientation})
.execute()
.expectAFenceWasReturned();
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index aa0005dfa6..060185bc87 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5755,7 +5755,6 @@ void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
// buffer bounds.
clientCompositionDisplay.physicalDisplay = Rect(reqWidth, reqHeight);
clientCompositionDisplay.clip = sourceCrop;
- clientCompositionDisplay.globalTransform = mat4();
clientCompositionDisplay.orientation = rotation;
clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace();