android触摸点上报伸缩问题

当在调试触摸板的时候发现触摸的上报值到android系统层x轴的触摸点会有压缩,这是是由于触摸屏的的触摸的倍数跟显示缓冲区有关系。在调试特殊的屏幕分辨率时,如果你的显示framebufferr跟你的显示屏的分辨率没有对应上,那么你触摸也会有问题,例如显示屏的分辨率为480x800,而你的缓冲区只有268x800的时候,如果这时候你的触摸屏配置的分辨率为480x800,那么触摸上报的x轴坐标的点也会被压缩268/480≈0.55倍。

相关压缩的代码代码如下:

路径:framework\native\services\inputflinger\InputReader.cpp

void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
int32_t oldDeviceMode = mDeviceMode;
......
  int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;

......
        // Configure X and Y factors.
        mXScale = float(mSurfaceWidth) / rawWidth;
        mYScale = float(mSurfaceHeight) / rawHeight;
        mXTranslate = -mSurfaceLeft;
        mYTranslate = -mSurfaceTop;
       ......
}

mSurfaceWidth代表的是显示缓冲区的宽度
rawWidth 代表的是驱动中设置的触摸宽度
X轴的宽度倍数为:
mXScale = float(mSurfaceWidth) / rawWidth;

由于:
mSurfaceWidth=268
rawWidth =480
则:
mXScale =float(268)/480≈0.55

为何rawWidth的值480,下面我们看下rawWidth 参数或获取过程:
(1)如上,rawWidth 来自mRawPointerAxes.x

路径:framework\native\services\inputflinger\InputReader.cpp

  rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;

(2)&mRawPointerAxes.x赋值过程

路径:

void SingleTouchInputMapper::configureRawPointerAxes() {
    TouchInputMapper::configureRawPointerAxes();

    getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);//赋值
    getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
    getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
    getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
    getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
    getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
}

(3)getAbsoluteAxisInfo实现,则是通过ioctl(device->fd, EVIOCGABS(axis), &info)去获得
并复制给mRawPointerAxes.x

代码路径:framework\native\services\inputflinger\EventHub.cpp

status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
        RawAbsoluteAxisInfo* outAxisInfo) const {
    outAxisInfo->clear();

    if (axis >= 0 && axis <= ABS_MAX) {
        AutoMutex _l(mLock);
        Device* device = getDeviceLocked(deviceId);
        if (device && device->hasValidFd() && test_bit(axis, device->absBitmask)) {
            struct input_absinfo info;
              //获取触摸信息,info
            if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
                ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
                     axis, device->identifier.name.string(), device->fd, errno);
                return -errno;
            }
            if (info.minimum != info.maximum) {
                outAxisInfo->valid = true;
//赋值mRawPointerAxes.x
                outAxisInfo->minValue = info.minimum;
                outAxisInfo->maxValue = info.maximum;
                outAxisInfo->flat = info.flat;
                outAxisInfo->fuzz = info.fuzz;
                outAxisInfo->resolution = info.resolution;
            }
            return OK;
        }
    }
    return -1;
}

(4)使用 EVIOCGABS ioctl提供绝对坐标轴设备的状态信息。它为每一个绝对坐标轴提供了一个 input_absinfo数据结构(参考 Listing 16)。如果你想查看设备的全局状态,对每一个坐标轴调用 EVIOCGABS ioctl函数。 Listing 17展示了该示例。
Listing 16. input_absinfo for an Absolute Axis

struct input_absinfo {
    __s32 value;         // current value of the axis
    __s32 minimum;       // current limits of the axis
    __s32 maximum;       // current limits of the axis
    __s32 fuzz;
    __s32 flat;
};

(5) maximum 等参数的赋值

代码路径:./kernel/drivers/input/input.c

void input_set_abs_params(struct input_dev *dev, unsigned int axis,
                          int min, int max, int fuzz, int flat)
{
        struct input_absinfo *absinfo;

        input_alloc_absinfo(dev);
        if (!dev->absinfo)
                return;

        absinfo = &dev->absinfo[axis];
        absinfo->minimum = min;
        absinfo->maximum = max;
        absinfo->fuzz = fuzz;
        absinfo->flat = flat;

        __set_bit(EV_ABS, dev->evbit);
        __set_bit(axis, dev->absbit);
}
EXPORT_SYMBOL(input_set_abs_params);

(6)触摸驱动的probe函数中初始化触摸屏分辨率,其中

#define  SCREEN_MAX_X  480
#define  SCREEN_MAX_Y  800
    input_set_abs_params(input_device,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);
    input_set_abs_params(input_device,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);
    input_set_abs_params(input_device,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);
    input_set_abs_params(input_device,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);

解决该问题只需要将SCREEN_MAX_X的宏定义值改为268便可。

#define  SCREEN_MAX_X  268

调试方法:
android 在输入子系统一些参数提供的一些快速的查询方法,只需要dumpsys input则获取所有的input子系统的一些参数。例如查询放大倍数:

rk3326_mid:/ # dumpsys | grep Scale
  mDozeScaleFactor=1.0
        XScale: 0.996
        YScale: 0.999
        GeometricScale: 0.998
        PressureScale: 0.000
        SizeScale: 0.004
        OrientationScale: 0.000
        DistanceScale: 0.000
        TiltXScale: 0.000
        TiltYScale: 0.000
   mKeyPreviewShowUpStartScaleX = 0.98
   mKeyPreviewShowUpStartScaleY = 0.98
   mKeyPreviewDismissEndScaleX = 0.94000006
   mKeyPreviewDismissEndScaleY = 0.94000006
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值