您的位置:首页 > 移动开发

android4.4 webview chromium实现硬件渲染的chromium内核结构

2014-06-13 13:43 591 查看
这里只关注与原生chromium不同的几个类。

一.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内核结构

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: