Chromium UI框架widget

很早之前就想把Chromium的UI框架总结一遍。知道一个事物并向别人描述清楚并非是一件容易的事情,而且它又是如此的复杂,我没有把握把Chromium的UI框架给别人讲清楚,只有尽力而为。

我准备分三部分来讲Chromium的UI框架。首先是Widget,它是View的宿主,也是连接操作系统原生的UI系统的枢纽,同时还与CC(Chrome compositor)渲染合成有关系。Widget在整个Chromium的UI框架系统中起着承上启下的作用,所以我以Widget为突破口来介绍这个框架。其次我将介绍View,有了Widget的基础,再通过使用View来学习View。最后我再介绍CC,探寻一下渲染底层的秘密。

chromium-ui

上图就是Chromium UI框架几大模块之间的关系。Widget的宿主是原生系统窗口,它接受来自原生系统窗口的UI事件,比如键盘鼠标等消息。Widget类似原始系统窗口,有标题栏、最大化最小化、客户区、非客户区等区域。Widget里面包含了View,Widget具体显示什么内容是由它包含的View决定的。Widget和View的界面更新的时候,会通过CC以Layer的形式去合成在一起,最终通过GPU渲染成可视的图像,画在原生系统窗口上。

看Widget头文件的注释:

Encapsulates the platform-specific rendering, event receiving and widget management aspects of the UI framework.

Owns a RootView and thus a View hierarchy. Can contain child Widgets.Widget is a platform-independent type that communicates with a platform or context specific NativeWidget implementation.

Widget封装了平台相关的渲染、事件接受和UI框架的widget管理。同时它也拥有一个RootView,与之对应的一个View层次。Widget还可以包含子Widget。Widget是一个平台无关的类型,跟同台相关的NativeWidget通信。
上面说了半天,我们可能还是不知道Widget到底是什么。其实我们可以把Wiget当作是Chromium UI框架里面的一个窗口对象,不过它是跨平台的,在不同平台上提供了相同的接口。它在不同的平台背后实现是不同的,它背后调用的是与平台相关的NativeWidget。
Widget是个窗口对象,真的跟Windows里面的窗口,比如对话框、菜单、弹出窗口等等很类似。Widget也有多种类型,比如WINDOW类型、PANEL类型、POPUP类型。Widget可以有标题栏,可以有父Widget、子Widget的,可以移动,可以隐藏,可以激活可以置顶。

下图基本上描述Widget系统:

20170317204010

最底层的虚线之下是操作系统。操作系统把键盘鼠标消息发送给WindowImpl对象。WindowImpl其实就是对HWND的封装,它代表了一个系统一个原生的窗口,做windows开发的同学应该对WindowImpl的代码很熟悉。WindowImpl会创建一个Chrome_WidgetWin_为类型的窗口。我们通过SPY++可以看到Chrome浏览器的父窗口类型是Chrome_WidgetWin_1。

20170321144409
HWNDMessageHandler继承自WindowImpl,WindowImpl会把各种系统消息发送给HWNDMessageHandler处理,然后HWNDMessageHandler一步通过DesktopWindowTreeHostWin->DesktopNativeWidgetAura->Widget->View,就如红线所示。
Widget和View收到消息,就会做出各种响应。当需要更新UI的时候,View->Widget->DesktopNativeWidgetAura->Window->Layer这样一层层调用,最终通过Compositor去合成,合成渲染完成之后,就会直接画到WindowImpl对应的HWND的窗口上。逻辑如上图的黄线所示。

上图最上层的Widget,它包含着View,这是我们使用Chromium UI框架的主要接口。DesktopNativeWidgetAura和NativeWidgetAura都是NativeWidget,它是平台里面UI框架的具体实现。NativeWidgetAura比较简单,它仅是是对Window对象的封装,而Window又是对layer对象的封装。
DesktopNativeWidgetAura逻辑比较复杂,它可以包含和管理其他的NativeWidgetAura。而DesktopNativeWidgetAura又包含过DesktopWindowTreeHostWin,过DesktopWindowTreeHostWin管理Window。

下图则是Widget系统的UML图:

20170320171923

《Chromium UI框架widget》有2个想法

  1. ChromeUI不是用GPU渲染的。

    Chrome为了保证UI渲染的稳定性,目前Widget里的CC层都是Browser进程处理,绘制纹理后,CC合成完毕后成一张图片,直接软件贴到窗口上的。
    只有页面中网页由于存在视频,各类动画,图片等,采用了CC合成后将纹理提交给了GPU进程进行Swap到窗口上的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注