问题背景:FDE在鼠标操作过程中发现光标显示不流畅给人以系统卡顿的感觉。为了提升用户对FDE的使用体验,决定对FDE光标显示进行优化。
FDE光标显示原始方案是使用Android光标作为FDE的光标进行显示,weston光标和x11光标均被隐藏。如下图所示:
...
原始方案中的缺点:FDE光标在Android client渲染,而后经历了hwcomposer、weston compositor、XServer composite三个阶段的合成,整个流程很长,时间延迟较大。
优化方案介绍:缩短FDE光标的渲染合成流程,减少延迟的时间,把FDE的光标层提到xserver端更早地渲染出来。而不是先作为作为Android client渲染再去参与后续的三次图形合成流程平白增加了延迟的时间。
在实际优化过程中,此问题分为了两个阶段的优化。第一阶段:将Android光标内容提取出来,然后创建weston光标,将提取的Android光标的内容贴到新创建的weston光标上,然后隐藏掉Android光标和x11光标,让weston光标来代替Android光标作为FDE的光标进行显示。如下图所示:
第一阶段:将Android光标内容提取出来,然后创建weston光标,将提取的Android光标的内容贴到新创建的weston光标上,然后隐藏掉Android光标和x11光标,让weston光标来代替Android光标作为FDE的光标进行显示。如下图所示:
...
第一阶段优化方案中的关键流程如下图所示:
...
第二阶段:第一阶段优化后,光标流畅度有明显提升,但在景嘉微显卡上运行时,光标显示更新变得很慢。为了提升操作体验,在第一阶段的基础上继续进行优化,首先在景嘉微显卡上对比测试麒麟桌面应用操作光标比较流畅。
第二阶段:第一阶段优化后,FDE光标不需要经过Android端的hwcomposer进行合成,直接在weston compositor参与合成,渲染合成的流程缩短了,光标流畅度有在AMD显卡上有明显提升。因为后续的测试中在景嘉微显卡上运行时,FDE光标显示的流畅度虽有所提升,但仍然比较慢, 是因为weston的gl_renderer_repaint_output函数和在AMD显卡相比,在景嘉微显卡上运行很慢。为了进一步提升操作体验,在第一阶段的基础上继续进行优化,首先在景嘉微显卡上对比测试麒麟桌面应用操作光标比较流畅。
而FDE的weston窗口是运行在麒麟系统之上的,所以考虑为weston窗口创建自定义的x11光标,将weston client的光标内容提取出来并给到新创建的x11光标,然后隐藏Android光标和weston client光标,让x11光标作为FDE的光标进行显示。如下图所示:
...
而在weston光标转x11光标优化方案里,在pointer_set_cursor方法中我们可以得到weston光标图层weston_surface,根据weston_surface的宽高信息开辟一段临时内存空间用于存储weston光标图形数据,通过weston_surface_copy_content提取到weston光标的图形数据并保存到临时开辟的内存空间中。最后通过调用新增的函数set_custom_cursor创建并设置x11光标,同时调用pointer_unmap_sprite将weston光标隐藏。创建设置x11光标功能实现参照了libxcursor库,其中的一些关键方法有XcursorImageCreate、XcursorImageLoadCursor、XCreatePixmap、XCreateGC、XPutImage、XRenderCreatePicture、XRenderCreateCursor。sprite将weston光标隐藏。创建设置x11光标功能实现参照了libxcursor和libxrender库,其中的一些关键方法有
XcursorImageCreate: 创建XcursorImage,在创建好后接下来可将提取的weston光标图形数据赋给XcursorImage变量的XcursorPixel指针。
XcursorImageLoadCursor:此方法封装了Cursor的创建过程,将赋值好的XcursorImage作为参数传入。
XCreatePixmap:创建Pixmap
XCreateGC:创建GC图形上下文
XPutImage:在XcursorImage转换成XImage后,将XImage和Pixmap作为参数传入,将图形数据贴到Pixmap上。
XRenderCreatePicture:创建Picture,Pixmap作为参数传入将图形数据转到Picture上。
XRenderCreateCursor:创建Cursor,Picture作为参数传入。