执行线程是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线程。
从建立proxy的callstack中可以看到是:
#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最后的参数就是implthread的threadloop 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));
}
创建该thread的callstack;
#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创建的thread是ui线程:
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,
//下面可以证明,这个loop是ui线程的
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的线程上,就会执行该handler的handleMessage函数:
@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是把layertree从webcorethread copy到uithread.
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) 是真正的同步impl和webcore线程的layertree的逻辑所在。他完成layertree同步
他会同步layerhost tree到laytree impl里面。
如果需要完全同步:
sync_tree->SetRootLayer(TreeSynchronizer::SynchronizeTrees(
root_layer(), sync_tree->DetachLayerTree(), sync_tree));
会调用TreeSynchronizer来完成同步操作。
sync_tree是我们的目标结果。通过从源tree的rootlayer开始递归,创建或者同步各个子layer,来完成rendertree的同步。
在ThreadProxy::ScheduledActionCommit()最后会解除webcore线程的等待。
还看到了在ui线程,其实是impl线程,执行完成commit操作之后,并已经解除了webcore线程的等待之后,在ThreadProxy::ScheduledActionCommit()函数中还会创建rastertask:
#0 cc::TileManager::ScheduleTasks(this=0xa1c0fc00,
//这里应该会为每个需要raster的tile创建一个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::ScheduleTasks(RasterTaskQueue)
这个ImageRasterWorkerPool也是tilemanager的rasterizer.也是rastertask的client.
classCC_EXPORT ImageRasterWorkerPool : public RasterWorkerPool,
public Rasterizer,
public RasterizerTaskClient{
rasterworkerpool把tasks都加入到一个taskgraph里面,然后schedule给了originalthread:
->voidRasterWorkerPool::ScheduleTasksOnOriginThread(RasterizerTaskClient*client, TaskGraph* graph),这个函数会调用到RasterTaskImpl::ScheduleOnOriginThread,其实并没有把这个task交给originthread执行,只是给了调用线程本身一个机会,在真正执行本task之前做一些初始化等工作,比如获得该task的canvas.
还会调用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 activate成activetree:
voidImageRasterWorkerPool::OnRasterFinished(),这个callback是在ImageRasterWorkerPool::ScheduleTasks函数中注册进去的。当所有rastertask完成之后会调用他。
->TileManager::DidFinishRunningTasks
-》ready_to_activate_check_notifier_.Schedule();
这会向ui线程post一个task执行TileManager::CheckIfReadyToActivate函数。目的在于让ui线程在某个时间后,执行检查是否可以activiate操作。
下面是ui线程执行TileManager::CheckIfReadyToActivate的callstack:如果可以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 ?? ()
那么可以知道,只有在raster了pendingtree的内容之后,才会把pendingtree同步给activetree. 然后呢会通知,需要重新合成。合成时会调用drawLayer等操作,生成compositorframe. 之后会把合成结果commit,也就是提交给parenetcompositr的layertree里面。
注意,implthread这边,有2tree, pending tree, active tree, 后者是正在显示的tree.需要通过activation操作,将pendingtree设置成activetree. 同步操作发生在pendingtree.
所以,从webcore线程的layertreecommit到impl线程的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.猜测,当所有需要raster的tile都被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());
这都是在同步pendingtree到activetree.
...
SetNeedsRedraw();
这个函数大概会让laytree host impl来drawLayers到一个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 {,可以包含一个RenderPass的list.
2. void LayerTreeHostImpl::DrawLayers(FrameData*frame,
base::TimeTicks frame_begin_time) {
这个函数依赖准备好了renderpass的FrameData来开始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交给outputsurface的frame_holder.//那么这个frame_holder是如何被后续使用的?
当然,ui线程在执行onDraw时,更是因该调用childcompositor合成一个compositorframe的。比如:
那么还有一个调用cc::DelegatingRenderer::DrawFrame的场景,就是onDraw在ui线程被调用时,看callstack:我觉的这个场景是ui线程在执行网页的composite,也就是把当前的activetree绘制出来。其实也是合成.
可见下面的ui线程的ondraw操作干了两件事:1. 告诉webcore线程准备下个paintframe。2. 使用当前的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()
→先给schedulerStateMachine的need_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::DrawSwapInternal(forced_draw= false)
→ 1. LayerTreeHostImpl::PrepareToDraw(FrameData* frame)
2. LayerTreeImpl::UpdateDrawProperties
3. LayerTreeHostImpl::PrepareToDraw(FrameData* frame)
-->CalculateRenderPasses(FrameData* frame)
4. LayerTreeHostImpl::DrawLayers(frame)
-->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交给outputsurface的frame_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),将需要raster的tile都创建rastertask放到对列里面准备raster.
-
ThreadProxy::DidManageTiles
-->Scheduler::DidManageTiles
我们知道上面的draw且swap buffer之后,SynchronousCompositorOutputSurface的frame_holder被赋值了一个compositorframe, 那么他是如何被使用的?这就是childcompositor合成生成的compositorframe数据。这个东西需要commit给parentcompositor 的rootlayer下面。
上面的代码一种调用场景是onDraw,这个触发是在合成完成之前。这里又是讲触发redraw的callstack.
#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时新draw的compositorframe设置给
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
-
把frame赋值给draw_gl_input->frame
-
把drawgl input 设置给sharedrender state.:SharedRendererState::SetDrawGLInput(DrawGLInput)
-
BrowserViewRenderer::DidComposite
-
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结果commit到impl线程的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数据.
-
DelegatedFrameProvider::SetFrameData,将frame数据传给它.干什么用?
-
创建DelegatedRendererLayer,并将DelegatedFrameProvider作为参数。这样此delegatedrender layer就可以包含了之前的compositorframe的数据了。
-
root_layer_->AddChild(delegated_layer_);将这个delegatedlayer设置为rootlayer的child.这样,以后绘制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 host和layertree 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挂载到parentcompositor的layertree上了,所以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的内容绘制出来,就像当于向gl的surface上绘制好了.剩下就是系统做得了?而之前的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 ?? ()