Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68933fb8 authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

[CE] Extract transform computation logic to ProjectionSpace

The logic that computes the transformation matrix that maps
from one projection space to another currently lives in
DisplayDevice::setProjection although it's not specific to
the DisplayDevice. In this CL we move this to ProjectionSpace
so it can be reused and add appropriate testing. Additionally
we move most of the remaining logic from DisplayDevice::setProjection
to Output::setProjection.

Bug: 161793589
Bug: 165184567
Test: atest ProjectionSpaceTest
Test: atest libcompositionengine_test libsurfaceflinger_unittest
Test: on phone emualutor test that rotation works propertly
Change-Id: Ic65a3ba18eda597edb7d2c8635cccfa7cb58a107
parent 9c5aaf72
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ public:
    void dump(std::string& result, const char* name, const char* prefix = "") const;
    void dump(const char* name, const char* prefix = "") const;

    static RotationFlags toRotationFlags(Rotation);
    static constexpr RotationFlags toRotationFlags(Rotation);

private:
    struct mat33 {
@@ -136,7 +136,7 @@ inline void PrintTo(const Transform& t, ::std::ostream* os) {
    *os << out;
}

inline Transform::RotationFlags Transform::toRotationFlags(Rotation rotation) {
inline constexpr Transform::RotationFlags Transform::toRotationFlags(Rotation rotation) {
    switch (rotation) {
        case ROTATION_0:
            return ROT_0;
+2 −1
Original line number Diff line number Diff line
@@ -95,8 +95,9 @@ cc_test {
        "tests/MockHWC2.cpp",
        "tests/MockHWComposer.cpp",
        "tests/MockPowerAdvisor.cpp",
        "tests/OutputTest.cpp",
        "tests/OutputLayerTest.cpp",
        "tests/OutputTest.cpp",
        "tests/ProjectionSpaceTest.cpp",
        "tests/RenderSurfaceTest.cpp",
    ],
    static_libs: [
+2 −3
Original line number Diff line number Diff line
@@ -163,9 +163,8 @@ public:
    virtual void setCompositionEnabled(bool) = 0;

    // Sets the projection state to use
    virtual void setProjection(const ui::Transform&, uint32_t orientation,
                               const Rect& orientedDisplaySpaceRect,
                               const Rect& layerStackSpaceRect, const Rect& displaySpaceRect) = 0;
    virtual void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
                               const Rect& orientedDisplaySpaceRect) = 0;
    // Sets the bounds to use
    virtual void setDisplaySpaceSize(const ui::Size&) = 0;

+62 −3
Original line number Diff line number Diff line
@@ -38,14 +38,73 @@ struct ProjectionSpace {

    // Rect onto which content is projected.
    Rect content;

    // The orientation of this space. This value is meaningful only in relation to the rotation
    // of another projection space and it's used to determine the rotating transformation when
    // mapping between the two.
    // As a convention when using this struct orientation = 0 for the "oriented*" projection
    // spaces. For example when the display is rotated 90 degress counterclockwise, the orientation
    // of the display space will become 90, while  the orientation of the layer stack space will
    // remain the same.
    ui::Rotation orientation = ui::ROTATION_0;

    // Returns a transform which maps this.content into destination.content
    // and also rotates according to this.orientation and destination.orientation
    ui::Transform getTransform(const ProjectionSpace& destination) const {
        ui::Rotation rotation = destination.orientation - orientation;

        // Compute a transformation which rotates the destination in a way it has the same
        // orientation as us.
        const uint32_t inverseRotationFlags = ui::Transform::toRotationFlags(-rotation);
        ui::Transform inverseRotatingTransform;
        inverseRotatingTransform.set(inverseRotationFlags, destination.bounds.width(),
                                     destination.bounds.height());
        // The destination content rotated so it has the same orientation as us.
        Rect orientedDestContent = inverseRotatingTransform.transform(destination.content);

        // Compute translation from the source content to (0, 0).
        const float sourceX = content.left;
        const float sourceY = content.top;
        ui::Transform sourceTranslation;
        sourceTranslation.set(-sourceX, -sourceY);

        // Compute scaling transform which maps source content to destination content, assuming
        // they are both at (0, 0).
        ui::Transform scale;
        const float scaleX = static_cast<float>(orientedDestContent.width()) / content.width();
        const float scaleY = static_cast<float>(orientedDestContent.height()) / content.height();
        scale.set(scaleX, 0, 0, scaleY);

        // Compute translation from (0, 0) to the orientated destination content.
        const float destX = orientedDestContent.left;
        const float destY = orientedDestContent.top;
        ui::Transform destTranslation;
        destTranslation.set(destX, destY);

        // Compute rotation transform.
        const uint32_t orientationFlags = ui::Transform::toRotationFlags(rotation);
        auto orientedDestWidth = destination.bounds.width();
        auto orientedDestHeight = destination.bounds.height();
        if (rotation == ui::ROTATION_90 || rotation == ui::ROTATION_270) {
            std::swap(orientedDestWidth, orientedDestHeight);
        }
        ui::Transform rotationTransform;
        rotationTransform.set(orientationFlags, orientedDestWidth, orientedDestHeight);

        // The layerStackSpaceRect and orientedDisplaySpaceRect are both in the logical orientation.
        // Apply the logical translation, scale to physical size, apply the
        // physical translation and finally rotate to the physical orientation.
        return rotationTransform * destTranslation * scale * sourceTranslation;
    }
};

} // namespace compositionengine

inline std::string to_string(const android::compositionengine::ProjectionSpace& space) {
    return android::base::StringPrintf("ProjectionSpace(bounds = %s, content = %s)",
                                       to_string(space.bounds).c_str(),
                                       to_string(space.content).c_str());
    return android::base::
            StringPrintf("ProjectionSpace(bounds = %s, content = %s, orientation = %s)",
                         to_string(space.bounds).c_str(), to_string(space.content).c_str(),
                         toCString(space.orientation));
}

// Defining PrintTo helps with Google Tests.
+2 −3
Original line number Diff line number Diff line
@@ -38,9 +38,8 @@ public:
    bool isValid() const override;
    std::optional<DisplayId> getDisplayId() const override;
    void setCompositionEnabled(bool) override;
    void setProjection(const ui::Transform&, uint32_t orientation,
                       const Rect& orientedDisplaySpaceRect, const Rect& layerStackSpaceRect,
                       const Rect& displaySpaceRect) override;
    void setProjection(ui::Rotation orientation, const Rect& layerStackSpaceRect,
                       const Rect& orientedDisplaySpaceRect) override;
    void setDisplaySpaceSize(const ui::Size&) override;
    void setLayerStackFilter(uint32_t layerStackId, bool isInternal) override;

Loading