当在调试触摸板的时候发现触摸的上报值到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