Android触摸屏坐标转换

时间:2024-04-10 14:28:07

转载自:http://blog.csdn.net/ningyaodong/article/details/54318853


一、坐标转换机制概述

特有名词:

    TP : 触摸屏(Touch Panel) 
    LCD : 显示屏(Liquid Crystal Display)

 Android系统中,大多数的操作都是通过TP完成,这些操作是如何准确的呈现在LCD上的呢?这就涉及到将TP上报的触摸坐标映射LCD的像素坐标,这也正是Android坐标转换机制的作用。

二、坐标转换机制流程

Android触摸屏坐标转换

从上面的流程图可以看到整个坐标转换的过程,其中TP分辨率在驱动中调用input_set_abs_params来配置,而LCD分辨率则通过上层DisplayManagerService提供。然后在inputReader中计算转换比例。

下面我们从代码看下inputReader中是如何转换坐标的。


2.1监听设备的添加和初始化

EventHub线程启动后,会去扫描当前的输入设备节点,并产生DEVICE_ADDED事件给inputReader,将该设备添加到监听设备表。

Android触摸屏坐标转换

addDeviceLocked函数中,我们主要关注两个操作,一个是监听设备的创建,一个是对监听设备的配置初始化。

Android触摸屏坐标转换

监听设备的创建:包括定义其支持的设备模式和添加设备对应的InputMapper类:以TP为例,由于上报的事件类型是EV_ABS并且支持多点触控,所以会被设置为(INPUT_DEVICE_CLASS_EXTERNAL| INPUT_DEVICE_ CLASS_TOUCH_MT);根据TP模式,又会为设备添加MultiTouchInputMapper类。

configure的初始化:这里实际上是依次调用了inputDevice::configure()TouchInputMapper::configure()两个函数,去获取监听设备的配置信息(包括在驱动中配置的TP分辨率)和display信息。值得注意的是,上面提到的设备配置信息仅会在这里更新一次;如果配置出现异常将无法恢复,直到再次开关机。


Android触摸屏坐标转换

其中configureSurface()主要是根据当前显示视图的旋转角度来分别计算TP坐标到显示坐标的转换系数。其基本算法如下:当手机竖直放置时(旋转角度为0),X轴转换系数= (LCD_width) / (TP_X_max) , Y轴转换系数 =(LCD_height) /(TP_Y_max)。这一部分代码很长,但是逻辑比较简单,有兴趣的同事可以找到源代码详细阅读下,这里就不再贴出来了。


2.2坐标转换-cookPointerData

touch事件上报时,inputReader线程会最终调用cookPointerData()函数对这些数据进行预处理,然后再发送给上层。整个调用过程大家可以参考Input子系统部分的内容,这里不再过多描述,我们主要了解下cookPointerData函数的功能。

我们在驱动中上报touch信息时,不仅仅会上报坐标点,同时还会有tracking_id,pressure ,touch_major等属性值;这些属性值会在cookPointerData函数中经过简单计算然后再上报,例如坐标转换、压力值归一化等。在这里我们只截取关于坐标转换的一部分代码:

Android触摸屏坐标转换

代码逻辑非常清晰,根据当前画面的不同旋转角度,将TP坐标映射到正确的位置;其中不同的角度mXScalemYScaleconfigureSurface()中的计算情况,也不尽相同。


三、影响分辨率转换的关键点

  1. TPIC的输出分辨率

这个通常是读IC寄存器获取到的,如果读取到异常值,就会导致报点错乱,需要重启手机才能恢复。

  1. DisplayInfo出错

由于这个是上层传递下来的分辨率,如果出错,UI显示应该都会出现异常;但上层会有viewPort配置的更新监听,除非该配置一直是错误的,否则应该是可恢复的;具体情况可能需要深入研究下Display相关内容才能确定。