本文旨在按照从底层到上层的顺序,详细串联下android4.4 webview chromium架构下的硬件绘制实现细节。
目录结构
一.webview chromium与GPU交互的方式(单进程CommandBuffer系统的详细结构)
1.1 OpenGL ES2.0与EGL简介
1.2 android4.4中创建的供chromium内核使用的EGLContext和EGLSurface
1.3 chromium内核加载gles2及egl库并绑定其接口
1.4 chromium内核对GL Context及GL Surface的封装
1.5 GLContext的虚拟化及InProcessCommandBuffer对GLContext的封装
1.6 单进程CommandBuffer系统对client端提供的接口及client端创建该接口的过程
1.7 小结
1.8 CommandBuffer系统设计目标及基本实现原理
二.网页内容从webkit RenderTree合成到android系统WebView控件对应的Surface上的过程
一.webviewchromium与GPU交互的方式(单进程CommandBuffer系统的详细结构)
1.1 OpenGL ES2.0与EGL简介
OpenGLES2.0
是一套跨平台的在手持及嵌入式设备上渲染复杂3D图形的软件接口,由Khronos Group开发。
可以简单理解为操纵GPU的一组通用接口,由平台厂商提供具体实现,实现库libglesv2.so.
EGL
EGL是OpenGL ES关联本地窗口系统的接口标准。
功能类似于OpenGL在Windows平台上关联窗口系统使用的wgl,在Mac平台使用的agl,以及x-windows上使用的xgl。开发者需要查阅平台商的文档来决定支持哪个接口,由平台厂商提供具体实现,实现库的名字libegl.so.
OpenGLES2.0与EGL的关系
OpenGL ES本质上是个pipeline的状态机。OpenGLES命令的执行需要一个rendering context和一个drawing surface。
renderingcontext
存放的是状态机的当前状态。有当前的颜色、纹理坐标、变换矩阵、渲染模式等,这些状态作用于程序提交的顶点坐标等图元从而形成帧缓冲内的像素。在OpenGL的编程接口中,rendering context就代表这个状态机,程序的主要工作就是向Context提供图元、设置状态,偶尔也从Context里获取一些信息。(这段取自网上某位同学的博客,没找到出处,不好意思)
drawingsurface
是图元绘制其上的目标surface。drawing surface指定了渲染需要的buffer类型,比如color buffer,depth buffer和stencil buffer.
rendering context与drawingsurface是由EGL创建并维护的。
OpenGL ES在开始渲染之前,需要使用EGL做如下事情:
●查询设备上可用的display,并初始化它们。
比如,翻盖手机可能有两个LCD面板,我们使用OpenGL ES渲染的surface可能可以在其中一个或两个面板上显示。
●创建一个renderingsurface.EGL创建的Surface可以分为两类:on-screen surfaces和off-screen surfaces。On-screen surfaces是attach到本地窗口系统的.而off-screen surfaces是不能不显示的pixel buffers,但是可以作为rendering surface使用。off-screen surfaces可以被用来渲染到texture上,或者在多重Khronos APIs之间共享。
●创建一个rendering context.EGL需要创建一个OpenGL ES rendering context.在rendering实际开始之前,renderingcontext需要attach到一个合适的surface上。
下面例子是EGL初始化的一个基本调用:
1.创建display并初始化
//返回与native display相连接的EGLdisplay.
display =eglGetDisplay(EGL_DEFAULT_DISPLAY);
//初始化EGL display.
eglInitialize(display,...).
//返回满足一定属性的EGL framebuffer配置列表
eglChooseConfig(&config)
2.创建rendering surface
//创建一个EGL windowsurface返回其句柄
surface = eglCreateWindowSurface(display,config, winType, NULL);
3.创建rendering context
//创建EGL renderingcontext,可以使用这个context渲染到EGL drawing surface
context = eglCreateContext(display, config,EGL_NO_CONTEXT, NULL);
display,surface,context三者之间的联系
surface必须绑定到调用线程的当前context,