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

这篇博客深入探讨了硬件渲染过程,从WebCore线程的beginframe触发,经过layer的动画计算、布局计算、更新绘制,到通知impl线程进行commit操作,直至UI线程的合成与绘制。详细分析了DirectRenderer在绘制过程中的作用,揭示了Android系统中GPU绘制命令的执行细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

执行线程是Chrome_InProcRenderThread,应该就是webcore线程。

下面是webcore线程执行paint操作的内容。

ThreadProxy::BeginMainFrame(

->layer_tree_host()->AnimateLayers( //layer的动画计算

layer_tree_host()->Layout(); //从新计算layout

bool updated = layer_tree_host()->UpdateLayers(queue.get());//更新各个layer,paint操作.

下面通知impl线程/ui线程,开始commit操作。并block主线程等待commit操作结束。

CompletionEvent completion;

Proxy::ImplThreadTaskRunner()->PostTask(

FROM_HERE,

base::Bind(&ThreadProxy::StartCommitOnImplThread,

impl_thread_weak_ptr_,

&completion,

queue.release()));

completion.Wait();


layer_tree_host()->CommitComplete();//操作完成。

Impl线程是哪个线程?最终的结论是UI线程。也是childcompositor线程。

从建立proxycallstack中可以看到是:

#0 cc::Proxy::Proxy(this=0x971581c0, impl_task_runner=...) at ../../cc/trees/proxy.cc:72

#1 0x9ca50bf6 in cc::ThreadProxy::ThreadProxy (this=0x971581c0,layer_tree_host=0x97e85200, impl_task_runner=...) at../../cc/trees/thread_proxy.cc:79

#2 0x9ca50cfe in cc::ThreadProxy::Create(layer_tree_host=layer_tree_host@entry=0x97e85200,impl_task_runner=...) at ../../cc/trees/thread_proxy.cc:69

#3 0x9ca3e964 in cc::LayerTreeHost::InitializeThreaded(this=this@entry=0x97e85200, impl_task_runner=...) at../../cc/trees/layer_tree_host.cc:128

#4 0x9ca40172 in cc::LayerTreeHost::CreateThreaded(client=client@entry=0xa3ed944c, manager=manager@entry=0xa3e339d8,settings=..., impl_task_runner=...) at../../cc/trees/layer_tree_host.cc:74

#5 0x9d35048c in content::RenderWidgetCompositor::Initialize(this=this@entry=0xa3ed9448, settings=...) at../../content/renderer/gpu/render_widget_compositor.cc:452

#6 0x9d350dcc in content::RenderWidgetCompositor::Create(widget=widget@entry=0x97ec4c00, threaded=<optimized out>) at../../content/renderer/gpu/render_widget_compositor.cc:330

#7 0x9d384590 in content::RenderWidget::initializeLayerTreeView(this=this@entry=0x97ec4c00) at../../content/renderer/render_widget.cc:1177

#8 0x9d37b522 in content::RenderViewImpl::initializeLayerTreeView(this=0x97ec4c00) at ../../content/renderer/render_view_impl.cc:2123

#9 0x9c7085da in blink::WebViewImpl::setIsAcceleratedCompositingActive(this=this@entry=0x979a0000, active=active@entry=true) at../../third_party/WebKit/Source/web/WebViewImpl.cpp:4080

#100x9c708918 in blink::WebViewImpl::setRootGraphicsLayer(this=0x979a0000, layer=0x95e60180) at../../third_party/WebKit/Source/web/WebViewImpl.cpp:3965

#110x9cc24594 in WebCore::RenderLayerCompositor::attachRootLayer(this=this@entry=0x9798cda0,attachment=attachment@entry=WebCore::RenderLayerCompositor::RootLayerAttachedViaChromeClient)

at../../third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp:1168

#120x9cc24c90 in WebCore::RenderLayerCompositor::ensureRootLayer(this=this@entry=0x9798cda0) at../../third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp:1104

#130x9cc24e8a inWebCore::RenderLayerCompositor::setCompositingModeEnabled(this=this@entry=0x9798cda0, enable=enable@entry=true)

at../../third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp:108

#140x9cc24ed2 inWebCore::RenderLayerCompositor::enableCompositingModeIfNeeded(this=this@entry=0x9798cda0) at../../third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp:131

#150x9cc24ef8 inWebCore::RenderLayerCompositor::setNeedsCompositingUpdate(this=0x9798cda0, updateType=WebCore::CompositingUpdateRebuildTree)

#160x9cbe1376 in WebCore::RenderLayer::styleChanged(this=0x95a14000, diff=..., diff@entry=...,oldStyle=oldStyle@entry=0x0) at../../third_party/WebKit/Source/core/rendering/RenderLayer.cpp:3733

#170x9cbe5cfa in WebCore::RenderLayerModelObject::styleDidChange(this=this@entry=0x95a04000, diff=diff@entry=...,oldStyle=oldStyle@entry=0x0)

at../../third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp:165

#180x9cbbe8f2 in WebCore::RenderBox::styleDidChange(this=this@entry=0x95a04000, diff=..., diff@entry=...,oldStyle=oldStyle@entry=0x0) at../../third_party/WebKit/Source/core/rendering/RenderBox.cpp:188

#190x9cba87ac in WebCore::RenderBlock::styleDidChange(this=this@entry=0x95a04000, diff=..., diff@entry=...,oldStyle=oldStyle@entry=0x0) at../../third_party/WebKit/Source/core/rendering/RenderBlock.cpp:332

#200x9cbae7ca in WebCore::RenderBlockFlow::styleDidChange(this=0x95a04000, diff=..., oldStyle=0x0) at../../third_party/WebKit/Source/core/rendering/RenderBlockFlow.cpp:1836

#210x9cbf9c58 in WebCore::RenderObject::setStyle(this=this@entry=0x95a04000, style=...) at../../third_party/WebKit/Source/core/rendering/RenderObject.cpp:2142

#220x9caca7cc in WebCore::Document::attach(this=0x95c04000, context=...) at../../third_party/WebKit/Source/core/dom/Document.cpp:2201

#230x9d060d20 in WebCore::LocalDOMWindow::installNewDocument(this=0x979f00e0, mimeType=..., init=...,forceXHTML=forceXHTML@entry=false) at../../third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp:401

#240x9d0ae476 inWebCore::DocumentLoader::createWriterFor(frame=frame@entry=0x979e4000,ownerDocument=ownerDocument@entry=0x0, url=..., mimeType=...,encoding=..., userChosen=userChosen@entry=false,

dispatch=dispatch@entry=false) at../../third_party/WebKit/Source/core/loader/DocumentLoader.cpp:905

#250x9d0ae5fa in WebCore::DocumentLoader::ensureWriter(this=this@entry=0x95e04000, mimeType=..., overridingURL=...) at../../third_party/WebKit/Source/core/loader/DocumentLoader.cpp:511

#260x9d0ae682 in WebCore::DocumentLoader::commitData(this=this@entry=0x95e04000, bytes=0x0, length=0) at../../third_party/WebKit/Source/core/loader/DocumentLoader.cpp:524

#270x9d0aed96 in WebCore::DocumentLoader::finishedLoading(this=0x95e04000, finishTime=<optimized out>) at../../third_party/WebKit/Source/core/loader/DocumentLoader.cpp:275

#280x9d0af5ee in WebCore::DocumentLoader::maybeLoadEmpty(this=this@entry=0x95e04000) at../../third_party/WebKit/Source/core/loader/DocumentLoader.cpp:706

#290x9d0af8e6 in WebCore::DocumentLoader::startLoadingMainResource(this=0x95e04000) at../../third_party/WebKit/Source/core/loader/DocumentLoader.cpp:720

#300x9d0b3b72 in WebCore::FrameLoader::init(this=0x979e4060) at../../third_party/WebKit/Source/core/loader/FrameLoader.cpp:135

#310x9c6fa33e in init (this=<optimized out>) at../../third_party/WebKit/Source/core/frame/LocalFrame.h:176

#32blink::WebLocalFrameImpl::initializeAsMainFrame(this=0x97994000, page=<optimized out>) at../../third_party/WebKit/Source/web/WebLocalFrameImpl.cpp:1608

#330x9d380a86 in content::RenderViewImpl::Initialize(this=this@entry=0x97ec4c00, params=params@entry=0x98601680) at../../content/renderer/render_view_impl.cc:762

#340x9d380d50 in content::RenderViewImpl::Create(opener_id=<optimized out>,window_was_created_with_opener=<optimized out>,renderer_prefs=..., webkit_prefs=..., routing_id=4,main_frame_routing_id=3,

surface_id=2, session_storage_namespace_id=1, frame_name=...,off_the_record=false,is_renderer_created=is_renderer_created@entry=false,swapped_out=false, proxy_routing_id=-2, hidden=false,

never_visible=false, next_page_id=1, screen_info=...,accessibility_mode=AccessibilityModeOff) at../../content/renderer/render_view_impl.cc:977

#350x9d375d2a in content::RenderThreadImpl::OnCreateNewView(this=this@entry=0xa3eea300, params=...) at../../content/renderer/render_thread_impl.cc:1297

#360x9d377f9e in DispatchToMethod<content::RenderThreadImpl, void(content::RenderThreadImpl::*)(ViewMsg_New_Params const&),ViewMsg_New_Params> (arg=..., method=<optimized out>,obj=0xa3eea300)

at ../../base/tuple.h:548

#37Dispatch<content::RenderThreadImpl, content::RenderThreadImpl,void, void (content::RenderThreadImpl::*)(ViewMsg_New_Params const&)>(sender=0xa3eea300, parameter=0x0, func=<optimized out>,obj=0xa3eea300,

msg=0x99158984) at ../../content/common/view_messages.h:577

#38content::RenderThreadImpl::OnControlMessageReceived (this=0xa3eea300,msg=...) at ../../content/renderer/render_thread_impl.cc:1257

#390x9d2176bc in content::ChildThread::OnMessageReceived(this=0xa3eea304, msg=...) at ../../content/child/child_thread.cc:474

#400x9c7a3e52 in IPC::ChannelProxy::Context::OnDispatchMessage(this=0x97e0b180, message=...) at ../../ipc/ipc_channel_proxy.cc:273

#410x9c7a3c90 in Run (a1=..., object=<optimized out>,this=0x98601ba8) at ../../base/bind_internal.h:190

#42MakeItSo (a2=..., a1=<optimized out>, runnable=...) at../../base/bind_internal.h:898

#43base::internal::Invoker<2,base::internal::BindState<base::internal::RunnableAdapter<void(IPC::ChannelProxy::Context::*)(IPC::Message const&)>, void(IPC::ChannelProxy::Context*, IPC::Message const&), void (I

PC::ChannelProxy::Context*,IPC::Message)>, void (IPC::ChannelProxy::Context*, IPC::Messageconst&)>::Run(base::internal::BindStateBase*) (base=<optimizedout>) at ../../base/bind_internal.h:1253

#440x9d2ba7a0 in Run (this=0x98601cb0) at ../../base/callback.h:401

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

#460x9d2ba858 in base::MessageLoop::DeferOrRunPendingTask(this=this@entry=0xa3ecb0c0, pending_task=...) at../../base/message_loop/message_loop.cc:482

#470x9d2baf6e in base::MessageLoop::DoWork (this=0xa3ecb0c0) at../../base/message_loop/message_loop.cc:596

#480x9d2bb4be in base::MessagePumpDefault::Run (this=0xa3e40d00,delegate=0xa3ecb0c0) at../../base/message_loop/message_pump_default.cc:32

#490x9d2bab92 in base::MessageLoop::RunHandler (this=0xa3ecb0c0) at../../base/message_loop/message_loop.cc:407

#500x9d2c2130 in base::RunLoop::Run (this=this@entry=0x98601d20) at../../base/run_loop.cc:49

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

#520x9d2cac8e in base::Thread::ThreadMain(this=0x9f813dd0) at ../../base/threading/thread.cc:225

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

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

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

#560x00000000 in ?? ()




从这个函数可以看到:

voidRenderWidgetCompositor::Initialize(cc::LayerTreeSettingssettings) {

scoped_refptr<base::MessageLoopProxy>compositor_message_loop_proxy;

RenderThreadImpl* render_thread = RenderThreadImpl::current();

cc::SharedBitmapManager* shared_bitmap_manager = NULL;

// render_thread may be NULL in tests.

if (render_thread) {

compositor_message_loop_proxy =

render_thread->compositor_message_loop_proxy();

shared_bitmap_manager = render_thread->shared_bitmap_manager();

}

if (compositor_message_loop_proxy.get()) {

layer_tree_host_ = cc::LayerTreeHost::CreateThreaded(

this, shared_bitmap_manager, settings,compositor_message_loop_proxy);

} else {

layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(

this, this, shared_bitmap_manager, settings);

}

DCHECK(layer_tree_host_);

}

传入LayerTreeHost::CreateThreaded最后的参数就是implthreadthreadloop proxy. 那么这个loop对应了哪个thread?

Implthread应该对应了一个compositorthread.:


voidRenderThreadImpl::EnsureWebKitInitialized() {

if (webkit_platform_support_)

return;


webkit_platform_support_.reset(newRendererWebKitPlatformSupportImpl);

blink::initialize(webkit_platform_support_.get());


const CommandLine& command_line =*CommandLine::ForCurrentProcess();


bool enable =command_line.HasSwitch(switches::kEnableThreadedCompositing);

if (enable) {

#ifdefined(OS_ANDROID)

if (SynchronousCompositorFactory* factory =

SynchronousCompositorFactory::GetInstance())

compositor_message_loop_proxy_ =

factory->GetCompositorMessageLoop();

实际走的这里,

#endif

if (!compositor_message_loop_proxy_.get()) {

compositor_thread_.reset(new base::Thread("Compositor"));

compositor_thread_->Start();

#ifdefined(OS_ANDROID)

compositor_thread_->SetPriority(base::kThreadPriority_Display);

#endif

compositor_message_loop_proxy_ =

compositor_thread_->message_loop_proxy();

compositor_message_loop_proxy_->PostTask(

FROM_HERE,

base::Bind(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed),

false));

}



创建该threadcallstack

#0 content::RenderThreadImpl::EnsureWebKitInitialized(this=0xa23aa300) at ../../content/renderer/render_thread_impl.cc:755

#1 0x9d81fcc0 in content::RenderThreadImpl::OnCreateNewView(this=this@entry=0xa23aa300, params=...) at../../content/renderer/render_thread_impl.cc:1276

#2 0x9d821f9e in DispatchToMethod<content::RenderThreadImpl, void(content::RenderThreadImpl::*)(ViewMsg_New_Params const&),ViewMsg_New_Params> (arg=..., method=<optimized out>,obj=0xa23aa300)

at ../../base/tuple.h:548

#3 Dispatch<content::RenderThreadImpl, content::RenderThreadImpl,void, void (content::RenderThreadImpl::*)(ViewMsg_New_Params const&)>(sender=0xa23aa300, parameter=0x0, func=<optimized out>,obj=0xa23aa300,

msg=0xa20a1294) at ../../content/common/view_messages.h:577

#4 content::RenderThreadImpl::OnControlMessageReceived(this=0xa23aa300, msg=...) at../../content/renderer/render_thread_impl.cc:1257

#5 0x9d6c16bc in content::ChildThread::OnMessageReceived(this=0xa23aa304, msg=...) at ../../content/child/child_thread.cc:474

#6 0x9cc4de52 in IPC::ChannelProxy::Context::OnDispatchMessage(this=0xa23ce180, message=...) at ../../ipc/ipc_channel_proxy.cc:273

#7 0x9cc4dc90 in Run (a1=..., object=<optimized out>,this=0x989f9ba8) at ../../base/bind_internal.h:190

#8 MakeItSo (a2=..., a1=<optimized out>, runnable=...) at../../base/bind_internal.h:898

#9 base::internal::Invoker<2,base::internal::BindState<base::internal::RunnableAdapter<void(IPC::ChannelProxy::Context::*)(IPC::Message const&)>, void(IPC::ChannelProxy::Context*, IPC::Message const&), void (I

PC::ChannelProxy::Context*,IPC::Message)>, void (IPC::ChannelProxy::Context*, IPC::Messageconst&)>::Run(base::internal::BindStateBase*) (base=<optimizedout>) at ../../base/bind_internal.h:1253

#100x9d7647a0 in Run (this=0x989f9cb0) at ../../base/callback.h:401

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

#120x9d764858 in base::MessageLoop::DeferOrRunPendingTask(this=this@entry=0xa23920c0, pending_task=...) at../../base/message_loop/message_loop.cc:482

#130x9d764f6e in base::MessageLoop::DoWork (this=0xa23920c0) at../../base/message_loop/message_loop.cc:596

#140x9d7654be in base::MessagePumpDefault::Run (this=0xa230a130,delegate=0xa23920c0) at../../base/message_loop/message_pump_default.cc:32

#150x9d764b92 in base::MessageLoop::RunHandler (this=0xa23920c0) at../../base/message_loop/message_loop.cc:407

#160x9d76c130 in base::RunLoop::Run (this=this@entry=0x989f9d20) at../../base/run_loop.cc:49

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

#180x9d774c8e in base::Thread::ThreadMain(this=0x9efc4060) at ../../base/threading/thread.cc:225

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

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

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

#220x00000000 in ?? ()


实际上从下面的函数可以看出来,针对compositormessage loop创建的threadui线程:

SynchronousCompositorFactoryImpl::GetCompositorMessageLoop(){ returnBrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);}


那么结论是:5.0上,implthread, 也就是compsitorthread,UI线程。

那么结论是:5.0上,implthread, 也就是compsitorthread,UI线程。

那么结论是:5.0上,implthread, 也就是compsitorthread,UI线程。

那么结论是:5.0上,implthread, 也就是compsitorthread,UI线程。



我们可以给ThreadProxy::StartCommitOnImplThread加断点看看是不是ui线程:

因为这个操作应该在impl线程执行。这个操作是webcore绘制完成后,impl线程commitlayer tree的操作。这个操作是webcore线程post过来的。

callstack如下:

#0 cc::ThreadProxy::StartCommitOnImplThread(this=0x980151c0, completion=0x989f9a04, raw_queue=0xa20a8880) at../../cc/trees/thread_proxy.cc:885

#1 0x9cefc7b6 in Run (a2=@0xa2362d3c: 0xa20a8880, a1=@0xa2362d38:0x989f9a04, object=<optimized out>, this=0xbe9730e0) at../../base/bind_internal.h:248

#2 MakeItSo (a3=@0xa2362d3c: 0xa20a8880, a2=@0xa2362d38: 0x989f9a04,weak_ptr=..., runnable=...) at ../../base/bind_internal.h:938

#3 base::internal::Invoker<3,base::internal::BindState<base::internal::RunnableAdapter<void(cc::ThreadProxy::*)(cc::CompletionEvent*,cc::ResourceUpdateQueue*)>, void (cc::ThreadProxy*,cc::CompletionEvent*, cc

::ResourceUpdateQueue*),void (base::WeakPtr<cc::ThreadProxy>, cc::CompletionEvent*,cc::ResourceUpdateQueue*)>, void (cc::ThreadProxy*,cc::CompletionEvent*,cc::ResourceUpdateQueue*)>::Run(base::internal::BindSt

ateBase*)(base=0xa2362d20) at ../../base/bind_internal.h:1383

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

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

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

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

#8 0x9d748050 in DoRunLoopOnce(delayed_scheduled_time_ticks=7642965136, native_delegate=<optimizedout>, obj=0xbe97328c, env=0xb4f51240) at../../base/message_loop/message_pump_android.cc:35

#9Java_com_jetpack_dolphin_webkit_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce(env=0xb4f51240, jcaller=0xbe97328c,

//下面可以证明,这个loopui线程的

messagePumpDelegateNative=<optimized out>,delayedScheduledTimeTicks=7642965136)

at gen/base/jni/SystemMessageHandler_jni.h:42

#100x9fe3e8a8 in ?? ()

#110x9fe3e8a8 in ?? ()


是从java层调用过来的:

实际上是这样的:


voidMessagePumpForUI::Start(Delegate*delegate) {

run_loop_ = new RunLoop();

if (!run_loop_->BeforeRun())

NOTREACHED();


JNIEnv* env = base::android::AttachCurrentThread();

DCHECK(env);


system_message_handler_obj_.Reset(

Java_SystemMessageHandler_create(

env, reinterpret_cast<intptr_t>(delegate)));

}


staticbase::android::ScopedJavaLocalRef<jobject>

Java_SystemMessageHandler_create(JNIEnv* env, jlong

messagePumpDelegateNative) {


CHECK_CLAZZ(env, SystemMessageHandler_clazz(env),

SystemMessageHandler_clazz(env), NULL);

jmethodID method_id =

base::android::MethodID::LazyGet<

base::android::MethodID::TYPE_STATIC>(

env, SystemMessageHandler_clazz(env),

"create",


"("

"J"

")"

"Ldolphin/blink/org/chromium/base/SystemMessageHandler;",

&g_SystemMessageHandler_create);


jobject ret =

env->CallStaticObjectMethod(SystemMessageHandler_clazz(env),

method_id, messagePumpDelegateNative);

jni_generator::CheckException(env);

return base::android::ScopedJavaLocalRef<jobject>(env, ret);

}


--->调用java层的:

private static SystemMessageHandler create(longmessagePumpDelegateNative) {

return new SystemMessageHandler(messagePumpDelegateNative);

}

在创建这个handler的线程上,就会执行该handlerhandleMessage函数:

@Override

public void handleMessage(Messagemsg) {

if (msg.what == DELAYED_SCHEDULED_WORK) {

mDelayedScheduledTimeTicks = 0;

}

nativeDoRunLoopOnce(mMessagePumpDelegateNative,mDelayedScheduledTimeTicks);

}




那么messagepumpForUI::start谁调用的:

#0 base::MessagePumpForUI::Start(this=0x9e37d600, delegate=0xac3fc860) at../../base/message_loop/message_pump_android.cc:112

#1 0x9c14a2cc in base::MessageLoopForUI::Start(this=<optimized out>) at../../base/message_loop/message_loop.cc:681

#2 0x9bcdc682 in content::BrowserMainLoop::EarlyInitialization(this=0x9f730160) at ../../content/browser/browser_main_loop.cc:372

#3 0x9bcdebea in content::BrowserMainRunnerImpl::Initialize(this=0x9e37d5b0, parameters=...) at../../content/browser/browser_main_runner.cc:84

#4 0x9b93d182 in android_webview::AwMainDelegate::RunProcess(this=0x9f758e80, process_type=..., main_function_params=...) at../../android_webview/lib/main/aw_main_delegate.cc:120

#5 0x9b92490a in content::RunNamedProcessTypeMain(process_type=..., main_function_params=..., delegate=0x9f758e80) at../../content/app/content_main_runner.cc:409

#6 0x9b924be8 in content::ContentMainRunnerImpl::Run (this=0x9f7fe830)at ../../content/app/content_main_runner.cc:767

#7 0x9b9244b8 in Start (env=<optimized out>, clazz=<optimizedout>) at ../../content/app/android/content_main.cc:48

#8content::Java_com_jetpack_dolphin_webkit_org_chromium_content_app_ContentMain_nativeStart(env=<optimized out>, jcaller=<optimized out>) atgen/content/jni/ContentMain_jni.h:50

#9 0x9fd2afda in ?? ()

#100x9fd2afda in ?? ()


ContentMain.java,start()

->nativestart

→content::Java_com_jetpack_dolphin_webkit_org_chromium_content_app_ContentMain_nativeStart


那么java层的callstack


1 gc(25905): java.lang.Throwable

2 gc(25905): atcom.jetpack.dolphin.webkit.org.chromium.content.app.ContentMain.start(ContentMain.java:35)

3 gc(25905): atcom.jetpack.dolphin.webkit.org.chromium.content.browser.BrowserStartupController.contentStart(BrowserStartupController.java:211)

4 gc(25905): atcom.jetpack.dolphin.webkit.org.chromium.content.browser.BrowserStartupController.startBrowserProcessesSync(BrowserStartupController.java:193)

5 gc(25905): atcom.jetpack.dolphin.webkit.org.chromium.android_webview.AwBrowserProcess$1.run(AwBrowserProcess.java:54)

6 gc(25905): atcom.jetpack.dolphin.webkit.org.chromium.base.ThreadUtils.runOnUiThreadBlocking(ThreadUtils.java:64)

7 gc(25905): atcom.jetpack.dolphin.webkit.org.chromium.android_webview.AwBrowserProcess.start(AwBrowserProcess.java:50)

8 gc(25905): atcom.jetpack.dolphin.webkit.webview.WebViewChromiumFactoryProvider.startChromiumLocked(WebViewChromiumFactoryProvider.java:324)

9 gc(25905): atcom.jetpack.dolphin.webkit.webview.WebViewChromiumFactoryProvider.ensureChromiumStartedLocked(WebViewChromiumFactoryProvider.java:275)

10 gc(25905): atcom.jetpack.dolphin.webkit.webview.WebViewChromiumFactoryProvider.getWebIconDatabase(WebViewChromiumFactoryProvider.java:511)

11 gc(25905): atcom.jetpack.dolphin.webkit.WebIconDatabase.getInstance(WebIconDatabase.java:104)

12 gc(25905): atcom.dolphin.browser.jetpack.WebIconDatabaseWrapper.<init>(WebIconDatabaseWrapper.java:35)

13 gc(25905): at java.lang.reflect.Constructor.newInstance(NativeMethod)

14 gc(25905): atjava.lang.reflect.Constructor.newInstance(Constructor.java:288)

15 gc(25905): atcom.dolphin.browser.core.WebViewFactory.getWebIconDatabase(WebViewFactory.java:477)

16 gc(25905): atcom.dolphin.browser.core.WebIconDatabase.<init>(WebIconDatabase.java:56)

17 gc(25905): atcom.dolphin.browser.core.WebIconDatabase.<init>(WebIconDatabase.java:32)

18 gc(25905): atcom.dolphin.browser.core.WebIconDatabase$SingletonHolder.<clinit>(WebIconDatabase.java:60)

19 gc(25905): atcom.dolphin.browser.core.WebIconDatabase.getInstance(WebIconDatabase.java:52)

20 gc(25905): atcom.dolphin.browser.core.WebIconDatabase.retainIconsOnStartup(WebIconDatabase.java:135)

21 gc(25905): atmobi.mgeek.TunnyBrowser.BrowserUIManager.onFirstScreenShown(BrowserUIManager.java:938)

22 gc(25905): atcom.mgeek.android.ui.MainScreen$2.run(MainScreen.java:208)

23 gc(25905): at android.os.Handler.handleCallback(Handler.java:739)

24 gc(25905): at android.os.Handler.dispatchMessage(Handler.java:95)

25 gc(25905): at android.os.Looper.loop(Looper.java:135)

26 gc(25905): atandroid.app.ActivityThread.main(ActivityThread.java:5221)

27 gc(25905): at java.lang.reflect.Method.invoke(Native Method)

28 gc(25905): at java.lang.reflect.Method.invoke(Method.java:372)

29 gc(25905): atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)

30 gc(25905): atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)


可见,的确是ui线程创建的implthread. 也就是compositorthread. 所以compositorthread,也就是implthread就是ui线程。


我们继续看ThreadProxy::StartCommitOnImplThread干了什么:也就是impl线程如何执行commit操作处理webcore线程paintlayer tree的结果:

ThreadProxy::StartCommitOnImplThread做了如下事情:

创建ResourceUpdateController,并且调用:

voidResourceUpdateController::PerformMoreUpdates(

他会注册一个ResourceUpdateController::OnTimerFired,并且后期,在ui线程可能会调用onTimerFired.因为有一个ui线程调用的messageloop, 所以可以向ui线程注册delayedtask:ui线程调用onTimerFired,检查到应该进行commit,就执行commit操作,执行完成后会通知webcore线程,时webcore线程解除block.


ResourceUpdateController::OnTimerFired

-voidThreadProxy::ReadyToFinalizeTextureUpdates() {

->voidScheduler::NotifyReadyToCommit()

更新statemachine状态,然后:

voidScheduler::ProcessScheduledActions()

-voidThreadProxy::ScheduledActionCommit()

//这里的commit是把layertreewebcorethread copyuithread.

blocked_main().main_thread_inside_commit = true;

impl().layer_tree_host_impl->BeginCommit();

layer_tree_host()->BeginCommitOnImplThread(impl().layer_tree_host_impl.get());

layer_tree_host()->FinishCommitOnImplThread(

impl().layer_tree_host_impl.get());

blocked_main().main_thread_inside_commit = false;

这里的

LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl*host_impl) 是真正的同步implwebcore线程的layertree的逻辑所在。他完成layertree同步

他会同步layerhost treelaytree impl里面。

如果需要完全同步:

sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(

root_layer(), sync_tree->DetachLayerTree(), sync_tree));

会调用TreeSynchronizer来完成同步操作。

sync_tree是我们的目标结果。通过从源treerootlayer开始递归,创建或者同步各个子layer,来完成rendertree的同步。

ThreadProxy::ScheduledActionCommit()最后会解除webcore线程的等待。



还看到了在ui线程,其实是impl线程,执行完成commit操作之后,并已经解除了webcore线程的等待之后,在ThreadProxy::ScheduledActionCommit()函数中还会创建rastertask:

#0 cc::TileManager::ScheduleTasks(this=0xa1c0fc00,

//这里应该会为每个需要rastertile创建一个rastertask 放入队列中。

tiles_that_need_to_be_rasterized=...) at../../cc/resources/tile_manager.cc:924

#1 0x9b7b301c in cc::TileManager::ManageTiles (this=0xa1c0fc00,state=...) at ../../cc/resources/tile_manager.cc:662

#2 0x9b7c0dfe in cc::LayerTreeHostImpl::ManageTiles(this=0x9e5f3600)

//这里调用tilemanger来处理managertiles

at ../../cc/trees/layer_tree_host_impl.cc:431

#3 0x9b7c53f2 in cc::LayerTreeHostImpl::CommitComplete(this=0x9e5f3600)

//commit完成。

at ../../cc/trees/layer_tree_host_impl.cc:346

#4 0x9b7ced86 in cc::ThreadProxy::ScheduledActionCommit(this=0x971cc1c0) at ../../cc/trees/thread_proxy.cc:1004

#5 0x9b7b6b3c in cc::Scheduler::ProcessScheduledActions(this=this@entry=0xa1c0f900) at ../../cc/scheduler/scheduler.cc:665

#6 0x9b7b6cd6 in cc::Scheduler::NotifyReadyToCommit (this=0xa1c0f900)at ../../cc/scheduler/scheduler.cc:220

#7 0x9b7accc6 in cc::ResourceUpdateController::OnTimerFired(this=0xa09b33c0) at../../cc/resources/resource_update_controller.cc:111

#8 0x9b7ac97a in Run (object=<optimized out>, this=0xbeef70e0) at../../base/bind_internal.h:134

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

#10base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(cc::ResourceUpdateController::*)()>, void(cc::ResourceUpdateController*), void(base::WeakPtr<cc::ResourceUpdateContr

oller>)>,void(cc::ResourceUpdateController*)>::Run(base::internal::BindStateBase*)(base=0xa4016070) at ../../base/bind_internal.h:1169

#110x9c0377b8 in Run (this=0xbeef71f0) at ../../base/callback.h:401

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

#130x9c037870 in base::MessageLoop::DeferOrRunPendingTask(this=this@entry=0xa1c0e120, pending_task=...) at../../base/message_loop/message_loop.cc:482

#140x9c037f86 in base::MessageLoop::DoWork (this=0xa1c0e120) at../../base/message_loop/message_loop.cc:596

#150x9c01b068 in DoRunLoopOnce (delayed_scheduled_time_ticks=2233168243,native_delegate=<optimized out>, obj=0xbeef728c,env=0xb5051240) at ../../base/message_loop/message_pump_android.cc:35

#16Java_com_jetpack_dolphin_webkit_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce(env=0xb5051240, jcaller=0xbeef728c, //ui线程messagePumpDelegateNative=<optimized out>,delayedScheduledTimeTicks=2233168243)

#170xa003c6c0 in ?? ()

#180xa003c6c0 in ?? ()




那么用来触发raster任务的voidTileManager::ScheduleTasks(主要任务:

创建的rastertask是:

scoped_refptr<RasterTask>TileManager::CreateRasterTask(Tile* tile){函数,实际创建RasterTaskImpl,每个tile一个task.

RasterTaskImpl定义在tile_manager.cc中。

然后调用

ImageRasterWorkerPool::ScheduleTasksRasterTaskQueue

这个ImageRasterWorkerPool也是tilemanagerrasterizer.也是rastertaskclient.


classCC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool,

public Rasterizer,

public RasterizerTaskClient{


rasterworkerpooltasks都加入到一个taskgraph里面,然后schedule给了originalthread:

->voidRasterWorkerPool::ScheduleTasksOnOriginThread(RasterizerTaskClient*client, TaskGraph* graph),这个函数会调用到RasterTaskImpl::ScheduleOnOriginThread,其实并没有把这个task交给originthread执行,只是给了调用线程本身一个机会,在真正执行本task之前做一些初始化等工作,比如获得该taskcanvas.


还会调用TaskGraphRunner::ScheduleTasks,将tasks交给taskgraph runner. 究竟task在哪里执行?


但是我们又看到raster_worker_pool.cc中,会针对taskgraph建立若干workerthreads,那么究竟raster操作在originalthread执行还是在rasterworker thread执行?我们可以找一个task断点看看。

classRasterTaskGraphRunner : public TaskGraphRunner,

publicbase::DelegateSimpleThread::Delegate {

public:

RasterTaskGraphRunner() {

size_t num_threads = RasterWorkerPool::GetNumRasterThreads();

while (workers_.size() < num_threads) {

scoped_ptr<base::DelegateSimpleThread> worker =

make_scoped_ptr(newbase::DelegateSimpleThread(

this,

base::StringPrintf("CompositorRasterWorker%u",

static_cast<unsigned>(workers_.size()+ 1))

.c_str()));

worker->Start();

#ifdefined(OS_ANDROID) || defined(OS_LINUX)

worker->SetThreadPriority(base::kThreadPriority_Background);

#endif

workers_.push_back(worker.Pass());

}

}



我们通过加断点看到:

#0 AnalyzeAndRaster(picture_pile=0x9f0c7ec0, this=0xa09ec4e0) at../../cc/resources/tile_manager.cc:102 //实际的raster工作。

#0 cc::(anonymous namespace)::RasterTaskImpl::RunOnWorkerThread

//这个函数是raster的具体工作。

(this=0xa09edc10)at ../../cc/resources/tile_manager.cc:65

#1 0x9b7ae642 in cc::TaskGraphRunner::RunTaskWithLockAcquired(this=this@entry=0x9ccc60bc <cc::(anonymousnamespace)::g_task_graph_runner+4>) at../../cc/resources/task_graph_runner.cc:419

#2 0x9b7ae77a in cc::TaskGraphRunner::Run(this=0x9ccc60bc <cc::(anonymousnamespace)::g_task_graph_runner+4>) at../../cc/resources/task_graph_runner.cc:362

#3 0x9c0476f0 in base::DelegateSimpleThread::Run(this=0xa096e3d0) at

//这个是rasterworker thread

../../base/threading/simple_thread.cc:81

#4 0x9c0478fc in base::SimpleThread::ThreadMain(this=0xa096e3d0) at ../../base/threading/simple_thread.cc:60

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

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

#7 0xb6f7e2d4 in __start_thread () from/tmp/tshao-adb-gdb-libs/system/lib/libc.so

#8 0x00000000 in ?? ()



那么raster的具体工作是怎么做的?Raster完成之后如何通知的?


Raster完成之后,会把pendingtree activateactivetree

voidImageRasterWorkerPool::OnRasterFinished(),这个callback是在ImageRasterWorkerPool::ScheduleTasks函数中注册进去的。当所有rastertask完成之后会调用他。

->TileManager::DidFinishRunningTasks

-ready_to_activate_check_notifier_.Schedule();

这会向ui线程post一个task执行TileManager::CheckIfReadyToActivate函数。目的在于让ui线程在某个时间后,执行检查是否可以activiate操作。


下面是ui线程执行TileManager::CheckIfReadyToActivatecallstack:如果可以active了,就执行active操作:


#0 cc::Scheduler::ProcessScheduledActions(this=0xa1c0f900) at

会执行ScheduledActionActivatePendingTree。会activatepending tree.

../../cc/scheduler/scheduler.cc:670

#1 0x9b7b6bde in cc::Scheduler::NotifyReadyToActivate(this=<optimized out>) at ../../cc/scheduler/scheduler.cc:164

这个函数会先调用voidSchedulerStateMachine::NotifyReadyToActivate() pending_tree_is_ready_for_activation_设置为true;这样statemachine会将下一个action设置为activatepending tree,

#2 0x9b7cb9c4 in cc::ThreadProxy::NotifyReadyToActivate(this=0x971cc1c0) at ../../cc/trees/thread_proxy.cc:394

#3 0x9b7c0a72 in cc::LayerTreeHostImpl::NotifyReadyToActivate(this=<optimized out>) at../../cc/trees/layer_tree_host_impl.cc:1294

#4 0x9b7b057c in cc::TileManager::CheckIfReadyToActivate(this=0xa1c0fc00) at ../../cc/resources/tile_manager.cc:1574

#5 0x9b7b01d6 in Run (object=<optimized out>, this=0xbeef70c8) at../../base/bind_internal.h:134

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

#7 base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(cc::TileManager::*)()>, void (cc::TileManager*), void(base::internal::UnretainedWrapper<cc::TileManager>)>, void(cc:

:TileManager*)>::Run(base::internal::BindStateBase*)(base=<optimized out>) at ../../base/bind_internal.h:1169

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

#9 cc::UniqueNotifier::Notify (this=<optimized out>) at../../cc/base/unique_notifier.cc:39

#100x9b76c3be in Run (object=<optimized out>, this=0xbeef70e0) at../../base/bind_internal.h:134

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

#12base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(cc::UniqueNotifier::*)()>, void (cc::UniqueNotifier*), void(base::WeakPtr<cc::UniqueNotifier>)>, void (cc::UniqueNoti

fier*)>::Run(base::internal::BindStateBase*)(base=0xac4b1820) at ../../base/bind_internal.h:1169

#130x9c0377b8 in Run (this=0xbeef71f0) at ../../base/callback.h:401

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

#150x9c037870 in base::MessageLoop::DeferOrRunPendingTask(this=this@entry=0xa1c0e120, pending_task=...) at../../base/message_loop/message_loop.cc:482

#160x9c037f86 in base::MessageLoop::DoWork (this=0xa1c0e120) at../../base/message_loop/message_loop.cc:596

#170x9c01b068 in DoRunLoopOnce (delayed_scheduled_time_ticks=7986754512,native_delegate=<optimized out>, obj=0xbeef728c,env=0xb5051240) at ../../base/message_loop/message_pump_android.cc:35

#18Java_com_jetpack_dolphin_webkit_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce(env=0xb5051240, jcaller=0xbeef728c, //ui线程messagePumpDelegateNative=<optimized out>,delayedScheduledTimeTicks=7986754512)

at gen/base/jni/SystemMessageHandler_jni.h:42

#190xa003c6c0 in ?? ()

#200xa003c6c0 in ?? ()



那么可以知道,只有在rasterpendingtree的内容之后,才会把pendingtree同步给activetree. 然后呢会通知,需要重新合成。合成时会调用drawLayer等操作,生成compositorframe. 之后会把合成结果commit,也就是提交给parenetcompositrlayertree里面。






注意,implthread这边,有2tree, pending tree, active tree, 后者是正在显示的tree.需要通过activation操作,将pendingtree设置成activetree. 同步操作发生在pendingtree.

所以,从webcore线程的layertreecommitimpl线程的pendingtree之后,还需等待合适的时机再把impl线程的pendingtree同步到impl线程的activetree.

什么时候是合适的时机?也就是raster操作完成之后。


#0 cc::ThreadProxy::DidActivatePendingTree(this=0x93c341c0) at ../../cc/trees/thread_proxy.cc:1439

#1 0x9d1395ce in cc::LayerTreeHostImpl::ActivatePendingTree

//这里会把pendingtree内容同步给activetree.

(this=0x950edb80) at../../cc/trees/layer_tree_host_impl.cc:1878

#2 0x9d13ff00 in cc::ThreadProxy::ScheduledActionActivatePendingTree(this=0x93c341c0) at ../../cc/trees/thread_proxy.cc:1024

#3 0x9d12ab3c in cc::Scheduler::ProcessScheduledActions(this=0xa1d12c80) at ../../cc/scheduler/scheduler.cc:665

#4 0x9d12abde in cc::Scheduler::NotifyReadyToActivate (this=<optimizedout>) at ../../cc/scheduler/scheduler.cc:164

#5 0x9d13f9c4 in cc::ThreadProxy::NotifyReadyToActivate(this=0x93c341c0) at ../../cc/trees/thread_proxy.cc:394

#6 0x9d134a72 in cc::LayerTreeHostImpl::NotifyReadyToActivate(this=<optimized out>) at../../cc/trees/layer_tree_host_impl.cc:1294

#7 0x9d12457c in cc::TileManager::CheckIfReadyToActivate(this=0xa1d12e00)

//这里检查是否可以将pendingtree同步到activetree.猜测,当所有需要rastertile都被raster之后,这个函数返回true.这样就可以draw了。

at ../../cc/resources/tile_manager.cc:1574

#8 0x9d1241d6 in Run (object=<optimized out>, this=0xbeb8d0c8) at../../base/bind_internal.h:134

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

#10base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(cc::TileManager::*)()>, void (cc::TileManager*), void(base::internal::UnretainedWrapper<cc::TileManager>)>, void(cc:

:TileManager*)>::Run(base::internal::BindStateBase*)(base=<optimized out>) at ../../base/bind_internal.h:1169

#110x9d0e0346 in Run (this=<optimized out>) at../../base/callback.h:401

#12cc::UniqueNotifier::Notify(this=<optimized out>) at../../cc/base/unique_notifier.cc:39

#130x9d0e03be in Run (object=<optimized out>, this=0xbeb8d0e0) at../../base/bind_internal.h:134

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

#15base::internal::Invoker<1,base::internal::BindState<base::internal::RunnableAdapter<void(cc::UniqueNotifier::*)()>, void (cc::UniqueNotifier*), void(base::WeakPtr<cc::UniqueNotifier>)>, void (cc::UniqueNoti

fier*)>::Run(base::internal::BindStateBase*)(base=0xa4020400) at ../../base/bind_internal.h:1169

#160x9d9ab810 in Run (this=0xbeb8d1f0) at ../../base/callback.h:401

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

#180x9d9ab8c8 in base::MessageLoop::DeferOrRunPendingTask(this=this@entry=0xa0125a20, pending_task=...) at../../base/message_loop/message_loop.cc:482

#190x9d9abfde in base::MessageLoop::DoWork (this=0xa0125a20) at../../base/message_loop/message_loop.cc:596

#200x9d98f0c0 in DoRunLoopOnce(delayed_scheduled_time_ticks=20593782346, native_delegate=<optimizedout>, obj=0xbeb8d28c, env=0xb5051240) at../../base/message_loop/message_pump_android.cc:35

#21Java_com_jetpack_dolphin_webkit_org_chromium_base_SystemMessageHandler_//这是在ui线程。

nativeDoRunLoopOnce(env=0xb5051240, jcaller=0xbeb8d28c,messagePumpDelegateNative=<optimized out>,

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

#220xa0a2b6c0 in ?? ()

#230xa0a2b6c0 in ?? ()




那么cc::LayerTreeHostImpl::ActivatePendingTree函数干了什么,在返回之前还干了什么?除了将pendngtree内容同步给activetree, 它还通知要通知redraw.因为当前在ui线程同步了最新的layertree内容,可以尝试绘制一份,或者说合成一份frame.

if (pending_tree_->needs_full_tree_sync()) {

active_tree_->SetRootLayer(

TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),

active_tree_->DetachLayerTree(),

active_tree_.get()));

}

TreeSynchronizer::PushProperties(pending_tree_->root_layer(),

active_tree_->root_layer());

这都是在同步pendingtreeactivetree.

...

SetNeedsRedraw();

这个函数大概会让laytree host impldrawLayers到一个Frame,并且会swapBuffer.包含raster操作么?我觉的raster操作应该已经完成了,而且已经activatepending tree了,那么此时因该尝试通知childcompositor完成一次合成。即完成一次draw操作。


voidLayerTreeHostImpl::SetNeedsRedraw() {

-voidThreadProxy::SetNeedsRedrawOnImplThread()

->voidScheduler::SetNeedsRedraw()//这会给状态机设置需要重绘的标记,那么下次进入状态机会触发draw操作.因该就是childcompositor的合成操作。即使用activetree.那么具体干什么事情,看下面:

-voidScheduler::ProcessScheduledActions()

->voidScheduler::DrawAndSwapIfPossible()

->DrawResultThreadProxy::ScheduledActionDrawAndSwapIfPossible()

->DrawResultThreadProxy::DrawSwapInternal(false)

-> 1. DrawResultLayerTreeHostImpl::PrepareToDraw(FrameData*frame)

做了什么:初始化frame数据,并调用LayerTreeHostImpl::CalculateRenderPasses

renderPass维护了一个DrawQuad列表,什么是DrawQuad?一个layer因该对应一个DrawQuad?一个DrawQuad保存了一些数据,比如尺寸什么的,在用来绘制一个quad时使用。DrawQuad有很多子类,类新靠DrawQuad::Material来区分。

上述FrameData定义在LayerTreeHostImpl中,

structCC_EXPORT FrameData : public RenderPassSink {,可以包含一个RenderPasslist.


2. void LayerTreeHostImpl::DrawLayers(FrameData*frame,

base::TimeTicks frame_begin_time) {

这个函数依赖准备好了renderpassFrameData来开始draw的工作,并调用:

voidDelegatingRenderer::DrawFrame(RenderPassList*render_passes_in_draw_order,

float device_scale_factor,

const gfx::Rect&device_viewport_rect,

const gfx::Rect&device_clip_rect,

booldisable_picture_quad_image_filtering) {

其实并不会真正的draw.总之最终只是要合成而已。


3. void LayerTreeHostImpl::DidDrawAllLayers(const FrameData&frame) {


4.void LayerTreeHostImpl::UpdateAnimationState(boolstart_ready_animations)


5.boolLayerTreeHostImpl::SwapBuffers(const LayerTreeHostImpl::FrameData&frame)

synchronousCompositorOutputSurface::SwapBuffers

cc::CompositorFrame*) ,将传入的frame交给outputsurfaceframe_holder.//那么这个frame_holder是如何被后续使用的?






当然,ui线程在执行onDraw时,更是因该调用childcompositor合成一个compositorframe的。比如:



那么还有一个调用cc::DelegatingRenderer::DrawFrame的场景,就是onDrawui线程被调用时,看callstack:我觉的这个场景是ui线程在执行网页的composite,也就是把当前的activetree绘制出来。其实也是合成.

可见下面的ui线程的ondraw操作干了两件事:1. 告诉webcore线程准备下个paintframe2. 使用当前的activetree合成一个compositorframe.


#0 cc::ResourceProvider::PrepareSendToParent (this=0x9f6ad380,resources=..., list=list@entry=0xa08c0264) at../../cc/resources/resource_provider.cc:1385

#1 0x9b5659ac in cc::DelegatingRenderer::DrawFrame(this=0x9cc36a30, render_passes_in_draw_order=<optimizedout>, device_scale_factor=<optimized out>,device_viewport_rect=..., device_clip_rect=...,

disable_picture_quad_image_filtering=false) at../../cc/output/delegating_renderer.cc:109

#2 0x9b5a1602 in cc::LayerTreeHostImpl::DrawLayers(this=0x9ee8b780,

//这个函数会首先把renderpass准备好,然后再绘制。

frame=0xbea71a74, frame_begin_time=...) at../../cc/trees/layer_tree_host_impl.cc:1605

#3 0x9b5acc92 in cc::ThreadProxy::DrawSwapInternal

先针对activetree调用preparetoDraw,绘制出renderpass, 保存在frame里面。然后让drawlayers去绘制各个renderpass.

(this=this@entry=0x970341c0,forced_draw=forced_draw@entry=false) at../../cc/trees/thread_proxy.cc:1090

#4 0x9b5acf5c in cc::ThreadProxy::ScheduledActionDrawAndSwapIfPossible(this=0x970341c0) at ../../cc/trees/thread_proxy.cc:1177

#5 0x9b592ae0 in cc::Scheduler::DrawAndSwapIfPossible(this=this@entry=0xac3fa900) at ../../cc/scheduler/scheduler.cc:611

#6 0x9b593b20 in cc::Scheduler::ProcessScheduledActions(this=this@entry=0xac3fa900) at ../../cc/scheduler/scheduler.cc:652

#7 0x9b593e70 in cc::Scheduler::OnBeginImplFrameDeadline(this=this@entry=0xac3fa900) at ../../cc/scheduler/scheduler.cc:584

#8 0x9b593eb0 in cc::Scheduler::ScheduleBeginImplFrameDeadline

//当向webcore线程发送完成了消息后,状态机继续前行,检查是否到了deadline,如果到了就直接composite出一个frame来,也就是要画一个frame出来。这个操作也是在ui线程,也就是impl线程执行的。

(this=this@entry=0xac3fa900, deadline=...) at../../cc/scheduler/scheduler.cc:559

#9 0x9b5940dc in cc::Scheduler::BeginImplFrame//这个函数可能会立刻执行beginFrame也可能会推迟。但是不管怎么样,他会向webcore线程发送一个消息,让webcore线程去执行paint操作。

(this=this@entry=0xac3fa900,args=...) at ../../cc/scheduler/scheduler.cc:524

#100x9b59442c in cc::Scheduler::BeginFrame(this=0xac3fa900, args=...) at ../../cc/scheduler/scheduler.cc:426

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

#120x9b99deee incontent::SynchronousCompositorOutputSurface::InvokeComposite

//这里的compositre是在ui线程执行的网页内容级别的composite.要把activetree绘制出来。

(this=this@entry=0x97034700,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

#130x9b99e136 incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x97034700, 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

#140x9b99da88 in content::SynchronousCompositorImpl::DemandDrawHw(this=0x9f607bc8, 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

#150x9b5fd088 in android_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0xa084e468,java_canvas=java_canvas@entry=0xbea72110) at../../android_webview/browser/browser_view_renderer.cc:374

#160x9b5fd194 in android_webview::BrowserViewRenderer::OnDraw(this=this@entry=0xa084e468,java_canvas=java_canvas@entry=0xbea72110,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

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

#170x9bc5e9ce in android_webview::AwContents::OnDraw(this=0xa084e380, env=<optimized out>, obj=<optimized out>,canvas=0xbea72110, 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

#180x9fe2b27a in ?? ()

#190x9fe2b27a in ?? ()






LayerTreeHostImpl::DrawLayers的另一各调用场景:被系统renderthread调用:

我觉的这个调用场景是系统的render线程在执行parentcompositor合成工作,他要把已经合成好的网页内容和其他东西绘制合成好。这里会执行一些gl操作。

#0 cc::LayerTreeHostImpl::DrawLayers(this=0xa0804700, frame=0xa1dff620, frame_begin_time=...) at../../cc/trees/layer_tree_host_impl.cc:1605

#1 0x9b5a79fc in cc::SingleThreadProxy::DoComposite(this=this@entry=0xa084a250, frame_begin_time=...,frame=frame@entry=0xa1dff620) at../../cc/trees/single_thread_proxy.cc:432

#2 0x9b5a824c in cc::SingleThreadProxy::CompositeImmediately(this=0xa084a250, frame_begin_time=...) at../../cc/trees/single_thread_proxy.cc:350

#3 0x9b597e06 in cc::LayerTreeHost::Composite(this=this@entry=0x9e2e3700, frame_begin_time=...) at../../cc/trees/layer_tree_host.cc:685

#4 0x9b5feeb6 in android_webview::HardwareRenderer::DrawGL(this=this@entry=0x9f8ff580,stencil_enabled=stencil_enabled@entry=false,framebuffer_binding_ext=0, draw_info=draw_info@entry=0xa1dff8a8)

at ../../android_webview/browser/hardware_renderer.cc:224

#5 0x9bc60b58 in android_webview::AwContents::DrawGL (this=<optimizedout>, draw_info=0xa1dff8a8) at../../android_webview/native/aw_contents.cc:435

#6 0x9bd64c4a in draw_gl_50 (this=0xa0872568, data=0xa1dff964,what=<optimized out>) at../../third_party/android_plat_support/draw_gl_functor.cpp:103

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

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

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

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

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

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

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

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

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

#160xb672927c inandroid::uirenderer::renderthread::RenderThread::threadLoop() () from/tmp/tshao-adb-gdb-libs/system/lib/libhwui.so //系统创建的的renderthread.

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

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

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

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

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

#220x00000000 in ?? ()



我们重点看看调用了LayerTreeHostImpl::DrawLayers之后,干了什么?


那么从上面可知,有ui线程的onDraw会触发,还有系统render线程也会触发他。共同点都是在执行composite操作,前者是SynchronousCompositorOutputSurface::InvokeComposite,后者是SingleThreadProxy::DoComposite。两者的区别:第一次是在ui线程执行网页内容的合成,也就是childcompositor的工作,第2次是在系统的render线程执行parentcompositor的合成工作,也就是把网页合成结果和其他内容统统合成在一起。虽然貌似执行路径一样,但是使用到的render等都是不同的。


那么composite完成后数据干什么去了?

第一次的childcompositor合成的数据应该会在commit时挂载到rootlayer上。供parentcompositor合成时使用。

还有DrawLayers中涉及到的renderpass是如何生成的,并如何被消费掉的

preparetodraw时生成renderpass, drawLayer时被消耗掉。



看看DelegateRender::DrawFrame究竟干了什么?这个因该是childcompositor使用的render。他绘制内容到compositorframe里面。貌似并没有干什么特别特殊的处理,之前准备出来的renderpass也没有被处理。只是针对resource貌似做了一些处理。

voidDelegatingRenderer::DrawFrame(RenderPassList*render_passes_in_draw_order,

float device_scale_factor,

const gfx::Rect&device_viewport_rect,

const gfx::Rect&device_clip_rect,

booldisable_picture_quad_image_filtering) {


delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData);

DelegatedFrameData& out_data = *delegated_frame_data_;

out_data.device_scale_factor = device_scale_factor;


out_data.render_pass_list.swap(*render_passes_in_draw_order);


// Collect all resource ids in the render passes into aResourceIdArray.

ResourceProvider::ResourceIdArray resources;

DrawQuad::ResourceIteratorCallback append_to_array =

base::Bind(&AppendToArray, &resources);

for (size_t i = 0; i < out_data.render_pass_list.size(); ++i) {

RenderPass* render_pass = out_data.render_pass_list.at(i);

for (size_t j = 0; j < render_pass->quad_list.size(); ++j)

render_pass->quad_list[j]->IterateResources(append_to_array);

}

resource_provider_->PrepareSendToParent(resources,&out_data.resource_list);

}




新建raster任务的堆栈:

我们看到了onDraw触发的在ui线程执行的beginFrame操作。找到一个触发raster任务的堆栈:

#0 cc::TileManager::ScheduleTasks(this=0xa1c0fc00,

//这里会创建rastertasks并加入到队列里面,有rasterworker pool去执行他们。

tiles_that_need_to_be_rasterized=...) at../../cc/resources/tile_manager.cc:924

#1 0x9b7b301c in cc::TileManager::ManageTiles(this=0xa1c0fc00, state=...) at../../cc/resources/tile_manager.cc:662

#2 0x9b7c0dfe in cc::LayerTreeHostImpl::ManageTiles(this=0x9e5f3600) at ../../cc/trees/layer_tree_host_impl.cc:431

#3 0x9b7cbf8e in cc::ThreadProxy::ScheduledActionManageTiles(this=0x971cc1c0) at ../../cc/trees/thread_proxy.cc:1165

#4 0x9b7b6b3c in cc::Scheduler::ProcessScheduledActions(this=this@entry=0xa1c0f900) at ../../cc/scheduler/scheduler.cc:665

#5 0x9b7b6e70 in cc::Scheduler::OnBeginImplFrameDeadline(this=this@entry=0xa1c0f900) at ../../cc/scheduler/scheduler.cc:584

#6 0x9b7b6eb0 in cc::Scheduler::ScheduleBeginImplFrameDeadline(this=this@entry=0xa1c0f900, deadline=...) at../../cc/scheduler/scheduler.cc:559

#7 0x9b7b70dc in cc::Scheduler::BeginImplFrame(this=this@entry=0xa1c0f900, args=...) at../../cc/scheduler/scheduler.cc:524

#8 0x9b7b742c in cc::Scheduler::BeginFrame(this=0xa1c0f900, args=...) at ../../cc/scheduler/scheduler.cc:426

#9 0x9b7c0a86 in cc::LayerTreeHostImpl::BeginFrame (this=<optimizedout>, args=...) at ../../cc/trees/layer_tree_host_impl.cc:1408

#100x9bbc0f0e incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x971cc700, 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

#110x9bbc1156 incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x971cc700, 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

#120x9bbc0aa8 in content::SynchronousCompositorImpl::DemandDrawHw(this=0x9fac74c0, 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

#130x9b8200bc in android_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0xa0962968,java_canvas=java_canvas@entry=0xbeef6110) at../../android_webview/browser/browser_view_renderer.cc:374

#140x9b8201c8 in android_webview::BrowserViewRenderer::OnDraw(this=this@entry=0xa0962968,java_canvas=java_canvas@entry=0xbeef6110,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

#150x9be8196e in android_webview::AwContents::OnDraw (this=0xa0962880,env=<optimized out>, obj=<optimized out>,canvas=0xbeef6110, 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

#160xa002927a in ?? ()

#170xa002927a in ?? ()





那么如何activatepending tree呢:在impl也就是ui线程执行:

voidThreadProxy::ScheduledActionActivatePendingTree()

->voidLayerTreeHostImpl::ActivatePendingTree()

1. 同步pendingtree内容到activetree.:

TreeSynchronizer::SynchronizeTrees(pending_tree_->root_layer(),

active_tree_->DetachLayerTree(),

active_tree_.get()));

2. pending_tree_.swap(recycle_tree_);

3. active_tree_->DidBecomeActive();

4. SetNeedsRedraw(); 在将pendingtree activate之后,触发一次需要重新的绘制,其实是合成。


那么setNeedsRedraw干了什么?

->voidThreadProxy::SetNeedsRedrawOnImplThread()

先给schedulerStateMachineneed_redraw= true.然后调用

Scheduler::ProcessScheduledActions,因为inside_process_scheduled_actions_=true,所以什么也不干。也就是说我们已经在processScheduledActions里面了。所以这次什么都不干,那么因为need_redraw_应被设置成true了,迟早以后再次进入ProcessScheduledAction里面时,检查到need_redraw_true,从而会触发redraw操作的。



而后来当onDraw调用时,也会走到ThreadProxy::SetNeedsRedrawOnImplThread(),看stack

#0 cc::ThreadProxy::SetNeedsRedrawOnImplThread(this=0x9f8641c0) at ../../cc/trees/thread_proxy.cc:490

#1 0x9d65349e in cc::ThreadProxy::SetNeedsRedrawRectOnImplThread(this=0x9f8641c0, damage_rect=...) at../../cc/trees/thread_proxy.cc:507

#2 0x9d64abea in cc::LayerTreeHostImpl::SetNeedsRedrawRect(this=0x958ebb00, damage_rect=...) at../../cc/trees/layer_tree_host_impl.cc:1404

#3 0x9d61b38e in cc::OutputSurface::SetNeedsRedrawRect(this=this@entry=0x9f864700, damage_rect=...) at../../cc/output/output_surface.cc:89

#4 0x9da48ef0 incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x9f864700, 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:226

#5 0x9da49156 incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x9f864700, 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

#6 0x9da48aa8 in content::SynchronousCompositorImpl::DemandDrawHw(this=0x964db0d8, 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

#7 0x9d6a80bc in android_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0x98bf4968,java_canvas=java_canvas@entry=0xbeff7110) at../../android_webview/browser/browser_view_renderer.cc:374

#8 0x9d6a81c8 in android_webview::BrowserViewRenderer::OnDraw(this=this@entry=0x98bf4968,java_canvas=java_canvas@entry=0xbeff7110,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

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

#9 0x9dd0996e in android_webview::AwContents::OnDraw(this=0x98bf4880, env=<optimized out>, obj=<optimized out>,canvas=0xbeff7110, 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

#100xa091827a in ?? ()

#110xa091827a in ?? ()




那么onDraw触发的ThreadProxy::SetNeedsRedrawOnImplThread()会调用如下:

->Scheduler::ProcessScheduledActions

->也没干什么。


既然不好看到processScheduledActions干什么,那么他应该是有一定顺序的,直接从其函数入手,看各个状态机的状态变化,然后看究竟会引起什么操作。

比如当setNeedsRedraw被调用后,nextAction就可能会引起下次processScheduledAction执行draw相关操作:


SchedulerStateMachine::ActionSchedulerStateMachine::NextAction() const {

if (ShouldUpdateVisibleTiles())

return ACTION_UPDATE_VISIBLE_TILES;

if (ShouldActivatePendingTree())

return ACTION_ACTIVATE_PENDING_TREE;

if (ShouldCommit())

return ACTION_COMMIT;

if (ShouldAnimate())

return ACTION_ANIMATE;

if (ShouldDraw()){//一种返回true的场景:当need_redraw_== true

if (PendingDrawsShouldBeAborted())

return ACTION_DRAW_AND_SWAP_ABORT;

else if (forced_redraw_state_ ==FORCED_REDRAW_STATE_WAITING_FOR_DRAW)

return ACTION_DRAW_AND_SWAP_FORCED;

else

return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;

}

if (ShouldManageTiles())

return ACTION_MANAGE_TILES;

if (ShouldSendBeginMainFrame())

return ACTION_SEND_BEGIN_MAIN_FRAME;

if (ShouldBeginOutputSurfaceCreation())

return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;

return ACTION_NONE;

}

那么下面就是redraw也就是重新的合成工作:

其实普通的合成工作也是干这些事情:将acivetree的内容转换成renderpass然后生成compositorframe,保存到outputsurface里。


如果nextaction被设置为ACTION_DRAW_AND_SWAP_IF_POSSIBLE那么,后期processScheduledAction会:

-Scheduler::DrawAndSwapIfPossible

->ThreadProxy::ScheduledActionDrawAndSwapIfPossible

->ThreadProxy::DrawSwapInternalforced_draw= false

→ 1. LayerTreeHostImpl::PrepareToDraw(FrameData* frame)

2. LayerTreeImpl::UpdateDrawProperties

3. LayerTreeHostImpl::PrepareToDraw(FrameData* frame)

-->CalculateRenderPasses(FrameData* frame)

4. LayerTreeHostImpl::DrawLayersframe

-->DelegatingRenderer::DrawFrame(render passlist...)

5. LayerTreeHostImpl::DidDrawAllLayers(frame)

6. LayerTreeHostImpl::SwapBuffers(frame)

-->1.LayerTreeHostImpl::MakeCompositorFrameMetadata

2. DelegatingRenderer::SwapBuffers

构造CompositorFrame,并调用swapbuffer.

--->SynchronousCompositorOutputSurface::SwapBuffers

cc::CompositorFrame*) ,将传入的frame交给outputsurfaceframe_holder.//那么这个frame_holder是如何被后续使用的?

--->LayerTreeHostImpl::DidSwapBuffers

--->ThreadProxy::DidSwapBuffersOnImplThread

--->Scheduler::DidSwapBuffers

7. 向主webcore线程post一个task:ThreadProxy::DidCommitAndDrawFrame,



processScheduledAction执行完成Scheduler::DrawAndSwapIfPossible之后,紧接着会继续执行:ThreadProxy::ScheduledActionManageTiles,就是再次要发起raster的工作.

->LayerTreeHostImpl::ManageTiles

→1. TileManager::ManageTiles

-->TileManager::ScheduleTasks(tiles_that_need_to_be_rasterized),将需要rastertile都创建rastertask放到对列里面准备raster.

  1. ThreadProxy::DidManageTiles

    -->Scheduler::DidManageTiles




我们知道上面的drawswap buffer之后,SynchronousCompositorOutputSurfaceframe_holder被赋值了一个compositorframe, 那么他是如何被使用的?这就是childcompositor合成生成的compositorframe数据。这个东西需要commitparentcompositor rootlayer下面。



上面的代码一种调用场景是onDraw,这个触发是在合成完成之前。这里又是讲触发redrawcallstack.

#0 cc::ThreadProxy::SetNeedsRedrawOnImplThread (this=0x9f8641c0) at../../cc/trees/thread_proxy.cc:490

#1 0x9d65349e in cc::ThreadProxy::SetNeedsRedrawRectOnImplThread(this=0x9f8641c0, damage_rect=...) at../../cc/trees/thread_proxy.cc:507

#2 0x9d64abea in cc::LayerTreeHostImpl::SetNeedsRedrawRect(this=0x958ebb00, damage_rect=...) at../../cc/trees/layer_tree_host_impl.cc:1404

#3 0x9d61b38e in cc::OutputSurface::SetNeedsRedrawRect(this=this@entry=0x9f864700, damage_rect=...) at../../cc/output/output_surface.cc:89

#4 0x9da48ef0 incontent::SynchronousCompositorOutputSurface::InvokeComposite

注意在这个函数返回后,就会把drawand swap buffer时新drawcompositorframe设置给

outputsurface.

(this=this@entry=0x9f864700,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:226

#5 0x9da49156 incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x9f864700, 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

#6 0x9da48aa8 in content::SynchronousCompositorImpl::DemandDrawHw(this=0x964db0d8, 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

#7 0x9d6a80bc in android_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0x98bf4968,java_canvas=java_canvas@entry=0xbeff5eb0) at../../android_webview/browser/browser_view_renderer.cc:374

#8 0x9d6a81c8 in android_webview::BrowserViewRenderer::OnDraw(this=this@entry=0x98bf4968,java_canvas=java_canvas@entry=0xbeff5eb0,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

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

#9 0x9dd0996e in android_webview::AwContents::OnDraw(this=0x98bf4880, env=<optimized out>, obj=<optimized out>,canvas=0xbeff5eb0, 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

#100xa091827a in ?? ()

#110xa091827a in ?? ()





scoped_ptr<cc::CompositorFrame>

SynchronousCompositorOutputSurface::DemandDrawHw(

gfx::Size surface_size,

const gfx::Transform& transform,

gfx::Rect viewport,

gfx::Rect clip,

gfx::Rect viewport_rect_for_tile_priority,

const gfx::Transform& transform_for_tile_priority) {

DCHECK(CalledOnValidThread());

DCHECK(HasClient());

DCHECK(context_provider_);


surface_size_ = surface_size;


//invokeComposite函数返回后,frame_holder就已经有了最新的compositorframe.

InvokeComposite(transform,

viewport,

clip,

viewport_rect_for_tile_priority,

transform_for_tile_priority,

true);


return frame_holder_.Pass();//这就是childcompositor 合成的结果

}


并且在invokeComposite中还会通知swapbuffer完成:

#0 cc::ThreadProxy::DidSwapBuffersCompleteOnImplThread(this=0x9f8641c0) at ../../cc/trees/thread_proxy.cc:364

#1 0x9d648ae6 in cc::LayerTreeHostImpl::DidSwapBuffersComplete(this=<optimized out>) at../../cc/trees/layer_tree_host_impl.cc:1416

#2 0x9da48fae incontent::SynchronousCompositorOutputSurface::InvokeComposite(this=this@entry=0x9f864700, 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:250

#3 0x9da49156 incontent::SynchronousCompositorOutputSurface::DemandDrawHw(this=0x9f864700, 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

#4 0x9da48aa8 in content::SynchronousCompositorImpl::DemandDrawHw(this=0x964db0d8, 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

#5 0x9d6a80bc in android_webview::BrowserViewRenderer::OnDrawHardware(this=this@entry=0x98bf4968,java_canvas=java_canvas@entry=0xbeff5eb0) at../../android_webview/browser/browser_view_renderer.cc:374

#6 0x9d6a81c8 in android_webview::BrowserViewRenderer::OnDraw(this=this@entry=0x98bf4968,java_canvas=java_canvas@entry=0xbeff5eb0,is_hardware_canvas=is_hardware_canvas@entry=true, scroll=...,

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

#7 0x9dd0996e in android_webview::AwContents::OnDraw(this=0x98bf4880, env=<optimized out>, obj=<optimized out>,canvas=0xbeff5eb0, 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

#8 0xa091827a in ?? ()

#9 0xa091827a in ?? ()

而且还会向webcore主线程发送一个通知说swapbuffer完成:

&ThreadProxy::DidCompleteSwapBuffers,



那么当得到了compositorframe之后干了什么?我们看看这个函数:

BrowserViewRenderer::OnDrawHardware

->1.content::SynchronousCompositorImpl::DemandDrawHw,得到compositorframe

  1. frame赋值给draw_gl_input->frame

  2. drawgl input 设置给sharedrender state.:SharedRendererState::SetDrawGLInput(DrawGLInput)

  3. BrowserViewRenderer::DidComposite

  4. AwContents::RequestDrawGL

    -->Java_AwContents_requestDrawGL


那么我们可以认为ondraw,draw完的结果,swapbuffer,生成一个compositorframe, 被设置给DrawGlInput,并向系统请求gl操作,那么是不是系统会使用这个DrawGlInput里面的compositorframe? 的确,renderer线程会接着执行commit操作,取出这个compositorframe数据,提交给parentcompositor使用的renderlayer tree里面。下面就是commit操作的执行:注意,这里的commit不同于之前我们提到的commit,之前的commit是把webcore线程的paint结果commitimpl线程的pendinglayer tree里面。而这里讲的commit是指把impl线程的合成结果compositorframe数据提交给系统render线程的layertree上,挂载成上面的一个layer.而且这个commit操作由render线程完成。之前的commit操作由impl线程完成。


看看DrawGlInput如何被使用的:

的确在系统renderer线程会调用awContents::drawGL来处理这个frame:


#0 android_webview::HardwareRenderer::CommitFrame(this=0xa0116a00) at../../android_webview/browser/hardware_renderer.cc:135

#1 0x9dd0b9e6 in android_webview::AwContents::DrawGL(this=0x98bf4880, draw_info=0xa1dffa58) at../../android_webview/native/aw_contents.cc:372

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#350x00000000 in ?? ()


那么HardwareRenderer::CommitFrame干了什么:

-> 1. input = shared_renderer_state_->PassDrawGLInput(),取出glinput数据,包含了之前生成的compositorframe数据.

    1. DelegatedFrameProvider::SetFrameData,frame数据传给它.干什么用?

    2. 创建DelegatedRendererLayer,并将DelegatedFrameProvider作为参数。这样此delegatedrender layer就可以包含了之前的compositorframe的数据了。

    3. root_layer_->AddChild(delegated_layer_);将这个delegatedlayer设置为rootlayerchild.这样,以后绘制rootlayer对应的tree,也就把compositorframe作为childlayer绘制出来了。这就把childcompositor生成的compositorframe数据挂载到了parentcompositor以后用到的layertree下面了。


看来上面这个DrawGL操作把compositorframe数据取出来保存在了rootlayer对应的树里面了。



那么后续parentcompositor 合成时,就会取出挂载在rootlayer下面的compositorframe数据并合成他们,下面就是该callstack:


有一个函数可以从delegatedFrameProvider获取设置的frame数据,callstack如下:

#0 cc::DelegatedFrameProvider::GetFrameDataAndRefResources(this=0xa02971e0, observer=observer@entry=0x98bf8e80,damage=damage@entry=0x98bf90e4) at../../cc/layers/delegated_frame_provider.cc:86

#1 0x9d5fb870 in cc::DelegatedRendererLayer::Update(this=0x98bf8e80,

//取出之前设置的frame数据,保存到frame_data_里慢.

queue=<optimized out>, occlusion=<optimized out>) at../../cc/layers/delegated_renderer_layer.cc:94

#2 0x9d6443aa in cc::LayerTreeHost::PaintLayerContents

//绘制每个layer的内容。

(this=this@entry=0x82217100,render_surface_layer_list=..., queue=queue@entry=0xa20c5ac0,did_paint_content=did_paint_content@entry=0xa1dff476,

need_more_updates=need_more_updates@entry=0xa1dff477) at../../cc/trees/layer_tree_host.cc:994

#3 0x9d644790 in cc::LayerTreeHost::UpdateLayers(this=this@entry=0x82217100, root_layer=0x98bf7d00, queue=0xa20c5ac0)at ../../cc/trees/layer_tree_host.cc:830

#4 0x9d6449ce in cc::LayerTreeHost::UpdateLayers(this=0x82217100, queue=<optimized out>) at../../cc/trees/layer_tree_host.cc:696

#5 0x9d653242 in cc::SingleThreadProxy::CompositeImmediately

//注意,这里的singlethread proxy表明此时执行在parentcompositor里面

(this=0xa20bb0a0,frame_begin_time=...) at ../../cc/trees/single_thread_proxy.cc:344

#6 0x9d642e3e in cc::LayerTreeHost::Composite(this=this@entry=0x82217100, frame_begin_time=...) at../../cc/trees/layer_tree_host.cc:685

#7 0x9d6a9eea inandroid_webview::HardwareRenderer::DrawGL(this=this@entry=0x81caf4c0,stencil_enabled=stencil_enabled@entry=false,framebuffer_binding_ext=0, draw_info=draw_info@entry=0xa1dff8a8)

at ../../android_webview/browser/hardware_renderer.cc:224

#8 0x9dd0baf8 in android_webview::AwContents::DrawGL(this=<optimized out>, draw_info=0xa1dff8a8) at../../android_webview/native/aw_contents.cc:435

#9 0x9de0fbea in draw_gl_50 (this=0xa2098818, data=0xa1dff964,what=<optimized out>) at../../third_party/android_plat_support/draw_gl_functor.cpp:103

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#250x00000000 in ?? ()


上面这个callstack说明在另一次的drawGl操作里,会处理之前设置的frame数据.


从上面的callstack可以看到,他会走到一些singlethread proxy的一些逻辑,并且也会触发layertree hostlayertree host impl的一些逻辑,也有updatelayer操作,也有生成frame的逻辑.也会drawlayers,commit等操作,但是都在render线程,并且操作完成后,swapbuffer的操作使用的render和之前就不同了.当然不同了,这里是parentcompositor使用之前的compositorframe数据合成,这里如果再次绘制的话,会调用gl操作的。绘制完成,Swapbuffer的操作也跟以前不同。可以认为此时绘制操作都是绘制在gl里面了,所以swapbuffer的话,只需要flushgl就可以了。就会使用gl命令:


GLRenderer::SwapBuffers(CompositorFrameMetadata&)

->ParentOutputSurface::SwapBuffers(cc::CompositorFrame)

->1.GLES2Implementation::ShallowFlushCHROMIUM

-->CommandBufferHelper::Flush

-->InProcessCommandBuffer::Flush

-->queueTask, &InProcessCommandBuffer::FlushOnGpuThread,

2. LayerTreeHostImpl::DidSwapBuffers

-->SingleThreadProxy::DidSwapBuffersOnImplThread


但是代码里面并没有对compositorframe做什么处理.?其实这里没有什么compositorframe数据了,以前网页的compositorframe数据已经被再次合成绘制到gl里面了。

我怀疑compositor生成之后,被挂载到一个叫做rootlayer的下面,成为其一个childlayer. 日后,rootlayer画到屏幕上时,就会把他也画上去的.以后可以看看是否是这样的.因为compositorframe数据里其实其实保存的是renderpass等数据,这些已经作为一个子layer挂载到parentcompositorlayertree上了,所以parentcompositor合成,draw他的layertree就成了。





因为有两级compositor,child compositor负责生成compositorframe, 运行于ui线程..Parent compositior运行于系统创建的render线程.负责把compositorframe显示到屏幕.

并且是在DrawGL调用序列里执行的,好好看看:

HardwareRenderer::DrawGL


怀疑,向屏幕上绘制是下面的逻辑:

#0 cc::LayerTreeHost::PaintLayerContents(this=this@entry=0x82217a00,

//难不成这个函数就是直接向输出的surface上绘制?直接把layer的内容绘制出来,就像当于向glsurface上绘制好了.剩下就是系统做得了?而之前的compositorframe是不是已经挂载到rootlayer之下了?是的.

render_surface_layer_list=..., queue=queue@entry=0x97f2c640,did_paint_content=did_paint_content@entry=0xa1dff476,

need_more_updates=need_more_updates@entry=0xa1dff477) at../../cc/trees/layer_tree_host.cc:971

#1 0x9d644790 in cc::LayerTreeHost::UpdateLayers(this=this@entry=0x82217a00, root_layer=0x98bf9600, queue=0x97f2c640)at ../../cc/trees/layer_tree_host.cc:830

#2 0x9d6449ce in cc::LayerTreeHost::UpdateLayers(this=0x82217a00, queue=<optimized out>) at../../cc/trees/layer_tree_host.cc:696

#3 0x9d653242 in cc::SingleThreadProxy::CompositeImmediately(this=0x94c374c0, frame_begin_time=...) at../../cc/trees/single_thread_proxy.cc:344

#4 0x9d642e3e in cc::LayerTreeHost::Composite(this=this@entry=0x82217a00, frame_begin_time=...) at../../cc/trees/layer_tree_host.cc:685

#5 0x9d6a9eea in android_webview::HardwareRenderer::DrawGL(this=this@entry=0x81caf700,stencil_enabled=stencil_enabled@entry=false,framebuffer_binding_ext=0, draw_info=draw_info@entry=0xa1dff8a8)

at ../../android_webview/browser/hardware_renderer.cc:224

#6 0x9dd0baf8 in android_webview::AwContents::DrawGL(this=<optimized out>, draw_info=0xa1dff8a8) at../../android_webview/native/aw_contents.cc:435

#7 0x9de0fbea in draw_gl_50 (this=0xa01fe4f0, data=0xa1dff964,what=<optimized out>) at../../third_party/android_plat_support/draw_gl_functor.cpp:103

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#230x00000000 in ?? ()






再看下面的callstack;也是parentcompositor 合成的过程。

#0 cc::DirectRenderer::DrawFrame(this=0x97f73000,

//又蹦出一个directrender.

render_passes_in_draw_order=0xa1dff63c, device_scale_factor=1,device_viewport_rect=..., device_clip_rect=...,disable_picture_quad_image_filtering=false)

at ../../cc/output/direct_renderer.cc:200

#1 0x9d64c63a in cc::LayerTreeHostImpl::DrawLayers(this=0x94ccab00, frame=0xa1dff620, frame_begin_time=...) at../../cc/trees/layer_tree_host_impl.cc:1605

#2 0x9d652a34 in cc::SingleThreadProxy::DoComposite(this=this@entry=0x94c374c0, frame_begin_time=...,frame=frame@entry=0xa1dff620) at../../cc/trees/single_thread_proxy.cc:432

#3 0x9d653284 in cc::SingleThreadProxy::CompositeImmediately(this=0x94c374c0, frame_begin_time=...) at../../cc/trees/single_thread_proxy.cc:350

#4 0x9d642e3e in cc::LayerTreeHost::Composite(this=this@entry=0x82217a00, frame_begin_time=...) at../../cc/trees/layer_tree_host.cc:685

#5 0x9d6a9eea in android_webview::HardwareRenderer::DrawGL(this=this@entry=0x81caf700,stencil_enabled=stencil_enabled@entry=false,framebuffer_binding_ext=0, draw_info=draw_info@entry=0xa1dff8a8)

at ../../android_webview/browser/hardware_renderer.cc:224

#6 0x9dd0baf8 in android_webview::AwContents::DrawGL(this=<optimized out>, draw_info=0xa1dff8a8) at../../android_webview/native/aw_contents.cc:435

#7 0x9de0fbea in draw_gl_50 (this=0xa01fe4f0, data=0xa1dff964,what=<optimized out>) at../../third_party/android_plat_support/draw_gl_functor.cpp:103

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#230x00000000 in ?? ()


看看这个DirectRender干了什么?


他调用gl操作开始绘制:

#0 Init (_size=5,_command=299, this=0x85f00730) at../../gpu/command_buffer/common/cmd_buffer_common.h:52

注意,已经进入了commandbuffer里面了。

#1 SetCmd<gpu::gles2::cmds::DrawElements> (this=0x85f00730) at../../gpu/command_buffer/common/cmd_buffer_common.h:61

#2 SetHeader (this=0x85f00730) at../../gpu/command_buffer/common/../common/gles2_cmd_format_autogen.h:1913

#3 Init (_index_offset=0, _type=5123, _count=6, _mode=4,this=0x85f00730) at../../gpu/command_buffer/common/../common/gles2_cmd_format_autogen.h:1916

#4 DrawElements (index_offset=0, type=5123, count=6, mode=4,this=<optimized out>) at../../gpu/command_buffer/client/gles2_cmd_helper_autogen.h:419

#5 gpu::gles2::GLES2Implementation::DrawElements(this=0xa0803100, mode=4, count=6, type=5123, indices=0x0) at../../gpu/command_buffer/client/gles2_implementation.cc:878

#6 0x9bed9e1e in cc::GLRenderer::DrawQuadGeometry(this=this@entry=0x9f9fc000, frame=frame@entry=0xa1cff338,draw_transform=..., quad_rect=...,matrix_location=matrix_location@entry=0)

at ../../cc/output/gl_renderer.cc:2285

#7 0x9bedc310 in cc::GLRenderer::DrawSolidColorQuad(this=0x9f9fc000, frame=0xa1cff338, quad=0xa086f790) at../../cc/output/gl_renderer.cc:1545

#8 0x9bed7366 in cc::DirectRenderer::DrawRenderPass(this=this@entry=0x9f9fc000, frame=frame@entry=0xa1cff338,render_pass=render_pass@entry=0x9f7c92e0) at../../cc/output/direct_renderer.cc:386

#9 0x9bed754a in cc::DirectRenderer::DrawFrame(this=0x9f9fc000,

//这个函数会根据frame中的renderpass,遍历他们,并且把renderpass中的quard一个一个调用gl操作绘制出来。

render_passes_in_draw_order=0xa1cff63c,device_scale_factor=<optimized out>, device_viewport_rect=...,device_clip_rect=...,

disable_picture_quad_image_filtering=false) at../../cc/output/direct_renderer.cc:232

#100x9bf1263a in cc::LayerTreeHostImpl::DrawLayers(this=0xa0818c80, frame=0xa1cff620, frame_begin_time=...) at../../cc/trees/layer_tree_host_impl.cc:1605

#110x9bf18a34 in cc::SingleThreadProxy::DoComposite(this=this@entry=0xa085c220, frame_begin_time=...,frame=frame@entry=0xa1cff620) at../../cc/trees/single_thread_proxy.cc:432

#120x9bf19284 in cc::SingleThreadProxy::CompositeImmediately(this=0xa085c220, frame_begin_time=...) at../../cc/trees/single_thread_proxy.cc:350

#130x9bf08e3e in cc::LayerTreeHost::Composite(this=this@entry=0xa0803400, frame_begin_time=...) at../../cc/trees/layer_tree_host.cc:685

#140x9bf6feea in android_webview::HardwareRenderer::DrawGL(this=this@entry=0x9f923f80,stencil_enabled=stencil_enabled@entry=false,framebuffer_binding_ext=0, draw_info=draw_info@entry=0xa1cff8a8)

at ../../android_webview/browser/hardware_renderer.cc:224

#150x9c5d1af8 in android_webview::AwContents::DrawGL(this=<optimized out>, draw_info=0xa1cff8a8) at../../android_webview/native/aw_contents.cc:435

#160x9c6d5bea in draw_gl_50 (this=0x9f9e4fa0, data=0xa1cff964,what=<optimized out>) at../../third_party/android_plat_support/draw_gl_functor.cpp:103

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#320x00000000 in ?? ()





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值