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

Commit 0909dc1c authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

MotionEvent: Round coordinates to a precision of 0.001

When tests inject input events at a location on the screen, the
dispatched event is expected to have the same coordinates. However, on
scaled devices, this may not always be the case due to precision losses
incurred through floating point arithmetics. For example, it was
possible for an injected event with a coordinate of 1.0 to end up with
a value of 0.9997.

To combat this issue, we will round transformed axis values that are
leaving a MotionEvent to a precision of 0.001. After this CL, even if
the injection process results in precision losses, they should be
overcome by rounding, assuming injection does not require greater
precision.

This will solve the issue where input injected to an inclusive edge of
the View bounds was not getting dispatched to the View due to precision
losses.

Bug: 264978231
Bug: 260965930
Test: atest libinput_tests
Test: atest inputflinger_tests
Test: atest HoverTest (with screen size override)
Change-Id: I81062597058361a1218e6873d34b9b0d2fbfad96
Merged-In: I81062597058361a1218e6873d34b9b0d2fbfad96
parent 51b7ac6e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -816,6 +816,8 @@ public:
                                               const PointerCoords&);
    static PointerCoords calculateTransformedCoords(uint32_t source, const ui::Transform&,
                                                    const PointerCoords&);
    // The rounding precision for transformed motion events.
    static constexpr float ROUNDING_PRECISION = 0.001f;

protected:
    int32_t mAction;
+17 −4
Original line number Diff line number Diff line
@@ -117,10 +117,23 @@ int32_t IdGenerator::nextId() const {

// --- InputEvent ---

// Due to precision limitations when working with floating points, transforming - namely
// scaling - floating points can lead to minute errors. We round transformed values to approximately
// three decimal places so that values like 0.99997 show up as 1.0.
inline float roundTransformedCoords(float val) {
    // Use a power to two to approximate three decimal places to potentially reduce some cycles.
    // This should be at least as precise as MotionEvent::ROUNDING_PRECISION.
    return std::round(val * 1024.f) / 1024.f;
}

inline vec2 roundTransformedCoords(vec2 p) {
    return {roundTransformedCoords(p.x), roundTransformedCoords(p.y)};
}

vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy) {
    const vec2 transformedXy = transform.transform(xy);
    const vec2 transformedOrigin = transform.transform(0, 0);
    return transformedXy - transformedOrigin;
    return roundTransformedCoords(transformedXy - transformedOrigin);
}

const char* inputEventTypeToString(int32_t type) {
@@ -528,12 +541,12 @@ int MotionEvent::getSurfaceRotation() const {

float MotionEvent::getXCursorPosition() const {
    vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
    return vals.x;
    return roundTransformedCoords(vals.x);
}

float MotionEvent::getYCursorPosition() const {
    vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition());
    return vals.y;
    return roundTransformedCoords(vals.y);
}

void MotionEvent::setCursorPosition(float x, float y) {
@@ -855,7 +868,7 @@ std::string MotionEvent::actionToString(int32_t action) {
static inline vec2 calculateTransformedXYUnchecked(uint32_t source, const ui::Transform& transform,
                                                   const vec2& xy) {
    return shouldDisregardOffset(source) ? transformWithoutTranslation(transform, xy)
                                         : transform.transform(xy);
                                         : roundTransformedCoords(transform.transform(xy));
}

vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& transform,
+192 −126

File changed.

Preview size limit exceeded, changes collapsed.

+12 −8

File changed.

Preview size limit exceeded, changes collapsed.

+4 −4

File changed.

Preview size limit exceeded, changes collapsed.