原创文章,转载请以链接形式注明原始出处为http://blog.csdn.net/hongbomin/article/details/40896313
摘要:从Android KitKat系统第一个采用Chromium内核的WebView开始,Android WebView一直在持续演进中,自Chromium M38开始,WebView在硬件渲染模式方面发生了较大的变化,最明显的变化莫过于WebGL的支持以及ubercompositor的使用,同时为了吻合Android L的渲染模型变化,DrawGL函数是在Android系统的渲染线程中执行的。
Android 4.4系统WebView的硬件渲染
对于Chromium WebView来说,首先它是单进程模型的,至少在使用CommandBuffer时可以省去不必要的跨进程IPC开销,尽管IPC开销并没有想象中那么大(根据性能评测,大概占了不超过5%的开销)。更为重要的是,WebView必须是Android窗口中一个普通的View,与窗口其他View共享同一个Android Surface绘制表面,因此,
- WebView在UI线程上响应onDraw事件,启动页面渲染的流水线工作,将新的帧内容通过onDraw绘制到Canvas上;
- WebView使用同步合成器(SynchronousCompositor)来合成页面内容,“同步”指的是运行在UI线程上,合成操作是由UI线程的onDraw事件触发的,而不是VSYNC触发的。从线程化合成器的角度看,UI线程实际上也是Compositing线程;
- WebView提供了一个硬件加速版本的回调函数DrawGL(即AwContents::DrawGL),将Chromium的渲染流水线工作串到AndroidView的渲染路径上。在使用硬件加速的情况下,WebView.onDraw接受的参数Canvas是一个对Android SDK不可见的android.view.HardwareCanvas对象,HardwareCanvas允许客户端提供自己的GL回调函数,Android View系统在重放(playback)显示列表绘制View层次时会调用这个回调函数。(注:在AndroidFramework内部实现中,当开始绘制HardwareCanvas时,当前GL上下文会绑定HardwareCanvas的framebuffer对象,所以GL回调函数中所有的GL命令实际上在操作HardwareCanvas的framebuffer对象)。
Android 4.4系统中,在绘制View层次时,显示列表的更新记录以及重放都发生在UI线程上,相应地,WebView.onDraw事件的处理中,页面的层合成,以及通过DrawGL函数将合成的内容绘制到HardwareCanvas,都是在UI线程执行的。当WebView收到invalidate消息后,ViewRoot会遍历整个View树决定向哪些View派送onDraw事件,WebView响应onDraw事件时,会直接请求HardwareCanvas执行DrawGL回