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

执行线程是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.

  1. 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

  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结果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数据.

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

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

    3. 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 ?? ()





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

相关推荐

Android13 SurfaceFlinger composite(合成)流程分析

SurfaceFlinger的composite方法,用于将多个窗口的图像进行合成,主要负责对相关要进行上帧的layer进行,识别排序好,然后合成,有hwc合成的会构建对应OutputLayer传递hwc,GPU合成则直接合成,再传递到hwc中,它主要完成以下几个步骤:从队列中获取所有待合成的缓冲区。将这些缓冲区按照一定的顺序进行合成,生成最终的图像。将合成后的图像提交给HWC进行显示。

liuning1985622的博客 5346

chromium DOM 树构建

浏览器的整个过程,我借用李兵老师的一张简化的流程图如下,把浏览器的过程描述的很简单易懂。浏览器线程负责用户交互、文件储存等功能,网络线程面向渲染进程和浏览器进程等提供网络下载功能,渲染线程主要职责是把从网络下载的 HTML、JavaScript、CSS、图片等资源解析为可以显示和交互的页面,还有很多其他线程,慢慢理。浏览器线程是主线程,负责同用户之间的交互,不能有耗时操作,所以网络线程跟渲染线程是两个独立的线程。上一篇中介绍了network模块,这里开始整理下选染模块的流程,会结合trace 看整个...

木希博客 805

15、Kanzi插件——通过Kanzi Engine插件创建自定义消息类型+代码解析

一、创建trigger中的自定义消息 比如,想创建一个当汽车燃油量发生变化时对应的消息,可以进行如下操作 首先,在插件工程中的头文件中定义一个嵌套类,下面代码中的第23行和29-44行为新添加代码 #ifndef PLUGINDEMO_HPP #define PLUGINDEMO_HPP // Use kanzi.hpp only when you are learning to develop Kanzi applications. // To improve compilation time

Master Cui的博客 1005

QT 工作遇到的小问题

1.QT中清空布局中所有小控件 addWidget后,如果使用removeWidget,界面上的小控件不会立即消失,可以进行如下操作 QRadioButton *button = new QRadioButton("血刀老祖"); button->setParent(nullptr);

guorong520的博客 2417

CANOE DIVA 工程怎样在具体服务前增加前置条件

然后会在CANoe的Test Module视窗中发现一个跟系统条件相关的Test Module模块,在该模块中有生成跟系统条件相关的CAPL 脚本。这里需要根据你的实际项目进行更改,diva工程加载到canoe的工程的时候,会同步加入你创建的cdd文件,这里示例的ABS_ESP 就是你的cdd的ECU命名,后面就是具体的前置条件服务。4、配置完成后,测试用例就会如下图Trace窗口所示,在每一次10 02请求之前都会调用CAPL Function的PreconditionCheck函数中定义的脚本。

weixin_45940007的博客 1971

从零到一:Firefly-RK3399上的Ubuntu镜像构建与GPU加速实战

本文详细介绍了在Firefly-RK3399开发板上从零构建深度优化的Ubuntu系统镜像的全过程,包括交叉编译环境配置、内核定制、GPU加速环境部署(Mesa Panfrost驱动、OpenCL/Vulkan支持)以及深度学习推理优化(TFLite + LinuxNN)。通过实战案例展示了如何充分发挥Mali-T860 GPU的硬件潜力,提升边缘AI应用的性能和能效。

pz8901234的博客 1022

QOpenGLWidget渲染多路yuv,低cpu消耗,解决画面撕裂

QOpenGLWidget渲染多路yuv,低cpu消耗,解决画面撕裂

m0_46597409的博客 4780

cadence——MOS晶体管I-V特性曲线仿真

MOS晶体管I-V特性曲线仿真 目标:使用cadence绘制晶体管的I-V特性曲线(dc仿真) 流程: 新建原理图,将MOS管的栅极电压设为变量Vg,漏极电压设为变量Vd 打开ADEL,点击Variables——Copy From Cellview添加变量;并选择dc仿真,对Vd进行扫描 以Vg作为参变量进行仿真,点击Tools——Parametric Analysis进行设置 选择漏极电流作为输出,进行仿真即可得到I-V特性曲线 ...

skycmq的博客 1万+

blink不能发,这里记录下

程序被加载到内存中运行,形成进程。进程局部变量和函数调用层级关系会保存在栈中。系统栈空间大小可以通过ulimit -s查看和修改,我目前使用的centos6系统,限值默认为8192k;如果程序中递归层级过深(如递归死循环),会造成栈占用空间超限值引发的崩溃。如果使用gdb打开程序运行,保持程序崩溃时不退出,获得此时异常程序的pid,使用pmap pid命令查看,结果打印中的[ stack ]栏的值就是当前程序占用的栈空间大小。与系统限值比较可以判定是否栈空间超限值导致的问题。一般只有递归逻辑不当,无限递归会

ctb1252637337的博客 1万+

基于级联H桥的储能变流器仿真与性能优化

本文深入探讨了基于级联H桥的储能变流器,通过仿真建模与性能优化,详细解析了其模块化结构、载波移相SPWM控制策略及核心性能指标。重点攻克了电池SOC均衡难题,介绍了利用零序电压注入实现相内均衡及功率调节实现相间均衡的实战策略,为提升储能系统效率与电池寿命提供了关键技术路径。

gpu4optimizer的博客 371

Win11 WSL2 Ubuntu 18.04 ROS Gazebo 图形渲染性能调优:从LLVM到NVIDIA GPU的完整指南

本文详细解决了在Win11 WSL2 Ubuntu 18.04环境中运行ROS Gazebo时图形渲染卡顿的问题。通过诊断默认LLVM软件渲染的瓶颈,指导用户更新Mesa驱动PPA源,并关键性地设置环境变量以强制启用NVIDIA GPU硬件加速,最终显著提升仿真性能与流畅度。

weixin_29204749的博客 283

Chromium的Render进程启动过程分析

在配置多进程的情况下,Chromium的网页渲染和JS执行在一个单独的进程中进行。这个进程称为Render进程,由Browser进程启动。在Android平台中,Browser进程就是Android应用程序的主进程,而Render进程就是Android应用程序的Service进程,它们通过UNIX Socket进行通信。本文就详细分析Chromium的Browser进程启动Render进程的过程。

老罗的Android之旅 3万+

6 赫斯曼网管软件industrial hivision用户管理

文章目录前言一、打开Industrial HiVision服务器二、在用户管理界面添加策略三、使用可选策略四、接受策略总结 前言 安装 Industrial HiVision 后,所有人都能广泛使用程序。安全起见,请进行相 关配置,对访问权限进行限制。 本文主要介绍用户管理基于某种角色模型。在访问角色中定义角色名称,通过分配访问权限给这些角色分配角色功能。例如,给管理人员自然要分配可用的权限,而观察员尽管可以登录,但没有能够进行更改的权限。Industrial HiVision 提供以下访问角色: 

t98746194的博客 1381

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

ThreadProxy::BeginMainFrame会触发renderlayer tree中各layer的paint.那么谁触发的BeginMainFrame? ThreadProxy::ScheduledActionSendBeginMainFrame -> Proxy::MainThreadTaskRunner()->PostTask( FROM_HERE, base::

1304

Unity学习笔记之【IK反向动力学操作】

反向动力学,简称IK。相较于正向动力学,反向动力学旨在子级对父级产生的影响。使用IK,可以实现根据目标位置或方向来计算并调整角色的关节(骨骼)链,以使角色的末端(如手臂、腿部等)达到预期的位置或取向。通过使用 Unity 的 IK 功能,你可以实现各种复杂的角色动画效果,如角色抓取、足部对齐、手臂跟随等。 2. 将所视的目标物体拖拽绑定 4. 实现效果如下 :移动角色时注释立方体 实现效果如下

m0_47351846的博客 2955

802.1AS时间同步机制深度解析:从Sync报文到多域冗余设计

本文深度解析了802.1AS时间同步机制,从Sync与Follow_Up报文的核心交互原理入手,详细阐述了其如何通过精确的时钟频率比测量、链路延迟计算和驻留时间补偿来实现微秒乃至纳秒级同步。文章进一步探讨了802.1AS-2020版本引入的多时钟域冗余设计,为构建高可靠的车载TSN网络提供了关键见解和实战配置指南。

pytorch8learner的博客 464

Chromium中多线程及并发技术要点(C/C++)

Chromium中提供的线程机制,以及并发处理的工具类。

求索 5236

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

openxr runtime Monado 源码解析 源码分析:CreateSwapchain 画布 HardwareBuffer共享纹理 渲染线程 xrEndeFrame comp_renderer

openxr runtime Monado 源码解析 源码分析:CreateSwapchain 画布 HardwareBuffer共享纹理 渲染线程 xrEndeFrame comp_renderer

xuer_07的专栏 2033

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

从输入URL到页面展示,这中间发生了什么?net篇

目录 什么是IPC? 常见的IPC及简介 Chromium的IPC Mojo简介 Chromium 中IPC的调用

木希博客 910

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

WebKit之Chromium的Render进程分析

配置多进程的情况下,Chromium的网页渲染和JS执行在一个单独的进程中进行。这个进程称为Render进程,由Browser进程启动。在Android平台中,Browser进程就是Android应用程序的主进程,而Render进程就是Android应用程序的Service进程,它们通过UNIX Socket进行通信。本文就详细分析Chromium的Browser进程启动Render进程的过程。

3312

ZCU106 VCU Linux驱动转裸机驱动篇(二)

VCU Linux驱动转裸机驱动 前言 上一篇说到了上层函数调用硬件驱动,驱动文件libCommon/HardwareDriver.c中,这一片讲一下C++上层控制逻辑,注意大部分数据传输都是调用的的PostMessage~ 开始 系统配置信息 1、首先进入主函数: ConfigFile cfg; SetDefaults(cfg); auto& FileInfo = cfg...

weixin_43873379的博客 1629

LaTex排版技巧

演示文稿 beamer 1.算法 \begin{frame}[plain,t] \frametitle{The feedback vertex set problem in undirected graphs} \vspace{3ex} \xiaowuhao \begin{algorithm}[H]\label{alg} \scriptsize \caption{Primal...

浮生之居士 7281

beamer插入图片_用Latex制作幻灯片(beamer)

LaTeX安装和基本语句参考我的这篇文章:用Latex制作PPT,可以省去自己微调排版,只要把内容填写好,然后选择个主题即可,熟练使用后比较省心。文档类型选择为beamer。 beamer的官方文档链接:beamer的基本结构为:\documentclass{beamer}\usepackage{ctex} %一个支持中文宏包,如果不用中文无法显示\usepackage{graphicx} %这...

weixin_35128544的博客 6668

chromium 各线程的创建

看了一些博客,一般介绍的线程是browser跟render线程。但是ps |grep shell 获取进程号,top -t |grep 进程号,你会看到的,估计跟我看到的差不多,就是这样的哗啦啦的一大片或者还更多,所以很多面试的时候问的都是内存优化,或者是裁剪,或是性能优化,因为问流程性的细节说不清,体现不出深度。之前介绍了URL加载流程,我在 ...

木希博客 1118

Chormium线程模型及应用指南

核心概念 设计上遵循以下原则: 1 不要在UI线程做任何阻塞式的I/O操作,以及其它耗时的操作,通过消息传递把各种操作传给相应用途的线程去做。 2 不鼓励线程加锁机制和线程安全对象。对象只存在一个线程,通过消息来实现线程之间的通信,线程之间不互相阻塞。通过callback对象实现跨线程请求。 一般情况下,我...

weixin_34268843的博客 267
上一篇: blink渲染知识12 - 硬件渲染之触发beginframe
下一篇: blink渲染知识14 - 阶段总结
csshell2002
博客等级 码龄11年 30粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值