一、坐标转换机制概述

特有名词:

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

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

二、坐标转换机制流程


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

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


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

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

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

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

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


其中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函数中经过简单计算然后再上报,例如坐标转换、压力值归一化等。在这里我们只截取关于坐标转换的一部分代码:

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


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

  1. TPIC的输出分辨率

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

  1. DisplayInfo出错

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

更多相关文章

  1. ANDROID Porting系列八、Keymaps and Keyboard Input
  2. [Google Android] GCM: Getting Started
  3. android开发中adb的用法
  4. 最佳的免费移动设备的原型模板文件下载
  5. 【Android】 Android-wifi 直连 wifi direct wifi p2p
  6. A​n​d​r​o​i​d​ ​B​l​u​e​t​o​o​t​h​详​解(And
  7. Android关于arm64-v8a、armeabi-v7a、armeabi、X86的so文件兼容
  8. Android添加用户组及自定义App权限的方法
  9. Android(安卓)正 N 边形圆角头像的实现

随机推荐

  1. JQuery实现的 checkbox 全选、反选。
  2. 执行Django数据库值的计算:视图。py或Jav
  3. 通过AJAX加载内容和预加载图像?
  4. 使用JQuery从外部文件中通过id选择器获取
  5. 使用jQuery更新textarea值更改的文本
  6. 是否每次都可能分离内容、表示和行为?
  7. jquery向Django后台发送数组
  8. 将JavaScript对象作为Dictionary 传递给C
  9. 如何防止缓存.NET JSON源
  10. 如何在用户选择操作后获取当前日期和时间