一.DrawGLFunctor
android4.4 webview chromium的硬件渲染是android ui系统和chromium内核协作
完成的。android ui系统负责触发网页渲染(调用WebView.onDraw()),以及提供
网页内容的最终目的地(HardwareCanvas);chromium内核提供具体的渲染行为。
这里就引出了DrawGLFunctor结构。
DrawGLFunctor.java/draw_gl_functor.cpp
draw_gl_functor.cpp提供了接口供chromium内核注册自己的DrawGL函数。
DrawGLFunctor是一个函数指针,这个函数在系统调用WebView.onDraw()
的过程中被传给了android ui系统,并在android ui系统中被调用,
DrawGLFunctor的operator()调用的实际是chromium内核注册的DrawGL函数。
由于DrawGLFunctor的operator()是android ui系统调用的,所以需要将
android ui系统的DrawGlInfo结构转换成chromium的AwDrawGLInfo之后,
再调用chromium内核注册的DrawGL函数,并在调用完后,更新android ui
系统的DrawGlInfo结构。
先看chromium的DrawGL函数注册给draw_gl_functor.cpp的过程。
draw_gl_functor.cpp中定义了全局函数:
void SetChromiumAwDrawGLFunction() {
g_aw_drawgl_function = reinterpret_cast<AwDrawGLFunction*>(draw_function);
}
设置给draw_gl_functor.cpp的全局变量g_aw_drawgl_function的是AwContents.java中
nativeGetAwDrawGLFunction()返回的函数标识。
我们看AwContents.java::nativeGetAwDrawGLFunction()得到的具体是那个函数。
aw_contents.cc
static jint GetAwDrawGLFunction(JNIEnv* env, jclass) {
return reinterpret_cast<jint>(&DrawGLFunction);
}
aw_contents.cc中定义了全局的函数指针变量DrawGLFunction:
extern "C" {
static AwDrawGLFunction DrawGLFunction;
static void DrawGLFunction(int view_context,
AwDrawGLInfo* draw_info,
void* spare) {
// |view_context| is the value that was returned from the java
// AwContents.onPrepareDrawGL; this cast must match the code there.
reinterpret_cast<android_webview::BrowserViewRenderer*>(view_context)->DrawGL(
draw_info);
}
}
所以aw_contents.cc中GetAwDrawGLFunction()得到的是
android_webview::InProcessViewRenderer::DrawGL()的函数地址。
设置给draw_gl_functor.cpp的全局变量g_aw_drawgl_function的就是
android_webview::InProcessViewRenderer::DrawGL()。
接着看draw_gl_functor.cpp定义的DrawGLFunctor()被android ui系统调用的过程。
draw_gl_functor.cpp
virtual status_t operator ()(int what, void* data) {
g_aw_drawgl_function(view_context_, &aw_info, NULL);
}
前面的分析我们知道draw_gl_functor.cpp定义的全局变量g_aw_drawgl_function指向的是
android_webview::InProcessViewRenderer::DrawGL()。
所以DrawGLFunctor()调用的是android_webview::InProcessViewRenderer::DrawGL()。
二.SynchronousCompositorImpl
SynchronousCompositorImpl的结构图:
SynchronousCompositorImpl的创建过程:
调用SynchronousCompositorImpl::CreateForWebContents()
实际调用的是:
WebContentsUserData::CreateForWebContents(){
DCHECK(contents);
if (!FromWebContents(contents))
contents->SetUserData(UserDataKey(), new T(contents));
}
SynchronousCompositorImpl创建后被设置给了WebContents的UserData.
SynchronousCompositorImpl的SynchronousCompositor接口都是在InProcessViewRenderer中调用的。
SynchronousCompositorImpl的SynchronousCompositor接口实现转接给了SynchronousCompositorOutputSurface。
SynchronousCompositorImpl的SynchronousCompositorOutputSurfaceDelegate接口都在SynchronousCompositorOutputSurface中调用的;
SynchronousCompositorImpl的SynchronousCompositorOutputSurfaceDelegate接口实现转接给了
SynchronousCompositorClient即InProcessViewRenderer.
所以SynchronousCompositorImpl只是SynchronousCompositorOutputSurface
与InProcessViewRenderer之间协作的中转类。
三.WebGraphicsContext3DInProcessCommandBufferImpl和GLInProcessContextImpl
WebGraphicsContext3DInProcessCommandBufferImpl结构图如下:
WebGraphicsContext3DInProcessCommandBufferImpl的实例创建过两次。
一个保存在ContextProviderInProcess实例的scoped_ptr<WebKit::WebGraphicsContext3D> context3d_变量中,
ContextProviderInProcess实例保存在ResourceProvider的scoped_refptr<cc::ContextProvider> offscreen_context_provider_变量中。
另一个WebGraphicsContext3DInProcessCommandBufferImpl实例保存在OututSurface的scoped_ptr<WebKit::WebGraphicsContext3D> context3d_变量中。
下面是WebGraphicsContext3DInProcessCommandBufferImpl实例的创建过程:
void InProcessViewRenderer::DrawGL()第一次执行时会先调用
bool InProcessViewRenderer::InitializeHwDraw().触发硬件渲染需要的类的初始化。
webkit::gpu::ContextProviderInProcess::CreateOffscreen()创建包含
WebGraphicsContext3DInProcessCommandBufferImpl的ContextProviderInProcess实例。
SynchronousCompositorOutputSurface::InitializeHwDraw()调用CreateWebGraphicsContext3D()创建了
WebGraphicsContext3DInProcessCommandBufferImpl的实例。
ContextProviderInProcess实例以及WebGraphicsContext3DInProcessCommandBufferImpl的实例作为参数传给了
OutputSurface::InitializeAndSetContext3D()。
WebGraphicsContext3DInProcessCommandBufferImpl构造函数中需要GLInProcessContext做参数。
ContextProviderInProcess实例通过OutputSurface::InitializeAndSetContext3D()
调用的LayerTreeHostImpl::DeferredInitialize()最终传给了ResourceProvider::offscreen_context_provider_变量.
WebGraphicsContext3DInProcessCommandBufferImpl的实例通过OutputSurface::InitializeAndSetContext3D()
调用OutputSurface::SetContext3D()保存在了OututSurface的scoped_ptr<WebKit::WebGraphicsContext3D> context3d_变量中。
ResourceProvider::offscreen_context_provider_变量中包含的WebGraphicsContext3DInProcessCommandBufferImpl包含的
GLInProcessContext是null.在WebGraphicsContext3DInProcessCommandBufferImpl::MaybeInitializeGL()事通过
GLInProcessContext::CreateContext()创建的。
四.InProcessCommandBuffer和CommandBufferService
GLInProcessContextImpl::Initialize()触发流程:
synchronous_compositor_output_surface.cpp中定义了全局函数:
scoped_ptr<WebKit::WebGraphicsContext3D> CreateWebGraphicsContext3D()
GLInProcessContextImpl::Initialize()创建了
InProcessCommandBuffer,GLES2CmdHelper和GLES2Implementation实例。
InProcessCommandBuffer::InitializeOnGpuThread()创建了
CommandBufferService,GLES2DecoderImpl实例。
与多进程的原生chromium的GPU进程结构不同,这里不需要创建CommandBufferProxy.
GLES2Implementation还是通过GLES2CmdHelper向CommandBuffer写入数据,这里是直接向
CommandBufferService间接包含的SharedMemory.
GLES2DecoderImpl还是在GpuScheduler的调度下从CommandBuffer中读取数据,并调用命令中的gl操作。
最后总结下渲染相关的chromium内核结构
android4.4 webview chromium实现硬件渲染的chromium内核结构,布布扣,bubuko.com