I investigated when enabling Accelerated Compositing. However, process is the same to software path until RenderLayer::styleChanged() in 3. Notify filters changed.
1. Animation loop : loop using timer in AnimationControllerPrivate
FrameView::serviceScriptedAnimations() <- request animation frame callback
AnimationController::serviceAnimations()
AnimationControllerPrivate::animationFrameCallbackFired()
AnimationControllerPrivate::animationTimerFired()AnimationControllerPrivate::updateAnimationTimer()
1) m_animationTimer.startRepeating() if needed: creating loop
AnimationControllerPrivate::updateAnimations()
Document::updateStyleIfNeeded()
void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style)
{
if (!isText() && style)
setStyle(animation()->updateAnimations(this, style.get()));
else
setStyle(style);
}
1) Blend FilterOperation
2) Notify filters changed
2. Blend FilterOperation : Create FilterOperations per frame.
AnimationController::updateAnimations()
CompositeAnimation::animate()
KeyframeAnimation::animate()
CSSPropertyAnimation::blendProperties()
PropertyWrapperAcceleratedFilter::blend()
BasicColorMatrixFilterOperation::blend()
3. Notify filters changed : notify FilterOperations changed to RenderLayer
RenderObject::setStyle()
RenderLayerModelObject::styleDidChange()
RenderLayer::styleChanged()
4) ensure backing if needed
5) notify flush
4. ensure backing if needed : create RenderLayerBacking at the first time.
RenderLayerCompositor::updateLayerCompositingState()
RenderLayerCompositor::updateBacking()
RenderLayer::ensureBacking()
5. notify flush : notify FilterOperations changed to GraphicsLayer
RenderLayerBacking::updateGraphicsLayerGeometry()
RenderLayerBacking::updateFilters()
GraphicsLayerTextureMapper::setFilters()
LayerTreeCoordinator[AcceleratedCompositingContext]::scheduleLayerFlush()
'Technology > Webkit' 카테고리의 다른 글
High-DPI and viewport and sub pixel layout (2) | 2012.12.11 |
---|---|
WebKit css3 animations on Accelerated Compositing (1) | 2012.10.23 |
WebKit Filters Animation Internal (1) | 2012.10.20 |
WebKit2 Injected Bundle (1) | 2012.10.15 |
oprofile (2) | 2012.06.02 |
massif 메모리 사용량을 측정하자 (0) | 2012.05.31 |
Refer to
http://lists.webkit.org/pipermail/webkit-gtk/2012-May/001078.html
void WebProcess::postInjectedBundleMessage(const CoreIPC::DataReference& messageData)
{
InjectedBundle* injectedBundle = WebProcess::shared().injectedBundle();
...
}
in Tools/WebKitTestRunner/InjectedBundle/InjectedBundleMain.cpp
void WKBundleInitialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
WTR::InjectedBundle::shared().initialize(bundle, initializationUserData);
}
in Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
void InjectedBundle::initialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
WKBundleClient client = {
};
WKBundleSetClient(m_bundle, &client);
}
in Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp
void InjectedBundle::initializeClient(WKBundleClient* client)
{
m_client.initialize(client);
}
2. create page
in Source/WebKit2/WebProcess/WebPage/WebPage/WebPage.cpp
PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
{
....
if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
WebProcess::shared().injectedBundle()->didCreatePage(page.get());
....
}
in Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
void InjectedBundle::didCreatePage(WKBundlePageRef page)
{
m_pages.append(adoptPtr(new InjectedBundlePage(page)));
}
in Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page)
: m_page(page)
, m_world(AdoptWK, WKBundleScriptWorldCreateWorld())
{
WKBundlePageLoaderClient loaderClient = { };
WKBundlePageSetPageLoaderClient(m_page, &loaderClient);
WKBundlePageResourceLoadClient resourceLoadClient = { };
WKBundlePageSetResourceLoadClient(m_page, &resourceLoadClient);
WKBundlePagePolicyClient policyClient = { };
WKBundlePageSetPolicyClient(m_page, &policyClient);
WKBundlePageUIClient uiClient = { };
WKBundlePageSetUIClient(m_page, &uiClient);
WKBundlePageEditorClient editorClient = { };
WKBundlePageSetEditorClient(m_page, &editorClient);
#if ENABLE(FULLSCREEN_API)
WKBundlePageFullScreenClient fullScreenClient = { };
WKBundlePageSetFullScreenClient(m_page, &fullScreenClient);
#endif
}
in Source/WebKit2/WebProcess/WebPage/WebPage/WebPage.cpp
void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client)
{
....
m_loaderClient.initialize(client);
}
3. loader callback
in Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
void WebFrameLoaderClient::postProgressFinishedNotification()
{
if (WebPage* webPage = m_frame->page()) {
if (m_frame->isMainFrame()) {
// Notify the bundle client.
webPage->injectedBundleLoaderClient().didFinishProgress(webPage);
webPage->send(Messages::WebPageProxy::DidFinishProgress());
}
}
}
in Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
void InjectedBundlePage::didFinishProgress(WKBundlePageRef, const void *clientInfo)
{
static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didFinishProgress();
}
Build
InjectedBundle은 shared library로 따로 빌드된다. WebKitTestRunner를 실행히 env로 shared library의 path가 세팅된다.
in Tools/WebKitTestRunner/GNUmakefile.am
# The InjectedBundle library allows the render process to load harness code.
if ENABLE_WEBKIT2
noinst_LTLIBRARIES += Libraries/libTestRunnerInjectedBundle.la
endif
How to send InjectedBundle path from UI Process to Web Process
위에서 서술하다 싶이 env로 UI Process의 TestController가 알아낸후 WebContext에게 알려준다.
in Tools/WebKitTestRunner/gtk/main.cpp
int main(int argc, char** argv)
{
gtk_init(&argc, &argv);
// Prefer the not installed web and plugin processes.
WTR::TestController controller(argc, const_cast<const char**>(argv));
return 0;
}
in Tools/WebKitTestRunner/TestController.cpp
void TestController::initialize(int argc, const char* argv[])
{
...
initializeInjectedBundlePath();
...
m_context.adopt(WKContextCreateWithInjectedBundlePath(injectedBundlePath()));
...
}
in Source/WebKit2/UIrocess/WebContext.cpp
PassRefPtr<WebContext> WebContext::create(const String& injectedBundlePath)
{
JSC::initializeThreading();
WTF::initializeMainThread();
RunLoop::initializeMainRunLoop();
return adoptRef(new WebContext(ProcessModelSharedSecondaryProcess, injectedBundlePath));
}
What is InjectedBundle in UI Process
UI Process에도 callback을 inject하는 듯한 코드들이 있다. (밑에처럼)
이것은 shared library를 ld하여 callback을 등록한다는 개념의 injected bundle보다는, 그냥 callback을 등록하는 코드이다.
코드를 reuse하기위해 콜백등록 패턴을 그냥 쓰는데, 코드를 읽는데 굉장한 혼란을 준다.
in Tools/WebKitTestRunner/TestController.cpp
void TestController::initialize(int argc, const char* argv[])
{
...
WKContextInjectedBundleClient injectedBundleClient = {
kWKContextInjectedBundleClientCurrentVersion,
this,
didReceiveMessageFromInjectedBundle,
didReceiveSynchronousMessageFromInjectedBundle,
0 // getInjectedBundleInitializationUserData
};
WKContextSetInjectedBundleClient(m_context.get(), &injectedBundleClient);
...
}
'Technology > Webkit' 카테고리의 다른 글
WebKit css3 animations on Accelerated Compositing (1) | 2012.10.23 |
---|---|
WebKit Filters Animation Internal (1) | 2012.10.20 |
WebKit2 Injected Bundle (1) | 2012.10.15 |
oprofile (2) | 2012.06.02 |
massif 메모리 사용량을 측정하자 (0) | 2012.05.31 |
cachegrind in valgrind (5) | 2012.05.31 |
how to use
http://lbrandy.com/blog/2008/11/oprofile-profiling-in-linux-for-fun-and-profit/
how to profile WebKit
http://trac.webkit.org/wiki/QtWebKitProfilingSetup
how to build vmlinux and attach to oprofile
http://lovebug356.blogspot.kr/2008/06/oprofile-setup-on-ubuntu.html
ubuntu 12.04 is not supported
https://launchpad.net/ubuntu/precise/amd64/oprofile/0.9.6-1.3ubuntu1
various profile wiki
http://wiki.gnashdev.org/Profiling
'Technology > Webkit' 카테고리의 다른 글
WebKit Filters Animation Internal (1) | 2012.10.20 |
---|---|
WebKit2 Injected Bundle (1) | 2012.10.15 |
oprofile (2) | 2012.06.02 |
massif 메모리 사용량을 측정하자 (0) | 2012.05.31 |
cachegrind in valgrind (5) | 2012.05.31 |
WebKit2 Rendering 분석 (only if using Texture Mapper) (1) | 2012.01.28 |