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

Commit ae92b74e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes Iada825d7,Iaa056018 into rvc-dev am: 1718db1f am: b240a1e9 am: 16382b59

Change-Id: I758f3752ca3c5045642d409cfdca048bd7387a47
parents 858d9e0c 16382b59
Loading
Loading
Loading
Loading
+52 −15
Original line number Diff line number Diff line
@@ -109,11 +109,11 @@ struct Size {
    // Takes a value of type FromType, and ensures it can be represented as a value of type ToType,
    // clamping the input value to the output range if necessary.
    template <typename ToType, typename FromType>
    static Size::remove_cv_reference_t<ToType> clamp(
            typename std::enable_if<
                    std::numeric_limits<Size::remove_cv_reference_t<ToType>>::is_bounded &&
                            std::numeric_limits<Size::remove_cv_reference_t<FromType>>::is_bounded,
                    FromType&&>::type v) {
    static Size::remove_cv_reference_t<ToType>
    clamp(typename std::enable_if<
            std::numeric_limits<Size::remove_cv_reference_t<ToType>>::is_specialized &&
                    std::numeric_limits<Size::remove_cv_reference_t<FromType>>::is_specialized,
            FromType>::type v) {
        using BareToType = remove_cv_reference_t<ToType>;
        using BareFromType = remove_cv_reference_t<FromType>;
        static constexpr auto toHighest = std::numeric_limits<BareToType>::max();
@@ -121,21 +121,58 @@ struct Size {
        static constexpr auto fromHighest = std::numeric_limits<BareFromType>::max();
        static constexpr auto fromLowest = std::numeric_limits<BareFromType>::lowest();

        // A clamp is needed if the range of FromType is not a subset of the range of ToType
        static constexpr bool isClampNeeded = (toLowest > fromLowest) || (toHighest < fromHighest);
        // Get the closest representation of [toLowest, toHighest] in type
        // FromType to use to clamp the input value before conversion.

        // std::common_type<...> is used to get a value-preserving type for the
        // top end of the range.
        using CommonHighestType = std::common_type_t<BareToType, BareFromType>;

        // std::make_signed<std::common_type<...>> is used to get a
        // value-preserving type for the bottom end of the range, except this is
        // a bit trickier for non-integer types like float.
        using CommonLowestType =
                std::conditional_t<std::numeric_limits<CommonHighestType>::is_integer,
                                   std::make_signed_t<std::conditional_t<
                                           std::numeric_limits<CommonHighestType>::is_integer,
                                           CommonHighestType, int /* not used */>>,
                                   CommonHighestType>;

        // We can then compute the clamp range in a way that can be later
        // trivially converted to either the 'from' or 'to' types, and be
        // representabile in either.
        static constexpr auto commonClampHighest =
                std::min(static_cast<CommonHighestType>(fromHighest),
                         static_cast<CommonHighestType>(toHighest));
        static constexpr auto commonClampLowest =
                std::max(static_cast<CommonLowestType>(fromLowest),
                         static_cast<CommonLowestType>(toLowest));

        static constexpr auto fromClampHighest = static_cast<BareFromType>(commonClampHighest);
        static constexpr auto fromClampLowest = static_cast<BareFromType>(commonClampLowest);

        // A clamp is needed only if the range we are clamping to is not the
        // same as the range of the input.
        static constexpr bool isClampNeeded =
                (fromLowest != fromClampLowest) || (fromHighest != fromClampHighest);

        // If a clamp is not needed, the conversion is just a trivial cast.
        if (!isClampNeeded) {
            return static_cast<ToType>(v);
            return static_cast<BareToType>(v);
        }

        // Otherwise we need to carefully compare the limits of ToType (casted
        // for the comparisons to be warning free to FromType) while still
        // ensuring we return a value clamped to the range of ToType.
        return v < static_cast<const BareFromType>(toLowest)
                ? toLowest
                : (v > static_cast<const BareFromType>(toHighest) ? toHighest
                                                                  : static_cast<ToType>(v));
        // Note: Clang complains about the value of INT32_MAX not being
        // convertible back to int32_t from float if this is made "constexpr",
        // when clamping a float value to an int32_t value. This is however
        // covered by a test case to ensure the run-time cast works correctly.
        const auto toClampHighest = static_cast<BareToType>(commonClampHighest);
        const auto toClampLowest = static_cast<BareToType>(commonClampLowest);

        // Otherwise clamping is done by using the already computed endpoints
        // for each type.
        return (v <= fromClampLowest)
                ? toClampLowest
                : ((v >= fromClampHighest) ? toClampHighest : static_cast<BareToType>(v));
    }
};

+25 −0
Original line number Diff line number Diff line
@@ -186,9 +186,34 @@ TEST(SizeTest, Int8RangeIsNotClamped) {

TEST(SizeTest, FloatRangeIsClamped) {
    ClampTest(std::numeric_limits<float>::max(), std::numeric_limits<int32_t>::max());
    ClampTest(nexttowardf(std::numeric_limits<int32_t>::max(), std::numeric_limits<float>::max()),
              std::numeric_limits<int32_t>::max());
    ClampTest(static_cast<float>(std::numeric_limits<int32_t>::max()),
              std::numeric_limits<int32_t>::max());
    ClampTest(nexttowardf(std::numeric_limits<int32_t>::max(), 0),
              static_cast<int32_t>(nexttowardf(std::numeric_limits<int32_t>::max(), 0)));
    ClampTest(float(0), int32_t(0));
    ClampTest(nexttowardf(std::numeric_limits<int32_t>::lowest(), 0),
              static_cast<int32_t>(nexttowardf(std::numeric_limits<int32_t>::lowest(), 0)));
    ClampTest(static_cast<float>(std::numeric_limits<int32_t>::lowest()),
              std::numeric_limits<int32_t>::lowest());
    ClampTest(nexttowardf(std::numeric_limits<int32_t>::lowest(),
                          std::numeric_limits<float>::lowest()),
              std::numeric_limits<int32_t>::lowest());
    ClampTest(std::numeric_limits<float>::lowest(), std::numeric_limits<int32_t>::lowest());
}

TEST(SizeTest, Uint32RangeIsClamped) {
    ClampTest(std::numeric_limits<uint32_t>::max(), std::numeric_limits<int32_t>::max());
    ClampTest(std::numeric_limits<uint32_t>::max() - 1, std::numeric_limits<int32_t>::max());
    ClampTest(static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) + 1,
              std::numeric_limits<int32_t>::max());
    ClampTest(static_cast<uint32_t>(std::numeric_limits<int32_t>::max()),
              std::numeric_limits<int32_t>::max());
    ClampTest(static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) - 1,
              std::numeric_limits<int32_t>::max() - 1);
    ClampTest(uint32_t(0), int32_t(0));
}

} // namespace ui
} // namespace android
+1 −4
Original line number Diff line number Diff line
@@ -183,10 +183,7 @@ void FramebufferSurface::onFrameCommitted() {
}

ui::Size FramebufferSurface::limitFramebufferSize(uint32_t width, uint32_t height) {
    // TODO(b/149495759): Use the ui::Size constructor once it no longer is broken.
    ui::Size framebufferSize;
    framebufferSize.width = width;
    framebufferSize.height = height;
    ui::Size framebufferSize(width, height);
    bool wasLimited = true;
    if (width > mMaxWidth && mMaxWidth != 0) {
        float aspectRatio = float(width) / float(height);