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

Commit 6affbdb9 authored by Paul Ramirez's avatar Paul Ramirez
Browse files

Update Resampler_test.cpp to consider RESAMPLE_LATENCY

Updated Resampler_test.cpp to consider RESAMPLE_LATENCY because the
parameter was unused in Resampler.cpp

Bug: 297226446
Flag: EXEMPT refactor
Test: TEST=libinput_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST --gtest_filter="ResamplerTest*"
Change-Id: I965264e88bede4be74025f61bcd4ef8d235dc4c8
parent e2bb1873
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@ struct Resampler {
    virtual ~Resampler() = default;

    /**
     * Tries to resample motionEvent at resampleTime. The provided resampleTime must be greater than
     * Tries to resample motionEvent at frameTime. The provided frameTime must be greater than
     * the latest sample time of motionEvent. It is not guaranteed that resampling occurs at
     * resampleTime. Interpolation may occur is futureSample is available. Otherwise, motionEvent
     * frameTime. Interpolation may occur is futureSample is available. Otherwise, motionEvent
     * may be resampled by another method, or not resampled at all. Furthermore, it is the
     * implementer's responsibility to guarantee the following:
     * - If resampling occurs, a single additional sample should be added to motionEvent. That is,
@@ -45,15 +45,14 @@ struct Resampler {
     * samples by the end of the resampling. No other field of motionEvent should be modified.
     * - If resampling does not occur, then motionEvent must not be modified in any way.
     */
    virtual void resampleMotionEvent(std::chrono::nanoseconds resampleTime,
                                     MotionEvent& motionEvent,
    virtual void resampleMotionEvent(std::chrono::nanoseconds frameTime, MotionEvent& motionEvent,
                                     const InputMessage* futureSample) = 0;
};

class LegacyResampler final : public Resampler {
public:
    /**
     * Tries to resample `motionEvent` at `resampleTime` by adding a resampled sample at the end of
     * Tries to resample `motionEvent` at `frameTime` by adding a resampled sample at the end of
     * `motionEvent` with eventTime equal to `resampleTime` and pointer coordinates determined by
     * linear interpolation or linear extrapolation. An earlier `resampleTime` will be used if
     * extrapolation takes place and `resampleTime` is too far in the future. If `futureSample` is
@@ -61,7 +60,7 @@ public:
     * data, LegacyResampler will extrapolate. Otherwise, no resampling takes place and
     * `motionEvent` is unmodified.
     */
    void resampleMotionEvent(std::chrono::nanoseconds resampleTime, MotionEvent& motionEvent,
    void resampleMotionEvent(std::chrono::nanoseconds frameTime, MotionEvent& motionEvent,
                             const InputMessage* futureSample) override;

private:
+3 −1
Original line number Diff line number Diff line
@@ -241,13 +241,15 @@ inline void LegacyResampler::addSampleToMotionEvent(const Sample& sample,
                          motionEvent.getId());
}

void LegacyResampler::resampleMotionEvent(nanoseconds resampleTime, MotionEvent& motionEvent,
void LegacyResampler::resampleMotionEvent(nanoseconds frameTime, MotionEvent& motionEvent,
                                          const InputMessage* futureSample) {
    if (mPreviousDeviceId && *mPreviousDeviceId != motionEvent.getDeviceId()) {
        mLatestSamples.clear();
    }
    mPreviousDeviceId = motionEvent.getDeviceId();

    const nanoseconds resampleTime = frameTime - RESAMPLE_LATENCY;

    updateLatestSamples(motionEvent);

    const std::optional<Sample> sample = (futureSample != nullptr)
+67 −48
Original line number Diff line number Diff line
@@ -120,6 +120,47 @@ InputStream::operator MotionEvent() const {

} // namespace

/**
 * The testing setup assumes an input rate of 200 Hz and a display rate of 60 Hz. This implies that
 * input events are received every 5 milliseconds, while the display consumes batched events every
 * ~16 milliseconds. The resampler's RESAMPLE_LATENCY constant determines the resample time, which
 * is calculated as frameTime - RESAMPLE_LATENCY. resampleTime specifies the time used for
 * resampling. For example, if the desired frame time consumption is ~16 milliseconds, the resample
 * time would be ~11 milliseconds. Consequenly, the last added sample to the motion event has an
 * event time of ~11 milliseconds. Note that there are specific scenarios where resampleMotionEvent
 * is not called with a multiple of ~16 milliseconds. These cases are primarily for data addition
 * or to test other functionalities of the resampler.
 *
 * Coordinates are calculated using linear interpolation (lerp) based on the last two available
 * samples. Linear interpolation is defined as (a + alpha*(b - a)). Let t_b and t_a be the
 * timestamps of samples a and b, respectively. The interpolation factor alpha is calculated as
 * (resampleTime - t_a) / (t_b - t_a). The value of alpha determines whether the resampled
 * coordinates are interpolated or extrapolated. If alpha falls within the semi-closed interval [0,
 * 1), the coordinates are interpolated. If alpha is greater than or equal to 1, the coordinates are
 * extrapolated.
 *
 * The timeline below depics an interpolation scenario
 * -----------------------------------|---------|---------|---------|----------
 *                                   10ms      11ms      15ms      16ms
 *                                   MOVE       |        MOVE       |
 *                                         resampleTime         frameTime
 * Based on the timeline alpha is (11 - 10)/(15 - 10) = 1/5. Thus, coordinates are interpolated.
 *
 * The following timeline portrays an extrapolation scenario
 * -------------------------|---------|---------|-------------------|----------
 *                          5ms      10ms      11ms                16ms
 *                          MOVE     MOVE       |                   |
 *                                         resampleTime         frameTime
 * Likewise, alpha = (11 - 5)/(10 - 5) = 6/5. Hence, coordinates are extrapolated.
 *
 * If a motion event was resampled, the tests will check that the following conditions are satisfied
 * to guarantee resampling correctness:
 * - The motion event metadata must not change.
 * - The number of samples in the motion event must only increment by 1.
 * - The resampled values must be at the end of motion event coordinates.
 * - The rasamples values must be near the hand calculations.
 * - The resampled time must be the most recent one in motion event.
 */
class ResamplerTest : public testing::Test {
protected:
    ResamplerTest() : mResampler(std::make_unique<LegacyResampler>()) {}
@@ -225,7 +266,7 @@ TEST_F(ResamplerTest, NonResampledAxesArePreserved) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    EXPECT_EQ(motionEvent.getTouchMajor(0), TOUCH_MAJOR_VALUE);

@@ -243,7 +284,7 @@ TEST_F(ResamplerTest, SinglePointerNotEnoughDataToResample) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, motionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -270,23 +311,6 @@ TEST_F(ResamplerTest, SinglePointerDifferentDeviceIdBetweenMotionEvents) {
    assertMotionEventIsNotResampled(originalMotionEvent, motionFromSecondDevice);
}

// Increments of 16 ms for display refresh rate
// Increments of 6 ms for input frequency
// Resampling latency is known to be 5 ms
// Therefore, first resampling time will be 11 ms

/**
 * Timeline
 * ----+----------------------+---------+---------+---------+----------
 *     0ms                   10ms      11ms      15ms      16ms
 *    DOWN                   MOVE       |        MSG        |
 *                                  resample              frame
 * Resampling occurs at 11ms. It is possible to interpolate because there is a sample available
 * after the resample time. It is assumed that the InputMessage frequency is 100Hz, and the frame
 * frequency is 60Hz. This means the time between InputMessage samples is 10ms, and the time between
 * frames is ~16ms. Resample time is frameTime - RESAMPLE_LATENCY. The resampled sample must be the
 * last one in the batch to consume.
 */
TEST_F(ResamplerTest, SinglePointerSingleSampleInterpolation) {
    MotionEvent motionEvent =
            InputStream{{InputSample{10ms,
@@ -297,7 +321,7 @@ TEST_F(ResamplerTest, SinglePointerSingleSampleInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.id = 0,
@@ -338,18 +362,13 @@ TEST_F(ResamplerTest, SinglePointerSingleSampleExtrapolation) {

    const MotionEvent originalMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(11ms, secondMotionEvent, nullptr);
    mResampler->resampleMotionEvent(16ms, secondMotionEvent, nullptr);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, secondMotionEvent,
                                              {Pointer{.id = 0,
                                                       .x = 2.2f,
                                                       .y = 4.4f,
                                                       .isResampled = true}});
    // Integrity of the whole motionEvent
    // History size should increment by 1
    // Check if the resampled value is the last one
    // Check if the resampleTime is correct
    // Check if the PointerCoords are consistent with the other computations
}

TEST_F(ResamplerTest, SinglePointerMultipleSampleInterpolation) {
@@ -364,7 +383,7 @@ TEST_F(ResamplerTest, SinglePointerMultipleSampleInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.id = 0,
@@ -382,7 +401,7 @@ TEST_F(ResamplerTest, SinglePointerMultipleSampleExtrapolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, nullptr);
    mResampler->resampleMotionEvent(16ms, motionEvent, nullptr);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.id = 0,
@@ -400,7 +419,7 @@ TEST_F(ResamplerTest, SinglePointerDeltaTooSmallExtrapolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, nullptr);
    mResampler->resampleMotionEvent(16ms, motionEvent, nullptr);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -414,7 +433,7 @@ TEST_F(ResamplerTest, SinglePointerDeltaTooLargeExtrapolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(27ms, motionEvent, nullptr);
    mResampler->resampleMotionEvent(32ms, motionEvent, nullptr);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -428,7 +447,7 @@ TEST_F(ResamplerTest, SinglePointerResampleTimeTooFarExtrapolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(43ms, motionEvent, nullptr);
    mResampler->resampleMotionEvent(48ms, motionEvent, nullptr);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.id = 0,
@@ -451,7 +470,7 @@ TEST_F(ResamplerTest, MultiplePointerSingleSampleInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.x = 2.2f, .y = 2.2f, .isResampled = true},
@@ -475,7 +494,7 @@ TEST_F(ResamplerTest, MultiplePointerSingleSampleExtrapolation) {

    const MotionEvent originalMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, secondMotionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, secondMotionEvent,
                                              {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
@@ -498,7 +517,7 @@ TEST_F(ResamplerTest, MultiplePointerMultipleSampleInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
@@ -517,7 +536,7 @@ TEST_F(ResamplerTest, MultiplePointerMultipleSampleExtrapolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, motionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
@@ -539,7 +558,7 @@ TEST_F(ResamplerTest, MultiplePointerIncreaseNumPointersInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
                                              {Pointer{.x = 1.4f, .y = 1.4f, .isResampled = true},
@@ -560,7 +579,7 @@ TEST_F(ResamplerTest, MultiplePointerIncreaseNumPointersInterpolation) {

    const MotionEvent originalSecondMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(27ms, secondMotionEvent, &secondFutureSample);
    mResampler->resampleMotionEvent(32ms, secondMotionEvent, &secondFutureSample);

    assertMotionEventIsResampledAndCoordsNear(originalSecondMotionEvent, secondMotionEvent,
                                              {Pointer{.x = 3.8f, .y = 3.8f, .isResampled = true},
@@ -586,7 +605,7 @@ TEST_F(ResamplerTest, MultiplePointerIncreaseNumPointersExtrapolation) {

    const MotionEvent secondOriginalMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, secondMotionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
}
@@ -606,7 +625,7 @@ TEST_F(ResamplerTest, MultiplePointerDecreaseNumPointersInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -629,7 +648,7 @@ TEST_F(ResamplerTest, MultiplePointerDecreaseNumPointersExtrapolation) {

    const MotionEvent secondOriginalMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, secondMotionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsResampledAndCoordsNear(secondOriginalMotionEvent, secondMotionEvent,
                                              {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
@@ -650,7 +669,7 @@ TEST_F(ResamplerTest, MultiplePointerDifferentIdOrderInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -672,7 +691,7 @@ TEST_F(ResamplerTest, MultiplePointerDifferentIdOrderExtrapolation) {

    const MotionEvent secondOriginalMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, secondMotionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
}
@@ -691,7 +710,7 @@ TEST_F(ResamplerTest, MultiplePointerDifferentIdsInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -713,7 +732,7 @@ TEST_F(ResamplerTest, MultiplePointerDifferentIdsExtrapolation) {

    const MotionEvent secondOriginalMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, secondMotionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
}
@@ -746,7 +765,7 @@ TEST_F(ResamplerTest, MultiplePointerDifferentToolTypeInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
    mResampler->resampleMotionEvent(16ms, motionEvent, &futureSample);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -782,7 +801,7 @@ TEST_F(ResamplerTest, MultiplePointerDifferentToolTypeExtrapolation) {

    const MotionEvent secondOriginalMotionEvent = secondMotionEvent;

    mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, secondMotionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
}
@@ -815,7 +834,7 @@ TEST_F(ResamplerTest, MultiplePointerShouldNotResampleToolTypeInterpolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, motionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}
@@ -847,7 +866,7 @@ TEST_F(ResamplerTest, MultiplePointerShouldNotResampleToolTypeExtrapolation) {

    const MotionEvent originalMotionEvent = motionEvent;

    mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
    mResampler->resampleMotionEvent(16ms, motionEvent, /*futureSample=*/nullptr);

    assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
}