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

Commit 0839bd63 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Provide prediction time from the application

After further discussion with the graphics team, it turns out that the
Choreographer isn't the best way to compute the prediction time.

There may be some strategy that would use the Choreographer, like
looking at the last vsync and trying to guess when the next drawing will
occur.

However, for now, let's just provide this time from the application and
experiment with it. If we do need the Choreographer, we should be able
to get this data from libgui here in the native layer, so we don't need
the java to set this time, anyways.

Bug: 167946763
Test: atest libinput_tests inputflinger_tests
Change-Id: I496a9c184745d4cec085b880f913983cc2be9e3f
parent 990ff7ba
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -63,14 +63,10 @@ public:
    MotionPredictor(nsecs_t predictionTimestampOffsetNanos,
                    std::function<bool()> checkEnableMotionPrediction = isMotionPredictionEnabled);
    void record(const MotionEvent& event);
    std::vector<std::unique_ptr<MotionEvent>> predict();
    std::vector<std::unique_ptr<MotionEvent>> predict(nsecs_t timestamp);
    bool isPredictionAvailable(int32_t deviceId, int32_t source);
    void setExpectedPresentationTimeNanos(int64_t expectedPresentationTimeNanos);

private:
    std::mutex mLock;
    int64_t mExpectedPresentationTimeNanos GUARDED_BY(mLock) = 0;
    int64_t getExpectedPresentationTimeNanos();
    std::vector<MotionEvent> mEvents;
    const nsecs_t mPredictionTimestampOffsetNanos;
    const std::function<bool()> mCheckMotionPredictionEnabled;
+2 −12
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ void MotionPredictor::record(const MotionEvent& event) {
 * The returned event should not contain any of the real, existing data. It should only
 * contain the predicted samples.
 */
std::vector<std::unique_ptr<MotionEvent>> MotionPredictor::predict() {
std::vector<std::unique_ptr<MotionEvent>> MotionPredictor::predict(nsecs_t timestamp) {
    if (mEvents.size() < 2) {
        return {};
    }
@@ -67,7 +67,7 @@ std::vector<std::unique_ptr<MotionEvent>> MotionPredictor::predict() {

    std::unique_ptr<MotionEvent> prediction = std::make_unique<MotionEvent>();
    std::vector<PointerCoords> futureCoords;
    const int64_t futureTime = getExpectedPresentationTimeNanos() + mPredictionTimestampOffsetNanos;
    const nsecs_t futureTime = timestamp + mPredictionTimestampOffsetNanos;
    const nsecs_t currentTime = event.getEventTime();
    const MotionEvent& previous = mEvents.rbegin()[1];
    const nsecs_t oldTime = previous.getEventTime();
@@ -143,14 +143,4 @@ bool MotionPredictor::isPredictionAvailable(int32_t /*deviceId*/, int32_t source
    return true;
}

int64_t MotionPredictor::getExpectedPresentationTimeNanos() {
    std::scoped_lock lock(mLock);
    return mExpectedPresentationTimeNanos;
}

void MotionPredictor::setExpectedPresentationTimeNanos(int64_t expectedPresentationTimeNanos) {
    std::scoped_lock lock(mLock);
    mExpectedPresentationTimeNanos = expectedPresentationTimeNanos;
}

} // namespace android
+5 −9
Original line number Diff line number Diff line
@@ -63,8 +63,7 @@ TEST(MotionPredictorTest, LinearPrediction) {
    predictor.record(getMotionEvent(MOVE, 1, 3, 10));
    predictor.record(getMotionEvent(MOVE, 2, 5, 20));
    predictor.record(getMotionEvent(MOVE, 3, 7, 30));
    predictor.setExpectedPresentationTimeNanos(40);
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict();
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict(40);
    ASSERT_EQ(1u, predicted.size());
    ASSERT_EQ(predicted[0]->getX(0), 4);
    ASSERT_EQ(predicted[0]->getY(0), 9);
@@ -81,8 +80,7 @@ TEST(MotionPredictorTest, StationaryPrediction) {
    predictor.record(getMotionEvent(MOVE, 0, 1, 10));
    predictor.record(getMotionEvent(MOVE, 0, 1, 20));
    predictor.record(getMotionEvent(MOVE, 0, 1, 30));
    predictor.setExpectedPresentationTimeNanos(40);
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict();
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict(40);
    ASSERT_EQ(1u, predicted.size());
    ASSERT_EQ(predicted[0]->getX(0), 0);
    ASSERT_EQ(predicted[0]->getY(0), 1);
@@ -98,21 +96,19 @@ TEST(MotionPredictorTest, IsPredictionAvailable) {
TEST(MotionPredictorTest, Offset) {
    MotionPredictor predictor(/*predictionTimestampOffsetNanos=*/1,
                              []() { return true /*enable prediction*/; });
    predictor.setExpectedPresentationTimeNanos(40);
    predictor.record(getMotionEvent(DOWN, 0, 1, 30));
    predictor.record(getMotionEvent(MOVE, 0, 1, 35));
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict();
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict(40);
    ASSERT_EQ(1u, predicted.size());
    ASSERT_GE(predicted[0]->getEventTime(), 41);
}

TEST(MotionPredictionTest, FlagDisablesPrediction) {
TEST(MotionPredictorTest, FlagDisablesPrediction) {
    MotionPredictor predictor(/*predictionTimestampOffsetNanos=*/0,
                              []() { return false /*disable prediction*/; });
    predictor.setExpectedPresentationTimeNanos(40);
    predictor.record(getMotionEvent(DOWN, 0, 1, 30));
    predictor.record(getMotionEvent(MOVE, 0, 1, 35));
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict();
    std::vector<std::unique_ptr<MotionEvent>> predicted = predictor.predict(40);
    ASSERT_EQ(0u, predicted.size());
    ASSERT_FALSE(predictor.isPredictionAvailable(/*deviceId=*/1, AINPUT_SOURCE_STYLUS));
    ASSERT_FALSE(predictor.isPredictionAvailable(/*deviceId=*/1, AINPUT_SOURCE_TOUCHSCREEN));