blink渲染知识12 - 硬件渲染之触发beginframe

ThreadProxy::BeginMainFrame会触发renderlayer tree中各layer的paint.那么谁触发的BeginMainFrame?



ThreadProxy::ScheduledActionSendBeginMainFrame

-> Proxy::MainThreadTaskRunner()->PostTask(

FROM_HERE,

base::Bind(&ThreadProxy::BeginMainFrame,





硬件渲染触发的callstack:

注意,下面的callstack来自4.3机子:

#0 cc::ThreadProxy::ScheduledActionSendBeginMainFrame(this=0x641def38) at ../../cc/trees/thread_proxy.cc:691

#1 0x6078da14 in cc::Scheduler::ProcessScheduledActions

//这里只是向webcore申请paint操作。

(this=this@entry=0x64993cb8) at../../cc/scheduler/scheduler.cc:665

#2 0x6078df92 in cc::Scheduler::BeginImplFrame

//此函数不光要向webcore线程发出申请一paint操作。还要自己构造合成一个frame.

(this=this@entry=0x64993cb8, args=...) at../../cc/scheduler/scheduler.cc:520

#3 0x6078e304 in cc::Scheduler::BeginFrame(this=0x64993cb8, args=...) at ../../cc/scheduler/scheduler.cc:426

#4 0x6079795e in cc::LayerTreeHostImpl::BeginFrame(this=<optimized out>, args=...) at../../cc/trees/layer_tree_host_impl.cc:1408

#5 0x60b97c16 incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x642f4868, transform=..., viewport=..., clip=...,viewport_rect_for_tile_priority=...,

transform_for_tile_priority=..., hardware_draw=<optimizedout>, hardware_draw@entry=true) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:227

#6 0x60b97e5e incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x642f4868, surface_size=..., transform=..., viewport=...,clip=..., viewport_rect_for_tile_priority=...,

transform_for_tile_priority=...) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:178

#7 0x60b977b0 in content::SynchronousCompositorImpl::DemandDrawHw

//这个是同步compositor.此函数就会返回一个compositorframe.

this=0x6498e6c0, surface_size=..., transform=..., viewport=...,clip=..., viewport_rect_for_tile_priority=...,transform_for_tile_priority=...)

at../../content/browser/android/in_process/synchronous_compositor_impl.cc:139

#8 0x607f6cf0 inandroid_webview::BrowserViewRenderer::OnDrawHardware

注意,这个函数被调用的前提是我们是4.3,4.4系统,因为这个系统上,ui线程会调用drawGl,所以可以让他调用BrowserViewRender来合成一个compositorframe. 在5.0系统上,应该又真正的ui线程去合成compositorframe,而不应该在drawGl执行时干这件事情。

BrowserViewRender据说就是处理webview相关的一切绘图操作的类。此函数会掉用browser的childcompositor合成出一份compositorframe并保存到draw_gl_input里面。供后续使用,后续先要commit他。

(this=this@entry=0x6498e540)at ../../android_webview/browser/browser_view_renderer.cc:304

#9 0x60e5a5f8 in android_webview::AwContents::DrawGL(this=0x6498e458, draw_info=0xbec91240) at../../android_webview/native/aw_contents.cc:429//这个是我们注册给系统的drawGL函数。在4.4,4.3上是ui线程调用,在androidL上是一个独立的系统的render线程调用。

#10 0x60f5e816 in draw_gl_normal(this=0x641ffeb0, data=<optimized out>, what=<optimizedout>) at../../third_party/android_plat_support/draw_gl_functor.cpp:139

#11 android::(anonymous namespace)::DrawGLFunctor::operator()(this=0x641ffeb0, what=<optimized out>, data=<optimizedout>) at../../third_party/android_plat_support/draw_gl_functor.cpp:60//怀疑这个函数被注册到系统,底层。

#12 0x40bf40b2 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#13 0x40be80b0 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#14 0x40be686c in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#15 0x40be6798 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#16 0x40beee90 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#17 0x4024caf6 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libandroid_runtime.so

#18 0x408dec50 in dvmPlatformInvoke () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#19 0x4090eed2 in dvmCallJNIMethod(unsigned int const*, JValue*,Method const*, Thread*) () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#20 0x408e8064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#21 0x408e8064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so





关闭tab时,硬件渲染引发的callstack:

#0 cc::ThreadProxy::ScheduledActionSendBeginMainFrame(this=0x641def38) at ../../cc/trees/thread_proxy.cc:691

#1 0x6078da14 in cc::Scheduler::ProcessScheduledActions(this=0x64993cb8) at ../../cc/scheduler/scheduler.cc:665

#2 0x6078daca in cc::Scheduler::SetNeedsCommit (this=<optimizedout>) at ../../cc/scheduler/scheduler.cc:169

#3 0x607a2928 in cc::ThreadProxy::SetNeedsCommitOnImplThread(this=0x641def38) at ../../cc/trees/thread_proxy.cc:400

#4 0x6079ba64 in cc::LayerTreeHostImpl::ReleaseGL(this=0x64964948) at ../../cc/trees/layer_tree_host_impl.cc:2200

#5 0x6076a270 in cc::OutputSurface::ReleaseGL (this=<optimizedout>) at ../../cc/output/output_surface.cc:170

#6 0x60b97afe incontent::SynchronousCompositorOutputSurface::ReleaseHwDraw(this=<optimized out>) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:157

#7 0x60b979c8 incontent::SynchronousCompositorImpl::ReleaseHwDraw (this=<optimizedout>) at../../content/browser/android/in_process/synchronous_compositor_impl.cc:114

#8 0x607f6682 inandroid_webview::BrowserViewRenderer::ReleaseHardware(this=this@entry=0x6498e540) at../../android_webview/browser/browser_view_renderer.cc:543

#9 0x60e5a82c inandroid_webview::AwContents::OnDetachedFromWindow (this=0x6498e458,env=<optimized out>, obj=<optimized out>) at../../android_webview/native/aw_contents.cc:956

#10 0x408dec50 in dvmPlatformInvoke () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#11 0x4090eed2 in dvmCallJNIMethod(unsigned int const*, JValue*,Method const*, Thread*) () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#12 0x409108be in dvmResolveNativeMethod(unsigned int const*,JValue*, Method const*, Thread*) () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#13 0x408e8064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#14 0x408e8064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

Backtrace stopped: previous frame identical to this frame (corruptstack?)





还可能出现的软件渲染触发的callstack:

#0 cc::ThreadProxy::ScheduledActionSendBeginMainFrame(this=0x641def38) at ../../cc/trees/thread_proxy.cc:691

#1 0x6078da14 in cc::Scheduler::ProcessScheduledActions(this=this@entry=0x64993cb8) at ../../cc/scheduler/scheduler.cc:665

#2 0x6078df92 in cc::Scheduler::BeginImplFrame(this=this@entry=0x64993cb8, args=...) at../../cc/scheduler/scheduler.cc:520

#3 0x6078e304 in cc::Scheduler::BeginFrame (this=0x64993cb8,args=...) at ../../cc/scheduler/scheduler.cc:426

#4 0x6079795e in cc::LayerTreeHostImpl::BeginFrame(this=<optimized out>, args=...) at../../cc/trees/layer_tree_host_impl.cc:1408

#5 0x60b97c16 incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x642f4868, transform=..., viewport=..., clip=...,viewport_rect_for_tile_priority=...,

transform_for_tile_priority=..., hardware_draw=<optimizedout>, hardware_draw@entry=false) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:227

#6 0x60b97f28 incontent::SynchronousCompositorOutputSurface::DemandDrawSw(this=0x642f4868, canvas=<optimized out>) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:202

#7 0x60b97800 in content::SynchronousCompositorImpl::DemandDrawSw(this=0x6498e6c0, canvas=<optimized out>) at../../content/browser/android/in_process/synchronous_compositor_impl.cc:155

#8 0x607f6a14 inandroid_webview::BrowserViewRenderer::CompositeSW(this=this@entry=0x6498e540, canvas=canvas@entry=0xbec912c8) at../../android_webview/browser/browser_view_renderer.cc:846

#9 0x607f7796 inandroid_webview::BrowserViewRenderer::ForceFakeCompositeSW(this=this@entry=0x6498e540) at../../android_webview/browser/browser_view_renderer.cc:840

#10 0x607f7914 inandroid_webview::BrowserViewRenderer::FallbackTickFired(this=0x6498e540) at../../android_webview/browser/browser_view_renderer.cc:826

#11 0x607f5afa in Run (object=<optimized out>,this=0xbec91420) at ../../base/bind_internal.h:134

#12 MakeItSo (a1=<optimized out>, runnable=...) at../../base/bind_internal.h:871

#13 base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(android_webview::BrowserViewRenderer::*)()>, void(android_webview::BrowserViewRenderer*), void (base::internal::Unret

ainedWrapper<android_webview::BrowserViewRenderer>)>,void(android_webview::BrowserViewRenderer*)>::Run(base::internal::BindStateBase*)(base=<optimized out>) at ../../base/bind_internal.h:1169

#14 0x6055cdf2 in Run (this=<optimized out>) at../../base/callback.h:401

#15 base::CancelableCallback<void ()>::Forward()(this=<optimized out>) at ../../base/cancelable_callback.h:106

#16 0x6055ce38 in Run (object=<optimized out>,this=0xbec91438) at ../../base/bind_internal.h:134

#17 MakeItSo (weak_ptr=..., runnable=...) at../../base/bind_internal.h:882

#18 base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(base::CancelableCallback<void ()>::*)()>, void(base::CancelableCallback<void ()>*), void(base::WeakPtr<base::Cancela

bleCallback<void ()> >)>, void(base::CancelableCallback<void()>*)>::Run(base::internal::BindStateBase*) (base=0x64215488)at ../../base/bind_internal.h:1169

#19 0x6100e280 in Run (this=0xbec91550) at../../base/callback.h:401

#20 base::MessageLoop::RunTask (this=this@entry=0x5c9415f8,pending_task=...) at ../../base/message_loop/message_loop.cc:464

#21 0x6100e338 in base::MessageLoop::DeferOrRunPendingTask(this=this@entry=0x5c9415f8, pending_task=...) at../../base/message_loop/message_loop.cc:482

#22 0x6100ebac in base::MessageLoop::DoDelayedWork(this=0x5c9415f8, next_delayed_work_time=0xbec91598) at../../base/message_loop/message_loop.cc:634

#23 0x60ff1b46 in DoRunLoopOnce(delayed_scheduled_time_ticks=34676111993, native_delegate=<optimizedout>, obj=0x4330001d, env=0x41f93cf0) at../../base/message_loop/message_pump_android.cc:60

#24Java_com_jetpack_dolphin_webkit_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce(env=0x41f93cf0, jcaller=0x4330001d,messagePumpDelegateNative=<optimized out>,

delayedScheduledTimeTicks=34676111993) atgen/base/jni/SystemMessageHandler_jni.h:42

#25 0x408dec50 in dvmPlatformInvoke () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#26 0x4090eed2 in dvmCallJNIMethod(unsigned int const*, JValue*,Method const*, Thread*) () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#27 0x408e8064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#28 0x408e8064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so



看看DrawGLFunctor的使用和调用。

Native层和java层都有DrawGLFunctor他们相互关联。

native的在third_party/android_plat_support目录下。


DrawGLFunctor.java类的requestDrawGL函数会将native的drawGL操作注册进系统,系统会在合适时间调用。


AwContents.java有函数requestDrawGL会被nativie调用。

->NativeGLDelegate接口的requestDrawGL函数,这个接口实际上是WebViewNativeGLDelegate。,定义在webviewchromium.java中

->建立DrawGLFunctor并调用DrawGLFunctor.requestDrawGL().

->delegate的函数,delegate是ProxyDelegate(Api21CompatibilityDelegate)

ProxyDelegate继承自webviewDelegate,并且他只是一个adapter,他含有真正的delegate,

Api21CompatibilityDelegate。Api21CompatibilityDelegate也继承自WebViewDelegate,并且定义在WebViewDelegateFactory.java里。


->WebViewDelegateFactory.java中Api21CompatibilityDelegate的:

@Override

public int callDrawGlFunction(Canvascanvas, long nativeDrawGLFunctor) {

try {

// DOLPHIN CHANGE BEGIN

if (mDetachFunctorMethod == null) return -1;


if (android.os.Build.VERSION.SDK_INT < 20) {

return(Integer)mCallDrawGLFunctionMethod.invoke(canvas,(int)nativeDrawGLFunctor);

}

// DOLPHIN CHANGE END

return(Integer)mCallDrawGLFunctionMethod.invoke(canvas,nativeDrawGLFunctor);//nativeDrawGLFunctor至此被传进入了系统内部。这样系统就会调用native的DrawGLFunctor。

} catch (Exception e) {

throw new RuntimeException("Invalid reflection",e);

}

}


或者

publicvoid invokeDrawGlFunctor(ViewcontainerView, long nativeDrawGLFunctor,

boolean waitForCompletion) {

try {

Object viewRootImpl =mGetViewRootImplMethod.invoke(containerView);

if (viewRootImpl != null &&mInvokeFunctorMethod != null) {

mInvokeFunctorMethod.invoke(viewRootImpl,nativeDrawGLFunctor,waitForCompletion);

}

} catch (Exception e) {

throw new RuntimeException("Invalid reflection",e);

}

}


上面的mCallDrawGLFunctionMethod可能是类android.view.HardwareCanvas的callDrawGLFunction成员,或者callDrawGLFunction2成员。

上面的mInvokeFunctorMethod可能是android.view.ViewRootImpl类的invokeFunctor成员。



那么awContents.cc的requestDrawGL函数被调用的stack;这里只是要求系统调用gl操作而发出一个申请。

#0 android_webview::AwContents::RequestDrawGL(this=0x5a7627a0,

canvas=0x70600021, wait_for_completion=false) at../../android_webview/native/aw_contents.cc:797

#1 0x61037086 in android_webview::BrowserViewRenderer::OnDraw

//这个函数要在childcompositor这边合成一个compositorframe, 此函数是ui线程执行。所以他可以合成compositorframe. 然后向系统注册申请下一个gl操作。

(this=this@entry=0x5a762888,java_canvas=java_canvas@entry=0x70600021,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

global_visible_rect=...) at../../android_webview/browser/browser_view_renderer.cc:239

#2 0x6169858e in android_webview::AwContents::OnDraw(this=0x5a7627a0, env=<optimized out>, obj=<optimized out>,canvas=0x70600021,is_hardware_accelerated=1'\001', scroll_x=0, scroll_y=0, visible_left=0,

visible_top=220, visible_right=720, visible_bottom=1184) at../../android_webview/native/aw_contents.cc:1058

#3 0x4092bc50 in dvmPlatformInvoke () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#4 0x4095bed2 in dvmCallJNIMethod(unsigned int const*, JValue*, Methodconst*, Thread*) () from /tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#5 0x4095d8be in dvmResolveNativeMethod(unsigned int const*, JValue*,Method const*, Thread*) () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#6 0x40935064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so

#7 0x40935064 in dvmJitToInterpNoChain () from/tmp/tshao-adb-gdb-libs/system/lib/libdvm.so





下面的逻辑可能不正确

应该是来自java层的,下面是UI线程。

当native觉得网页内容有变化,会调用WebView的invalidate函数,告知系统,然后系统会调用onDraw到我们的view,然后我们会注册一个DrawGL到系统,并请求系统在合适的时候调用DrawGL,从而触发并推动一次渲染流水线开始work.

WebView.onDraw

->WebViewChromium.onDraw

AwContents.java,onDraw(canvas)

-----------native 在下面---------------

awContents.cc,onDraw

->BrowserViewRenderer::OnDraw

->AwContents::requestDrawGL,5.0新系统可能直接调用BrowserViewRenderer::OnDrawHardware来调用childcompositor合成一个compositorframe之后,才调用requestdraw gl

->Java_AwContents_requestDrawGL,

-----------------下面java层------------------

AwContents.java,requestDrawGL

->WebViewNativeGLDelegate.requestDrawGL

->WebViewDelegateFactory.java里callDrawGlFunction/invokeDrawGlFunctor。

将native的DrawGLFunctor注册进系统....并调用系统的drawGl.

这里是通过调用android.view.HardwareCanvas一个隐藏api的callDrawGLFunction方法,把我们的一个native的函数DrawGLFunctor传递进去给系统的。


注意,此时函数就会立即返回,并且能够返回一份canvas数据,这个canvas数据应该是之前的历史数据。

但同时,又向系统发送了一个请求绘制的申请。而系统会在合适的时候调用之前我们注册到系统里面的函数。

-------------------系统--------------下面是native---------

一定时间之后,系统调用我们注册的函数:注意,此时所处的线程和之前我们应用向系统发送绘制申请的线程是一个,都是ui线程。4.3上是这样的,但是androidL应该就是系统的render线程调用这个callback.


(注:HardwareCanvas允许客户端提供自己的GL回调函数,Android View系统在重放(playback)显示列表绘制View层次时会调用这个回调函数,在AndroidFramework内部实现中,当开始绘制HardwareCanvas时,当前GL上下文会绑定HardwareCanvas的framebuffer对象,所以GL回调函数中所有的GL命令实际上在操作HardwareCanvas的framebuffer对象).那么在drawGl函数中,parentcompositor合成所有内容,并绘制到glcontext的话,就会绘制到framebuffer上。

->DrawGLFunctor::operator()

->draw_gl_normal, 系统提供了尺寸,clip等数据,还有mode.这个函数指针来自于WebViewChromiumFactoryProvider.java中的initPlatSupportLibrary()函数中的DrawGLFunctor.setChromiumAwDrawGLFunction(AwContents.getAwDrawGLFunction());。本质上来于AwContents.

->AwContents.cc中的DrawGLFunction()

->AwContents::DrawGL 该看这里了。

如果是4.4,4.3先调用BrowserViewRender::onDrawHardware,否则如果5.0就不需要再调用BrowserViewRender::onDrawHardware了,因为childcompositor的合成工作不再drawGL下执行。

创建HardwareRenderer,再调用HardwareRenderer::DrawGL.


注意,4.3/4.4上才会调用下面操作:

->BrowserViewRenderer::OnDrawHardware

->SynchronousCompositorImpl::DemandDrawHw

->SynchronousCompositorOutputSurface::DemandDrawHw

本函数除了调用下面的invokeComposite之外,还会返回一个compositorFrame,并把它设置到sharedRenderState的drawgl input里面。返回的这个frame应该是之前弄好的。并且来自于:voidSynchronousCompositorOutputSurface::SwapBuffers(frame)中的frame.



->:SynchronousCompositorOutputSurface::InvokeComposite

->cc::LayerTreeHostImpl::BeginFrame

->cc::Scheduler::BeginFrame

->cc::Scheduler::BeginImplFrame

推动statemachine

->cc::Scheduler::ProcessScheduledActions

->cc::ThreadProxy::ScheduledActionSendBeginMainFrame//这里schedule一个task,要求beginFrame,要求内核要开始绘制。当然是要把请求发给另外的线程。应该是webcore线程。




下面callstack是4.3/4.4上执行drawGL时,顺带执行了childconmpositor的合成并触发webcore线程的BeginFrame的callstack:


#0 cc::ThreadProxy::ScheduledActionSendBeginMainFrame(this=0x641def38) at ../../cc/trees/thread_proxy.cc:691

#1 0x6078da14 in cc::Scheduler::ProcessScheduledActions(this=this@entry=0x64993cb8) at ../../cc/scheduler/scheduler.cc:665

#2 0x6078df92 in cc::Scheduler::BeginImplFrame(this=this@entry=0x64993cb8, args=...) at../../cc/scheduler/scheduler.cc:520

#3 0x6078e304 in cc::Scheduler::BeginFrame(this=0x64993cb8, args=...) at ../../cc/scheduler/scheduler.cc:426

#4 0x6079795e in cc::LayerTreeHostImpl::BeginFrame(this=<optimized out>, args=...) at../../cc/trees/layer_tree_host_impl.cc:1408

#5 0x60b97c16 incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x642f4868, transform=..., viewport=..., clip=...,viewport_rect_for_tile_priority=...,

transform_for_tile_priority=..., hardware_draw=<optimizedout>, hardware_draw@entry=true) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:227

#6 0x60b97e5e incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x642f4868, surface_size=..., transform=..., viewport=...,clip=..., viewport_rect_for_tile_priority=...,

transform_for_tile_priority=...) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:178

#7 0x60b977b0 in content::SynchronousCompositorImpl::DemandDrawHw(this=0x6498e6c0, surface_size=..., transform=..., viewport=...,clip=..., viewport_rect_for_tile_priority=...,transform_for_tile_priority=...)

at../../content/browser/android/in_process/synchronous_compositor_impl.cc:139

#8 0x607f6cf0 inandroid_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0x6498e540) at../../android_webview/browser/browser_view_renderer.cc:304

#9 0x60e5a5f8 in android_webview::AwContents::DrawGL(this=0x6498e458, draw_info=0xbec91240) at../../android_webview/native/aw_contents.cc:429

#10 0x60f5e816 indraw_gl_normal (this=0x641ffeb0,data=<optimized out>,




那么BeginFrame发送给了谁?谁处理?干设么事情?





在5.0上调试到的callstacki:

可以看出,5.0上的callstack就较为清晰:ui线程的onDraw会发送一个请求beginFrame的操作。


#0 cc::ThreadProxy::ScheduledActionSendBeginMainFrame(this=0x94fa71c0) at../../cc/trees/thread_proxy.cc:691 //这里发送一个请求beginMainFrame

#1 0x9d226b3c in cc::Scheduler::ProcessScheduledActions(this=this@entry=0x98aec880) at ../../cc/scheduler/scheduler.cc:665

#2 0x9d2270ba in cc::Scheduler::BeginImplFrame(this=this@entry=0x98aec880, args=...) at../../cc/scheduler/scheduler.cc:520

#3 0x9d22742c in cc::Scheduler::BeginFrame(this=0x98aec880, args=...) at ../../cc/scheduler/scheduler.cc:426

#4 0x9d230a86 in cc::LayerTreeHostImpl::BeginFrame(this=<optimized out>, args=...) at../../cc/trees/layer_tree_host_impl.cc:1408

#5 0x9d630eee incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x94fa7700, transform=..., viewport=..., clip=...,viewport_rect_for_tile_priority=...,

transform_for_tile_priority=..., hardware_draw=<optimized out>,hardware_draw@entry=true) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:227

#6 0x9d631136 incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x94fa7700, surface_size=..., transform=..., viewport=...,clip=..., viewport_rect_for_tile_priority=...,

transform_for_tile_priority=...) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:178

#7 0x9d630a88 in content::SynchronousCompositorImpl::DemandDrawHw(this=0xa0319f60, surface_size=..., transform=..., viewport=...,clip=..., viewport_rect_for_tile_priority=...,transform_for_tile_priority=...)

at../../content/browser/android/in_process/synchronous_compositor_impl.cc:139

#8 0x9d290088 in android_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0xaf2584e8,java_canvas=java_canvas@entry=0xbec49110) at../../android_webview/browser/browser_view_renderer.cc:374

#9 0x9d290194 in android_webview::BrowserViewRenderer::OnDraw(this=this@entry=0xaf2584e8,java_canvas=java_canvas@entry=0xbec49110,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

global_visible_rect=...) at../../android_webview/browser/browser_view_renderer.cc:241

#100x9d8f19ce in android_webview::AwContents::OnDraw(this=0xaf258400, env=<optimized out>, obj=<optimized out>,canvas=0xbec49110, is_hardware_accelerated=1 '\001', scroll_x=0,scroll_y=0, visible_left=0,

visible_top=330, visible_right=1080, visible_bottom=1776) at../../android_webview/native/aw_contents.cc:1058

#110xa09e527a in ?? ()

#120xa09e527a in ?? ()




那么5.0上的awContents.cc里面的DrawGL还会有人调用么?

会的,并且的确是本进程的系统给创建的render线程调用的,callstack:

#0 android_webview::AwContents::DrawGL(this=0xaf258400, draw_info=0xa1fffa58) at../../android_webview/native/aw_contents.cc:370

#1 0x9d9f7c4a in draw_gl_50(this=0xac3e0fa8, data=0x0, what=<optimized out>) at../../third_party/android_plat_support/draw_gl_functor.cpp:103

#2 android::(anonymous namespace)::DrawGLFunctor::operator()(this=0xac3e0fa8, what=<optimized out>, data=0x0) at../../third_party/android_plat_support/draw_gl_functor.cpp:58

#3 0xb66dd5c0 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#4 0xb66de53e in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#5 0xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#6 0xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#7 0xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#8 0xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#9 0xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#100xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#110xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#120xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#130xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#140xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#150xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#160xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#170xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#180xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#190xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#200xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#210xb66de618 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#220xb66de54a in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#230xb66de58e inandroid::uirenderer::RenderNode::prepareTree(android::uirenderer::TreeInfo&)() from /tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#240xb6e47bb4 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libandroid_runtime.so

#250xb66e6ace in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#260xb66e76ac in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#270xb66e7738 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#280xb66e927c inandroid::uirenderer::renderthread::RenderThread::threadLoop()() from /tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#290xb6c9f4d6 in android::Thread::_threadLoop(void*) () from/tmp/tshao-adb-gdb-libs/system/lib/libutils.so

#300xb6e29f4e in android::AndroidRuntime::javaThreadShell(void*) () from/tmp/tshao-adb-gdb-libs/system/lib/libandroid_runtime.so

#310xb6c9f046 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libutils.so

#320xb6ee42e4 in __pthread_start(void*) () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so

#330xb6ee22d4 in __start_thread () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so

#340x00000000 in ?? ()


这个又是怎么注册到5.0里面的,并且他干了什么?

Requestdrawgl的callstack:

这此之所以要requestdrawgl是因为ui线程在onDraw时,要创建gpumem buffer, 于是就创建了一个task,在inprocess command buffer里面queue了一个task,并申请drawgl操作。queue的操作是voidGpuControlService::RegisterGpuMemoryBuffer(,

下面是发起requestDrawGL的一个场景:


#0 android_webview::AwContents::RequestDrawGL(this=0xaf258400, canvas=0x0, wait_for_completion=false) at../../android_webview/native/aw_contents.cc:797

#1 0x9d2984f4 inandroid_webview::SharedRendererState::ClientRequestDrawGLOnUIThread(this=this@entry=0xaf25843c) at../../android_webview/browser/shared_renderer_state.cc:142

#2 0x9d2985ec inandroid_webview::SharedRendererState::ClientRequestDrawGL(this=0xaf25843c) at../../android_webview/browser/shared_renderer_state.cc:113

#3 0x9d2910ea inandroid_webview::DeferredGpuCommandService::RequestProcessGL() at../../android_webview/browser/deferred_gpu_command_service.cc:79

#4 0x9d29150c inandroid_webview::DeferredGpuCommandService::ScheduleTask(base::Callback<void()> const&) (this=0xa03c5ee0, task=...) at../../android_webview/browser/deferred_gpu_command_service.cc:105

#5 0x9e01f328 in QueueTask(task=..., this=0x94efe740) at../../gpu/command_buffer/service/in_process_command_buffer.h:177

#6 gpu::InProcessCommandBuffer::CreateGpuMemoryBuffer(this=0x94efe740, width=384, height=384, internalformat=32856,usage=30961, id=0xbec48884)

at../../gpu/command_buffer/service/in_process_command_buffer.cc:731//要创建gpucommand buffer,并把taskqueue到队列里面等待renderthread去处理和gl相关的操作。


#7 0x9d47d910 in gpu::gles2::GpuMemoryBufferTracker::CreateBuffer(this=0x96497ad8, width=width@entry=384,height=height@entry=384, internalformat=internalformat@entry=32856,usage=usage@entry=30961)

at ../../gpu/command_buffer/client/gpu_memory_buffer_tracker.cc:31

#8 0x9d47634e ingpu::gles2::GLES2Implementation::CreateImageCHROMIUMHelper(this=0x98aac200, width=384, height=384, internalformat=32856,usage=30961)

at ../../gpu/command_buffer/client/gles2_implementation.cc:4013

#9 0x9d218f1a in cc::ResourceProvider::AcquireImage(this=this@entry=0xa22d1e80, resource=resource@entry=0x96468908) at../../cc/resources/resource_provider.cc:2162

#100x9d21a1e8 in cc::ResourceProvider::MapImageRasterBuffer(this=0xa22d1e80, id=<optimized out>) at../../cc/resources/resource_provider.cc:1776

#110x9d2200fa in cc::(anonymousnamespace)::RasterTaskImpl::ScheduleOnOriginThread (this=0xac384970,client=<optimized out>) at../../cc/resources/tile_manager.cc:77

#120x9d217444 in cc::RasterWorkerPool::ScheduleTasksOnOriginThread(client=client@entry=0x956b5fa8, graph=graph@entry=0x956b5fd4) at../../cc/resources/raster_worker_pool.cc:238

#130x9d20b83e in cc::ImageRasterWorkerPool::ScheduleTasks(this=0x956b5fa0, queue=0x98aecb2c) at../../cc/resources/image_raster_worker_pool.cc:113

#140x9d2236c8 in cc::TileManager::ScheduleTasks (this=0x98aeca00,tiles_that_need_to_be_rasterized=...) at../../cc/resources/tile_manager.cc:963

#150x9d22301c in cc::TileManager::ManageTiles (this=0x98aeca00,state=...) at ../../cc/resources/tile_manager.cc:662

#160x9d230dfe in cc::LayerTreeHostImpl::ManageTiles (this=0x964f1e00) at../../cc/trees/layer_tree_host_impl.cc:431

#170x9d23bf8e in cc::ThreadProxy::ScheduledActionManageTiles(this=0x94fa71c0) at ../../cc/trees/thread_proxy.cc:1165

#180x9d226b3c in cc::Scheduler::ProcessScheduledActions(this=this@entry=0x98aec880) at ../../cc/scheduler/scheduler.cc:665

#190x9d226e70 in cc::Scheduler::OnBeginImplFrameDeadline(this=this@entry=0x98aec880) at ../../cc/scheduler/scheduler.cc:584

#200x9d226eb0 in cc::Scheduler::ScheduleBeginImplFrameDeadline(this=this@entry=0x98aec880, deadline=...) at../../cc/scheduler/scheduler.cc:559

#210x9d2270dc in cc::Scheduler::BeginImplFrame(this=this@entry=0x98aec880, args=...) at../../cc/scheduler/scheduler.cc:524

#220x9d22742c in cc::Scheduler::BeginFrame(this=0x98aec880, args=...) at ../../cc/scheduler/scheduler.cc:426

#230x9d230a86 in cc::LayerTreeHostImpl::BeginFrame(this=<optimized out>, args=...) at../../cc/trees/layer_tree_host_impl.cc:1408

#240x9d630eee incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x94fa7700, transform=..., viewport=..., clip=...,viewport_rect_for_tile_priority=...,

transform_for_tile_priority=..., hardware_draw=<optimized out>,hardware_draw@entry=true) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:227

#250x9d631136 incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x94fa7700, surface_size=..., transform=...,viewport=..., clip=..., viewport_rect_for_tile_priority=...,

transform_for_tile_priority=...) at../../content/browser/android/in_process/synchronous_compositor_output_surface.cc:178

#260x9d630a88 in content::SynchronousCompositorImpl::DemandDrawHw(this=0xa0319f60, surface_size=..., transform=..., viewport=...,clip=..., viewport_rect_for_tile_priority=...,transform_for_tile_priority=...)

at../../content/browser/android/in_process/synchronous_compositor_impl.cc:139

#270x9d290088 in android_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0xaf2584e8,java_canvas=java_canvas@entry=0xbec49110) at../../android_webview/browser/browser_view_renderer.cc:374

#280x9d290194 in android_webview::BrowserViewRenderer::OnDraw(this=this@entry=0xaf2584e8,java_canvas=java_canvas@entry=0xbec49110,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

global_visible_rect=...) at../../android_webview/browser/browser_view_renderer.cc:241

#290x9d8f19ce in android_webview::AwContents::OnDraw(this=0xaf258400, env=<optimized out>, obj=<optimized out>,canvas=0xbec49110, is_hardware_accelerated=1 '\001', scroll_x=0,scroll_y=0, visible_left=0,

visible_top=330, visible_right=1080, visible_bottom=1776) at../../android_webview/native/aw_contents.cc:1058

#300xa09e527a in ?? ()

#310xa09e527a in ?? ()



那么我们看看voidGpuControlService::RegisterGpuMemoryBuffer(这个操作是不是就是在renderthread上执行的?

的确,马上被renderthread执行了:

下面是DrawGL被调用并执行任务的一个场景:

#0 gpu::GpuControlService::RegisterGpuMemoryBuffer(this=0x95678f40, id=7, buffer=..., width=384, height=384,internalformat=32856) at../../gpu/command_buffer/service/gpu_control_service.cc:39

#1 0x9e01c1ac in Run (a5=@0x956ffdc0: 32856, a4=@0x956ffdbc: 384,a3=@0x956ffdb8: 384, a2=..., a1=@0x956ffd94: 7, object=<optimizedout>, this=0xa1fffaf8) at ../../base/bind_internal.h:452

#2 MakeItSo (a6=@0x956ffdc0: 32856, a5=@0x956ffdbc: 384,a4=@0x956ffdb8: 384, a3=..., a2=@0x956ffd94: 7, a1=<optimizedout>, runnable=...) at ../../base/bind_internal.h:1028

#3 base::internal::Invoker<6,base::internal::BindState<base::internal::RunnableAdapter<void(gpu::GpuControlService::*)(int, gfx::GpuMemoryBufferHandle, unsignedint, unsigned int, unsigned int)>, void (gpu::Gpu

ControlService*,int, gfx::GpuMemoryBufferHandle, unsigned int, unsigned int, unsignedint), void(base::internal::UnretainedWrapper<gpu::GpuControlService>,int, gfx::GpuMemoryBufferHandle, unsigned int, unsigned

int, unsigned int)>, void (gpu::GpuControlService*, int,gfx::GpuMemoryBufferHandle, unsigned int, unsigned int, unsignedint)>::Run(base::internal::BindStateBase*) (base=0x956ffd80)

at ../../base/bind_internal.h:2126

#4 0x9d291334 in Run (this=0xa1fffb20) at ../../base/callback.h:401

#5 android_webview::DeferredGpuCommandService::RunTasks(this=0xa03c5ee0) at../../android_webview/browser/deferred_gpu_command_service.cc:182

#6 0x9d29138a in android_webview::ScopedAllowGL::ScopedAllowGL

//在这个变量构造后,设置了全局flag后才允许执行gl操作。

(this=0xa1fffb5c)at ../../android_webview/browser/deferred_gpu_command_service.cc:34

#7 0x9d8f3a9e in android_webview::AwContents::DrawGL(this=0xaf258400, draw_info=0xa1fffc28) at../../android_webview/native/aw_contents.cc:390

#8 0x9d9f7c4a in draw_gl_50 (this=0xac3e0fa8, data=0x0, what=<optimizedout>) at../../third_party/android_plat_support/draw_gl_functor.cpp:103

#9 android::(anonymous namespace)::DrawGLFunctor::operator()(this=0xac3e0fa8, what=<optimized out>, data=0x0) at../../third_party/android_plat_support/draw_gl_functor.cpp:58

#100xb66e01ea in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#110xb66e695e in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#120xb66e7f68 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#130xb66e7ea6 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#140xb66e927c inandroid::uirenderer::renderthread::RenderThread::threadLoop()() from /tmp/tshao-adb-gdb-libs/system/lib/libhwui.so

#150xb6c9f4d6 in android::Thread::_threadLoop(void*) () from/tmp/tshao-adb-gdb-libs/system/lib/libutils.so

#160xb6e29f4e in android::AndroidRuntime::javaThreadShell(void*) () from/tmp/tshao-adb-gdb-libs/system/lib/libandroid_runtime.so

#170xb6c9f046 in ?? () from/tmp/tshao-adb-gdb-libs/system/lib/libutils.so

#180xb6ee42e4 in __pthread_start(void*) () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so

#190xb6ee22d4 in __start_thread () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so

#200x00000000 in ?? ()


那么既然我们由此可以看出,ui线程,或者别的线程,需要gl操作时,都会requestdrawgl,并把任务queue到一个task里面,然后系统的render线程会调用我们注册的drawGl函数从执行相关gl操作。


那么我们再看看beginFrame的实际操作是在哪里执行的?

#0 cc::ThreadProxy::BeginMainFrame(this=0x94fa71c0, begin_main_frame_state=...) at../../cc/trees/thread_proxy.cc:720

#1 0x9d23f606 in Run (a1=..., object=<optimized out>,this=0x9ac01ab8) at ../../base/bind_internal.h:190

#2 base::internal::InvokeHelper<true, void,base::internal::RunnableAdapter<void(cc::ThreadProxy::*)(scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::ThreadProxy::BeginMainFrame

AndCommitState>>)>, void (base::WeakPtr<cc::ThreadProxy> const&,scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::ThreadProxy::BeginMainFrameAndCommitState>>)>::MakeItSo(base::i

nternal::RunnableAdapter<void(cc::ThreadProxy::*)(scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::ThreadProxy::BeginMainFrameAndCommitState>>)>, base::WeakPtr<cc::ThreadProxy>

const&,scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::ThreadProxy::BeginMainFrameAndCommitState>>) (runnable=..., weak_ptr=..., a2=...) at../../base/bind_internal.h:909

#3 0x9d23f6be in base::internal::Invoker<2,base::internal::BindState<base::internal::RunnableAdapter<void(cc::ThreadProxy::*)(scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::T

hreadProxy::BeginMainFrameAndCommitState>>)>, void (cc::ThreadProxy*,scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::ThreadProxy::BeginMainFrameAndCommitState>>), void (base::

WeakPtr<cc::ThreadProxy>,base::internal::PassedWrapper<scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::ThreadProxy::BeginMainFrameAndCommitState>> >)>, void (cc::ThreadProxy*,

scoped_ptr<cc::ThreadProxy::BeginMainFrameAndCommitState,base::DefaultDeleter<cc::ThreadProxy::BeginMainFrameAndCommitState>>)>::Run(base::internal::BindStateBase*) (base=0x956653e0)

at ../../base/bind_internal.h:1253

#4 0x9daa7810 in Run (this=0x9ac01cb0) at ../../base/callback.h:401

#5 base::MessageLoop::RunTask (this=this@entry=0xa206f280,pending_task=...) at ../../base/message_loop/message_loop.cc:464

#6 0x9daa78c8 in base::MessageLoop::DeferOrRunPendingTask(this=this@entry=0xa206f280, pending_task=...) at../../base/message_loop/message_loop.cc:482

#7 0x9daa7fde in base::MessageLoop::DoWork (this=0xa206f280) at../../base/message_loop/message_loop.cc:596

#8 0x9daa852e in base::MessagePumpDefault::Run (this=0x96286028,delegate=0xa206f280) at../../base/message_loop/message_pump_default.cc:32

#9 0x9daa7c02 in base::MessageLoop::RunHandler (this=0xa206f280) at../../base/message_loop/message_loop.cc:407

#100x9daaf1a0 in base::RunLoop::Run (this=this@entry=0x9ac01d20) at../../base/run_loop.cc:49

#110x9daa7214 in base::MessageLoop::Run (this=<optimized out>) at../../base/message_loop/message_loop.cc:300

#120x9dab7cfe in base::Thread::ThreadMain(this=0xa22ceab0) at ../../base/threading/thread.cc:225 //这个是webcore主线程。

#130x9dab5b26 in base::(anonymous namespace)::ThreadFunc(params=<optimized out>) at../../base/threading/platform_thread_posix.cc:80

#140xb6ee42e4 in __pthread_start(void*) () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so

#150xb6ee22d4 in __start_thread () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so

#160x00000000 in ?? ()



至此,我们在5.0上分明看到了3个线程,

ui线程响应onDraw,会调用childcompositor合成一个compositorframe.并会向webcore主线程发送申请beginMainFrame让rwebcore启动一个paint.并可能会requestDrawGL,发送任务到队列,申请系统的renderer线程执行drawGL任务。

系统的renderer线程会调用DrawGL执行gl任务。主要包括执行一些deferredtasks以及调用parentcompositor来完成合成。

Webcore主线程会执行beginFrame的实际操作。也就是paint自己的layers.paint完成之后要commit到impl线程,也就是childcompositor所在的ui线程里。供ui线程合成使用。



问题:

1.系统renderer线程绘制的结果如何下一步处理?

render线程执行操作时,已经绑定了framebuffer,所以绘制结果因该被系统使用了。

2.compositeframe是谁生成的,何时生成的,如何使用干什么的?

是childcompositor生成的,也就是browserViewRender调用的synchronousCOmpositor完成合成工作。是ui线程上的,用于合成网页内容。

3.beginFrame绘制的结果如何下一步被使用的。

Webcore线程beginframe绘制的结果应该要被commit到ui线程/impl线程供合成使用。

4.最终的画面是如何合成和显示的?

最终的画面应该是renderer线程中的parentcompositor合成并绘制到framebuffer上的。供系统处理的。

Layer Tree 绘制 站在老罗的肩膀上:https://blog.youkuaiyun.com/luoshengyang/article/details/51148299 网页绘图表面创建完成之后,调度器就会请求绘制CC Layer Tree,这样网页在加载完成之后就能快速显示出来。通过CC Layer Tree可以依次找到Graphics Layer Tree、Paint Layer Tree和Layout Object Tr... 阅读详情

相关推荐

Chromium渲染框架总结

渲染优化 chromium为了优化渲染效率做了很多优化,这些不仅可以用在web渲染,也可以用于一些native图像界面的渲染;这些优化包括: 分成paint和compositing paint分为recording和光栅化 跨线程渲染,避免和网络请求影响帧率,同时paint和光栅化可以并行,充分利用了CPU多核特性 Tiling 跨进程渲染,提高稳定...

ckanhw的博客 1346

Chromium网页渲染调度器(Scheduler)实现分析

在采用线程化渲染方式渲染网页时,Chromium依赖一个调度器协调Main线程和Compositor线程的执行,同时也通过这个调度器决定它们什么时候该执行什么操作。调度器将Main线程和Compositor线程的当前状态记录在一个状态机中,然后通过这个状态机决定下一个要执行的操作。这个操作在满足当前设置条件下是最优的,因此可以使网页渲染更快更流畅。本文接下来就分析Chromium网页调度器的实现。

老罗的Android之旅 1万+

chromium网络栈学习

内容目录 1 Overview 3 1.1 常用工具 6 1.2 SSL,TLS 6 1.2.1 常识 6 1.2.2 browser代码中ssl版本的选择以及握手的过程 7 1.3 额外需要细节性分析的部分: 20 1.4 http 协议 20 1.4.1 http authencation 20 1.4.1.1 basic authentication 20 1

2453

blink渲染知识13- 硬件渲染之beginframe的处理以及一些后续步骤

执行线程是Chrome_InProcRenderThread,应该就是webcore线程。 下面是webcore线程执行paint操作的内容。 ThreadProxy::BeginMainFrame( ->layer_tree_host()->AnimateLayers( //layer的动画计算 layer_tree_host()->Layout(); //从新计算layout boo

1665

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

一.DrawGLFunctor android4.4 webview chromium的硬件渲染是android ui系统和chromium内核协作 完成的。android ui系统负责触发网页渲染(调用WebView.onDraw()),以及提供 网页内容的最终目的地(HardwareCanvas);chromium内核提供具体的渲染行为。 这里就引出了DrawGLFunctor结构。

jaylinzhou的专栏 3618

Matlab R2024a硬件支持包安装避坑指南:以Arduino为例(附离线包下载)

本文详细介绍了Matlab R2024a硬件支持包(Support Package)的安装流程,特别是针对Arduino平台的避坑指南和高效部署方法。从环境准备、离线安装方案到Arduino支持包的专项优化,提供了全面的技术细节和解决方案,帮助开发者避免常见错误,实现快速部署。

weixin_33737134的博客 449

WebKit/Blink 渲染网页的主要步骤

1.  发送网络资源请求。      WebKit在渲染网页之前,首先需要从网络上下载资源文件,这里把资源文件分为两类,一类称为主资源文件,比如Frame,另外一类成为子资源文件,比如图片,JavaScript脚本,CSS脚本,字体,音频视频文件等等。以前WebKit在加载这两种资源文件时采用不同的路径,主资源文件通过DocumentLoader类来加载,子资源文件通过DocLoader类来加载

HTML5, Chromium和WebKit技术 3783

手把手教你用Kali Linux搭建vulntarget-a靶场环境(附详细配置步骤)

本文详细介绍了如何在Kali Linux环境下搭建vulntarget漏洞靶场,包括环境规划、虚拟化平台配置、靶机系统部署及安全工具链配置等关键步骤。通过实战演练,帮助网络安全从业者和初学者掌握专业级漏洞实验平台的搭建与管理技巧,提升安全测试能力。

weixin_29279101的博客 107

chrome blink render engine and the render mechanism

这篇文章提供chrome基于硬件加速的组合实现的背景和细节 说明:为什么用硬件合成 传统式,web浏览器完全依赖CPU来渲染网页内容,但是随着现在GPUs的能力以及能够以更小的体积嵌入设备,人们逐渐把关注点转向寻找 更有效地使用基础硬件来实现更好的性能和节省电源消耗,使用GPU来合成网页内容能够带来非常明显的提速 使用硬件合成的优点可以归结为三个因素: 1、在绘制和组合...

dasfawef1255612的博客 267

SC8F073单片机串口通信保姆级教程:从寄存器配置到完整收发Demo(附避坑指南)

本文详细解析了SC8F073单片机串口通信的寄存器配置与调试技巧,涵盖TXSTA、RCSTA和SPBRG寄存器的逐位设置,提供精确的波特率计算方法和工业级抗干扰策略。通过完整的收发Demo和避坑指南,帮助开发者快速掌握底层串口通信技术,适用于工业控制等严苛环境。

weixin_33724046的博客 486

华为eNSP实战:手把手教你配置DHCP全局地址池(含AP固定IP分配)

本文通过华为eNSP模拟器,详细演示了如何配置DHCP全局地址池,为不同业务VLAN动态分配IP地址,并重点讲解了如何通过MAC地址绑定为接入点(AP)分配固定IP。文章涵盖了从拓扑设计、基础网络搭建到地址池精细配置、验证测试及常见故障排查的全流程,是网络工程师掌握企业级DHCP部署与AP管理的实用指南。

weixin_29235923的博客 600

网页渲染调度器(Scheduler)实现

站在老罗的肩膀上:https://blog.youkuaiyun.com/luoshengyang/article/details/51054990 调度器通过类SchedulerStateMachine描述内部的状态机。有以下4种状态 class CC_EXPORT SchedulerStateMachine { public: ... // corresponding to previou...

tornmy的博客 721

ANSYS Twin Builder实战:5步搞定数字孪生模型部署(附ROM配置技巧)

本文详细解析了ANSYS Twin Builder在数字孪生模型部署中的实战应用,重点介绍了ROM(降阶模型)配置技巧。通过5个关键步骤,从环境搭建到工业部署,帮助工程师高效实现高精度三维仿真到轻量化数字孪生的转化,提升预测性维护和系统仿真效率。

weixin_27330481的博客 661

Chromium网页Layer Tree绘制过程分析

网页绘图表面创建完成之后,调度器就会请求绘制CC Layer Tree,这样网页在加载完成之后就能快速显示出来。通过CC Layer Tree可以依次找到Graphics Layer Tree、Render Layer Tree和Render Object Tree。有了Render Object Tree之后,就可以执行具体的绘制工作了。接下来我们就分析网页CC Layer Tree的绘制过程。

老罗的Android之旅 2万+

智能生活中枢:基于 ESP32-S3 的桌面智能助手与日程提醒终端设计与实现

本文完成了基于 ESP32-S3 的桌面智能助手与日程提醒终端的完整设计,实现了时间同步、日程管理、声光提醒、环境监测、本地存储等核心功能。硬件接线简洁、软件逻辑清晰,可直接制作成品使用。硬件方案:以 ESP32-S3 为核心,搭配 OLED、DS3231、DHT11、按键、声光模块,接线标准化、易复刻;软件方案:基于 Arduino 开发,提供标准 Mermaid 软件流程图,代码模块化、可直接编译运行;核心功能:网络授时、本地日程管理、掉电存储、声光提醒、温湿度监测,满足桌面智能助手全场景需求。

weixin_42300449的博客 210

情感分析在金融领域的应用:舆情影响股价预测

我们都知道,股价的波动受到多种因素的影响,而大众的情绪和看法就是其中很重要的一部分。我们在日常生活中都有根据别人的评价来判断事物好坏的经验,在金融市场里,舆情就像是大众对某家公司的集体评价,它能反映出市场参与者的情绪和预期。学习这方面的知识,能帮助投资者更好地把握市场动态,做出更明智的投资决策,无论是个人投资者还是金融机构的分析师,都能从中受益。有一天,你看到某家知名企业被曝光了严重的产品质量问题,新闻铺天盖地,股民们也都在热议纷纷,负面情绪弥漫。这时,你会不会觉得这家公司的股价可能要下跌了呢?

AI 原生应用开发的博客 1148

Android WebView简要介绍和学习计划

我们通常会在App的UI中嵌入WebView,用来实现某些功能的动态更新。在4.4版本之前,Android WebView基于WebKit实现。不过,在4.4版本之后,Android WebView就换成基于Chromium的实现了。基于Chromium实现,使得WebView可以更快更流畅地显示网页。本文接下来就介绍Android WebView基于Chromium的实现原理,以及制定学习计划。

老罗的Android之旅 7万+

【OpenClaw从入门到精通】第19篇:OpenClaw电商实战:从零搭建比价+库存监控+自动调价全自动化系统(2026实测附完整代码)

2026年OpenClaw成为全球最火开源项目,电商行业因其场景高频、数据标准化成为其核心落地领域。本文针对电商从业者面临的比价繁琐、库存混乱、调价滞后三大痛点,基于OpenClaw的“接入层-执行层-决策层”三层架构,从零拆解智能比价、多平台库存监控、动态自动调价三大核心场景的实现逻辑。文中包含完整的环境配置、技能安装、代码实现(含Python脚本与YAML配置)、执行结果验证,同时补充关键算法原理与避坑指南,兼顾新手入门与进阶提升。读者可直接参考本文实操流程,快速搭建属于自己的电商自动化系统,实现7×2

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2240

Chromium网页光栅化过程分析

在前面一篇文章中,我们分析了网页CC Layer Tree同步为CC Pending Layer Tree的过程。同步操作完成后,CC Pending Layer Tree中的每一个Layer都会被划分成一系列的分块,并且每一个分块都会被赋予一个优先级。接下来CC模块会根据优先级对分块进行排序。优先级越高的分块越排在前面,越排在前面的分块就越快得到光栅化。本文接下来就详细分析网页分块的光栅化过程。

老罗的Android之旅 2万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

chromium:LoadUrl之后会发生那些事情之 cc::drawLayers

ThreadProxy::BeginMainFrame() --->Proxy::ImplThreadTaskRunner()->PostTask(       FROM_HERE,       base::Bind(&ThreadProxy::StartCommitOnImplThread,                         impl_thread_weak_ptr_,

Fantasy_116的专栏 1827

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

android 文字绘制

xxxxxxx

_ 739

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

android 分析so崩溃,android的/system/lib/libhwui.so崩溃分析和解决办法

直接上崩溃日志了:#00 pc 00039518 (null)#01 pc 00022ef9 /system/lib/libhwui.so [armeabi-v7a]#02 pc 00015d7d /system/lib/libhwui.so [armeabi-v7a]#03 pc 00014517 /system/lib/libhwui.so [armeabi-v7a]#04 pc 000144...

weixin_42512494的博客 5306

chromium drawGL

08-21 15:01:14.516 5179 5179 E chromium: #00 0x0069b0d3 /system/lib/libwebviewxx.so cc::Scheduler::SetNeedsManageTiles() ../../cc/scheduler/scheduler.cc:86 08-21 15:01:14.516 5179 5179 E c...

Neo_Zhang888的博客 352

blink渲染知识(二) - webcore rendering basics

Dom tree和Rendertree是独立的tree. Render tree由renderobject构成,并且renderobject并不和DOMnode 一一对应。有些dommode可能没有renderobject. 比如有些节点的css属性标记为display:none不显示。 Domtree的节点可以通过renderer()函数得到对应的rendertree中的renderOb

451

多线程下base库里可能的死锁重入问题。

问题是这样的,blink线程的void WaitableEvent::Wait() 里会卡死,等待UI线程。但UI线程可能在等blink线程的npapi真窗口响应消息。 理论上的解决方式,应该是blink线程不放真窗口,但实在要改太多东西,现在我只好折中一下,把void WaitableEvent::Wait()里加上消息循环,临时处理下真窗口消息。 但这样又有重入的问题: Ker...

weolar的专栏 669

Caused by: java.lang.NoSuchMethodException: callDrawGLFunction [long]

https://stackoverflow.com/questions/42687553/android-nosuchmethodexception-calldrawglfunction http://blog.youkuaiyun.com/g984160547/article/details/78459486 webview 在coolpad a8 930

fj_ut的博客 2207
上一篇: blink渲染知识11 - renderlayer tree的构建点
下一篇: blink渲染知识13- 硬件渲染之beginframe的处理以及一些后续步骤
csshell2002
博客等级 码龄11年 30粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值