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

Commit e07e1031 authored by Robert Carr's avatar Robert Carr
Browse files

SurfaceFlinger Input: Correct screen magnification.

We need to pass the computed scaling factors through SurfaceFlinger
as well as appropriately scaling the touchable region. We also need
to be careful as to which axes we scale. In the past screen magnification
has not lead to scaling of the TOUCH_MAJOR/MINOR axes, whereas whole-screen
display compatibility scaling has. We preserve this behavior by differentiating
between the global scale and a scale on any particular window. The window scale
works like the global scale used to and the global scale is only used for additional
scaling of the MAJOR/MINOR axes.

Bug: 80101428
Bug: 113136004
Bug: 111440400
Change-Id: I97d809826f86b452f28443cb1046e8bfef1bbf9d
parent e52502e2
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -244,7 +244,12 @@ struct PointerCoords {
    float getAxisValue(int32_t axis) const;
    status_t setAxisValue(int32_t axis, float value);

    void scale(float scale);
    void scale(float globalScale);

    // Scale the pointer coordinates according to a global scale and a
    // window scale. The global scale will be applied to TOUCH/TOOL_MAJOR/MINOR
    // axes, however the window scaling will not.
    void scale(float globalScale, float windowXScale, float windowYScale);
    void applyOffset(float xOffset, float yOffset);

    inline float getX() const {
@@ -595,7 +600,7 @@ public:

    void offsetLocation(float xOffset, float yOffset);

    void scale(float scaleFactor);
    void scale(float globalScaleFactor);

    // Apply 3x3 perspective matrix transformation.
    // Matrix is in row-major form and compatible with SkMatrix.
+7 −1
Original line number Diff line number Diff line
@@ -140,7 +140,13 @@ struct InputWindowInfo {
     */
    int32_t surfaceInset = 0;

    float scaleFactor;
    // A global scaling factor for all windows. Unlike windowScaleX/Y this results
    // in scaling of the TOUCH_MAJOR/TOUCH_MINOR axis.
    float globalScaleFactor;

    // Scaling factors applied to individual windows.
    float windowXScale = 1.0f;
    float windowYScale = 1.0f;

    /*
     * This is filled in by the WM relative to the frame and then translated
+1 −1
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ private:
        mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
        mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
        mInputInfo.dispatchingTimeout = 100000;
        mInputInfo.scaleFactor = 1.0;
        mInputInfo.globalScaleFactor = 1.0;
        mInputInfo.canReceiveKeys = true;
        mInputInfo.hasFocus = true;
        mInputInfo.hasWallpaper = false;
+22 −13
Original line number Diff line number Diff line
@@ -131,15 +131,24 @@ static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor)
    }
}

void PointerCoords::scale(float scaleFactor) {
void PointerCoords::scale(float globalScaleFactor, float windowXScale, float windowYScale) {
    // No need to scale pressure or size since they are normalized.
    // No need to scale orientation since it is meaningless to do so.
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);

    // If there is a global scale factor, it is included in the windowX/YScale
    // so we don't need to apply it twice to the X/Y axes.
    // However we don't want to apply any windowXYScale not included in the global scale
    // to the TOUCH_MAJOR/MINOR coordinates.
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, windowXScale);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, windowYScale);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, globalScaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, globalScaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, globalScaleFactor);
    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, globalScaleFactor);
}

void PointerCoords::scale(float globalScaleFactor) {
    scale(globalScaleFactor, globalScaleFactor, globalScaleFactor);
}

void PointerCoords::applyOffset(float xOffset, float yOffset) {
@@ -345,15 +354,15 @@ void MotionEvent::offsetLocation(float xOffset, float yOffset) {
    mYOffset += yOffset;
}

void MotionEvent::scale(float scaleFactor) {
    mXOffset *= scaleFactor;
    mYOffset *= scaleFactor;
    mXPrecision *= scaleFactor;
    mYPrecision *= scaleFactor;
void MotionEvent::scale(float globalScaleFactor) {
    mXOffset *= globalScaleFactor;
    mYOffset *= globalScaleFactor;
    mXPrecision *= globalScaleFactor;
    mYPrecision *= globalScaleFactor;

    size_t numSamples = mSamplePointerCoords.size();
    for (size_t i = 0; i < numSamples; i++) {
        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
        mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor);
    }
}

+6 −2
Original line number Diff line number Diff line
@@ -82,7 +82,9 @@ status_t InputWindowInfo::write(Parcel& output) const {
    output.writeInt32(frameRight);
    output.writeInt32(frameBottom);
    output.writeInt32(surfaceInset);
    output.writeFloat(scaleFactor);
    output.writeFloat(globalScaleFactor);
    output.writeFloat(windowXScale);
    output.writeFloat(windowYScale);
    output.writeBool(visible);
    output.writeBool(canReceiveKeys);
    output.writeBool(hasFocus);
@@ -121,7 +123,9 @@ InputWindowInfo InputWindowInfo::read(const Parcel& from) {
    ret.frameRight = from.readInt32();
    ret.frameBottom = from.readInt32();
    ret.surfaceInset = from.readInt32();
    ret.scaleFactor = from.readFloat();
    ret.globalScaleFactor = from.readFloat();
    ret.windowXScale = from.readFloat();
    ret.windowYScale = from.readFloat();
    ret.visible = from.readBool();
    ret.canReceiveKeys = from.readBool();
    ret.hasFocus = from.readBool();
Loading