android4.4 webview chromium實現硬體渲染的chromium核心結構

來源:互聯網
上載者:User

標籤: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核心結構

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.