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

Commit 01c682f2 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12253386 from fb775d52 to 24Q4-release

Change-Id: I17777830267122eca1f6751394ff8937d103bc03
parents f4c368e1 fb775d52
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
               libs/nativewindow/
               libs/renderengine/
               libs/ui/
               libs/vibrator/
               libs/vr/
               opengl/libs/
               services/bufferhub/
+22 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <chrono>
#include <optional>
#include <vector>

#include <input/Input.h>
#include <input/InputTransport.h>
@@ -71,7 +72,15 @@ private:

    struct Sample {
        std::chrono::nanoseconds eventTime;
        Pointer pointer;
        std::vector<Pointer> pointers;

        std::vector<PointerCoords> asPointerCoords() const {
            std::vector<PointerCoords> pointersCoords;
            for (const Pointer& pointer : pointers) {
                pointersCoords.push_back(pointer.coords);
            }
            return pointersCoords;
        }
    };

    /**
@@ -88,12 +97,21 @@ private:
    RingBuffer<Sample> mLatestSamples{/*capacity=*/2};

    /**
     * Adds up to mLatestSamples.capacity() of motionEvent's latest samples to mLatestSamples. (If
     * Adds up to mLatestSamples.capacity() of motionEvent's latest samples to mLatestSamples. If
     * motionEvent has fewer samples than mLatestSamples.capacity(), then the available samples are
     * added to mLatestSamples.)
     * added to mLatestSamples.
     */
    void updateLatestSamples(const MotionEvent& motionEvent);

    static Sample messageToSample(const InputMessage& message);

    /**
     * Checks if auxiliary sample has the same pointer properties of target sample. That is,
     * auxiliary pointer IDs must appear in the same order as target pointer IDs, their toolType
     * must match and be resampleable.
     */
    static bool pointerPropertiesResampleable(const Sample& target, const Sample& auxiliary);

    /**
     * Checks if there are necessary conditions to interpolate. For example, interpolation cannot
     * take place if samples are too far apart in time. mLatestSamples must have at least one sample
+86 −17
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <android-base/logging.h>
#include <android-base/properties.h>
#include <ftl/enum.h>

#include <input/Resampler.h>
#include <utils/Timers.h>
@@ -56,6 +57,11 @@ constexpr std::chrono::milliseconds RESAMPLE_MAX_DELTA{20};

constexpr std::chrono::milliseconds RESAMPLE_MAX_PREDICTION{8};

bool canResampleTool(ToolType toolType) {
    return toolType == ToolType::FINGER || toolType == ToolType::MOUSE ||
            toolType == ToolType::STYLUS || toolType == ToolType::UNKNOWN;
}

inline float lerp(float a, float b, float alpha) {
    return a + alpha * (b - a);
}
@@ -73,21 +79,70 @@ PointerCoords calculateResampledCoords(const PointerCoords& a, const PointerCoor

void LegacyResampler::updateLatestSamples(const MotionEvent& motionEvent) {
    const size_t numSamples = motionEvent.getHistorySize() + 1;
    for (size_t i = 0; i < numSamples; ++i) {
    const size_t latestIndex = numSamples - 1;
    const size_t secondToLatestIndex = (latestIndex > 0) ? (latestIndex - 1) : 0;
    for (size_t sampleIndex = secondToLatestIndex; sampleIndex < numSamples; ++sampleIndex) {
        std::vector<Pointer> pointers;
        const size_t numPointers = motionEvent.getPointerCount();
        for (size_t pointerIndex = 0; pointerIndex < numPointers; ++pointerIndex) {
            // getSamplePointerCoords is the vector representation of a getHistorySize by
            // getPointerCount matrix.
            const PointerCoords& pointerCoords =
                    motionEvent.getSamplePointerCoords()[sampleIndex * numPointers + pointerIndex];
            pointers.push_back(
                    Pointer{*motionEvent.getPointerProperties(pointerIndex), pointerCoords});
        }
        mLatestSamples.pushBack(
                Sample{static_cast<nanoseconds>(motionEvent.getHistoricalEventTime(i)),
                       Pointer{*motionEvent.getPointerProperties(0),
                               motionEvent.getSamplePointerCoords()[i]}});
                Sample{nanoseconds{motionEvent.getHistoricalEventTime(sampleIndex)}, pointers});
    }
}

LegacyResampler::Sample LegacyResampler::messageToSample(const InputMessage& message) {
    std::vector<Pointer> pointers;
    for (uint32_t i = 0; i < message.body.motion.pointerCount; ++i) {
        pointers.push_back(Pointer{message.body.motion.pointers[i].properties,
                                   message.body.motion.pointers[i].coords});
    }
    return Sample{nanoseconds{message.body.motion.eventTime}, pointers};
}

bool LegacyResampler::canInterpolate(const InputMessage& futureSample) const {
bool LegacyResampler::pointerPropertiesResampleable(const Sample& target, const Sample& auxiliary) {
    if (target.pointers.size() > auxiliary.pointers.size()) {
        LOG_IF(INFO, debugResampling())
                << "Not resampled. Auxiliary sample has fewer pointers than target sample.";
        return false;
    }
    for (size_t i = 0; i < target.pointers.size(); ++i) {
        if (target.pointers[i].properties.id != auxiliary.pointers[i].properties.id) {
            LOG_IF(INFO, debugResampling()) << "Not resampled. Pointer ID mismatch.";
            return false;
        }
        if (target.pointers[i].properties.toolType != auxiliary.pointers[i].properties.toolType) {
            LOG_IF(INFO, debugResampling()) << "Not resampled. Pointer ToolType mismatch.";
            return false;
        }
        if (!canResampleTool(target.pointers[i].properties.toolType)) {
            LOG_IF(INFO, debugResampling())
                    << "Not resampled. Cannot resample "
                    << ftl::enum_string(target.pointers[i].properties.toolType) << " ToolType.";
            return false;
        }
    }
    return true;
}

bool LegacyResampler::canInterpolate(const InputMessage& message) const {
    LOG_IF(FATAL, mLatestSamples.empty())
            << "Not resampled. mLatestSamples must not be empty to interpolate.";

    const Sample& pastSample = *(mLatestSamples.end() - 1);
    const nanoseconds delta =
            static_cast<nanoseconds>(futureSample.body.motion.eventTime) - pastSample.eventTime;
    const Sample& futureSample = messageToSample(message);

    if (!pointerPropertiesResampleable(pastSample, futureSample)) {
        return false;
    }

    const nanoseconds delta = futureSample.eventTime - pastSample.eventTime;
    if (delta < RESAMPLE_MIN_DELTA) {
        LOG_IF(INFO, debugResampling()) << "Not resampled. Delta is too small: " << delta << "ns.";
        return false;
@@ -104,15 +159,20 @@ std::optional<LegacyResampler::Sample> LegacyResampler::attemptInterpolation(
            << "Not resampled. mLatestSamples must not be empty to interpolate.";

    const Sample& pastSample = *(mLatestSamples.end() - 1);

    const nanoseconds delta =
            static_cast<nanoseconds>(futureSample.body.motion.eventTime) - pastSample.eventTime;
            nanoseconds{futureSample.body.motion.eventTime} - pastSample.eventTime;
    const float alpha =
            std::chrono::duration<float, std::milli>(resampleTime - pastSample.eventTime) / delta;
    const PointerCoords resampledCoords =
            calculateResampledCoords(pastSample.pointer.coords,
                                     futureSample.body.motion.pointers[0].coords, alpha);

    return Sample{resampleTime, Pointer{pastSample.pointer.properties, resampledCoords}};
    std::vector<Pointer> resampledPointers;
    for (size_t i = 0; i < pastSample.pointers.size(); ++i) {
        const PointerCoords& resampledCoords =
                calculateResampledCoords(pastSample.pointers[i].coords,
                                         futureSample.body.motion.pointers[i].coords, alpha);
        resampledPointers.push_back(Pointer{pastSample.pointers[i].properties, resampledCoords});
    }
    return Sample{resampleTime, resampledPointers};
}

bool LegacyResampler::canExtrapolate() const {
@@ -124,6 +184,10 @@ bool LegacyResampler::canExtrapolate() const {
    const Sample& pastSample = *(mLatestSamples.end() - 2);
    const Sample& presentSample = *(mLatestSamples.end() - 1);

    if (!pointerPropertiesResampleable(presentSample, pastSample)) {
        return false;
    }

    const nanoseconds delta = presentSample.eventTime - pastSample.eventTime;
    if (delta < RESAMPLE_MIN_DELTA) {
        LOG_IF(INFO, debugResampling()) << "Not resampled. Delta is too small: " << delta << "ns.";
@@ -160,16 +224,21 @@ std::optional<LegacyResampler::Sample> LegacyResampler::attemptExtrapolation(
    const float alpha =
            std::chrono::duration<float, std::milli>(newResampleTime - pastSample.eventTime) /
            delta;
    const PointerCoords resampledCoords =
            calculateResampledCoords(pastSample.pointer.coords, presentSample.pointer.coords,
                                     alpha);

    return Sample{newResampleTime, Pointer{presentSample.pointer.properties, resampledCoords}};
    std::vector<Pointer> resampledPointers;
    for (size_t i = 0; i < presentSample.pointers.size(); ++i) {
        const PointerCoords& resampledCoords =
                calculateResampledCoords(pastSample.pointers[i].coords,
                                         presentSample.pointers[i].coords, alpha);
        resampledPointers.push_back(Pointer{presentSample.pointers[i].properties, resampledCoords});
    }
    return Sample{newResampleTime, resampledPointers};
}

inline void LegacyResampler::addSampleToMotionEvent(const Sample& sample,
                                                    MotionEvent& motionEvent) {
    motionEvent.addSample(sample.eventTime.count(), &sample.pointer.coords, motionEvent.getId());
    motionEvent.addSample(sample.eventTime.count(), sample.asPointerCoords().data(),
                          motionEvent.getId());
}

void LegacyResampler::resampleMotionEvent(nanoseconds resampleTime, MotionEvent& motionEvent,
Loading