diff options
13 files changed, 78 insertions, 75 deletions
diff --git a/libs/gralloc/types/include/gralloctypes/Gralloc4.h b/libs/gralloc/types/include/gralloctypes/Gralloc4.h index 5ec4d0df3c..8d12754d79 100644 --- a/libs/gralloc/types/include/gralloctypes/Gralloc4.h +++ b/libs/gralloc/types/include/gralloctypes/Gralloc4.h @@ -25,6 +25,7 @@ #include <aidl/android/hardware/graphics/common/Interlaced.h> #include <aidl/android/hardware/graphics/common/PlaneLayout.h> #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h> +#include <aidl/android/hardware/graphics/common/Rect.h> #include <aidl/android/hardware/graphics/common/Smpte2086.h> #include <aidl/android/hardware/graphics/common/StandardMetadataType.h> #include <aidl/android/hardware/graphics/common/XyColor.h> 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/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp index d8e40593e5..f799ce4cb0 100644 --- a/libs/ui/Gralloc4.cpp +++ b/libs/ui/Gralloc4.cpp @@ -203,7 +203,7 @@ status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, cons std::vector<ui::PlaneLayout> planeLayouts; status_t err = getPlaneLayouts(bufferHandle, &planeLayouts); - if (err != NO_ERROR && !planeLayouts.empty()) { + if (err == NO_ERROR && !planeLayouts.empty()) { if (outBytesPerPixel) { int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits; for (const auto& planeLayout : planeLayouts) { diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp index c3454059aa..308ec5ae13 100644 --- a/services/surfaceflinger/CompositionEngine/src/Display.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp @@ -268,12 +268,9 @@ void Display::chooseCompositionStrategy() { } bool Display::getSkipColorTransform() const { - if (!mId) { - return false; - } - - auto& hwc = getCompositionEngine().getHwComposer(); - return hwc.hasDisplayCapability(*mId, HWC2::DisplayCapability::SkipClientColorTransform); + const auto& hwc = getCompositionEngine().getHwComposer(); + return mId ? hwc.hasDisplayCapability(*mId, HWC2::DisplayCapability::SkipClientColorTransform) + : hwc.hasCapability(HWC2::Capability::SkipClientColorTransform); } bool Display::anyLayersRequireClientComposition() const { 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/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp index 88f2686aca..f73a6f749e 100644 --- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp @@ -681,15 +681,17 @@ TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) { using DisplayGetSkipColorTransformTest = DisplayWithLayersTestCommon; -TEST_F(DisplayGetSkipColorTransformTest, doesNothingIfNonHwcDisplay) { +TEST_F(DisplayGetSkipColorTransformTest, checksCapabilityIfNonHwcDisplay) { + EXPECT_CALL(mHwComposer, hasCapability(HWC2::Capability::SkipClientColorTransform)) + .WillOnce(Return(true)); auto args = getDisplayCreationArgsForNonHWCVirtualDisplay(); auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)}; - EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform()); + EXPECT_TRUE(nonHwcDisplay->getSkipColorTransform()); } -TEST_F(DisplayGetSkipColorTransformTest, checksHwcCapability) { +TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) { EXPECT_CALL(mHwComposer, - hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID), + hasDisplayCapability(DEFAULT_DISPLAY_ID, HWC2::DisplayCapability::SkipClientColorTransform)) .WillOnce(Return(true)); EXPECT_TRUE(mDisplay->getSkipColorTransform()); diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h index 88f664922e..52bd6a1da1 100644 --- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h +++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h @@ -40,8 +40,7 @@ public: MOCK_CONST_METHOD3(getDisplayIdentificationData, bool(hwc2_display_t, uint8_t*, DisplayIdentificationData*)); MOCK_CONST_METHOD1(hasCapability, bool(HWC2::Capability)); - MOCK_CONST_METHOD2(hasDisplayCapability, - bool(const std::optional<DisplayId>&, HWC2::DisplayCapability)); + MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, HWC2::DisplayCapability)); MOCK_METHOD3(allocateVirtualDisplay, std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*)); 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/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 560299a0f3..f30d6629fc 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -190,17 +190,10 @@ bool HWComposer::hasCapability(HWC2::Capability capability) const { return mCapabilities.count(capability) > 0; } -bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId, +bool HWComposer::hasDisplayCapability(DisplayId displayId, HWC2::DisplayCapability capability) const { - if (!displayId) { - // Checkout global capabilities for displays without a corresponding HWC display. - if (capability == HWC2::DisplayCapability::SkipClientColorTransform) { - return hasCapability(HWC2::Capability::SkipClientColorTransform); - } - return false; - } - RETURN_IF_INVALID_DISPLAY(*displayId, false); - return mDisplayData.at(*displayId).hwcDisplay->getCapabilities().count(capability) > 0; + RETURN_IF_INVALID_DISPLAY(displayId, false); + return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0; } std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hwc2_display_t hwcDisplayId, diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 3cb40b1ac1..e18419a8e4 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -70,7 +70,7 @@ public: DisplayIdentificationData* outData) const = 0; virtual bool hasCapability(HWC2::Capability capability) const = 0; - virtual bool hasDisplayCapability(const std::optional<DisplayId>& displayId, + virtual bool hasDisplayCapability(DisplayId displayId, HWC2::DisplayCapability capability) const = 0; // Attempts to allocate a virtual display and returns its ID if created on the HWC device. @@ -234,7 +234,7 @@ public: DisplayIdentificationData* outData) const override; bool hasCapability(HWC2::Capability capability) const override; - bool hasDisplayCapability(const std::optional<DisplayId>& displayId, + bool hasDisplayCapability(DisplayId displayId, HWC2::DisplayCapability capability) const override; // Attempts to allocate a virtual display and returns its ID if created on the HWC device. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 952edb4a48..29793228f8 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1217,7 +1217,7 @@ status_t SurfaceFlinger::getAutoLowLatencyModeSupport(const sp<IBinder>& display displayToken.get()); return NAME_NOT_FOUND; } - *outSupport = getHwComposer().hasDisplayCapability(displayId, + *outSupport = getHwComposer().hasDisplayCapability(*displayId, HWC2::DisplayCapability::AutoLowLatencyMode); return NO_ERROR; } @@ -1488,7 +1488,7 @@ status_t SurfaceFlinger::getDisplayBrightnessSupport(const sp<IBinder>& displayT return NAME_NOT_FOUND; } *outSupport = - getHwComposer().hasDisplayCapability(displayId, HWC2::DisplayCapability::Brightness); + getHwComposer().hasDisplayCapability(*displayId, HWC2::DisplayCapability::Brightness); return NO_ERROR; } @@ -5756,7 +5756,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(); |