標籤:android class blog code java http
這裡只關注與原生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核心結構