Chromium how to display Web pages
Reprint Please specify source: https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//Start_Here_Background_Reading/How_Chromium_ Displays_web_pages.html
If you have a GitHub account, you may want to take star a Https://github.com/ahangchen/Chromium_doc_zh
This document describes from the bottom of how chromium is displaying Web pages. Make sure you have read too many process architectures in this article. You will particularly want to understand the framework of the main components. You might also be interested in multi-process resource loading to see how a Web page gets from the network.
Application concept Layer
(The original Google document on this elaboration is Http://goo.gl/MsEJX, open to all @chromium.org editors)
Each rectangle represents an application concept layer, each layer is not aware of the previous layer, and there is no dependency on the previous layer.
Webkit:safari,chromium and all other WebKit-based browser-sharing rendering engines. WebKit Port is a part of the WebKit that integrates platform-independent system services such as resource loading and imaging.
Glue: The type of WebKit is converted to chromium. This is our "WebKit embedding layer". This is the basis for two browser,chromium, and Test_shell (which allows us to test WebKit).
Renderer/render Host: This is the "multi-process embedding layer" of chromium. It proxies notifications and executes instructions across process boundaries.
Webcontents: A reusable component that is the main class of a content module. It is easy to embed, allowing multiple processes to draw HTML into view. See the Content Module pages for more information.
Browser: Represents a browser window that contains multiple webcontent.
Tab Helpers: A standalone object that can be bound to webcontent (by Webcontentsuserdata promiscuous). The browser binds one of these standalone objects to the webcontent to hold it, one to the website icon, one to the InfoBar, and so on.
Webkit
We use the WebKit open source project to lay out Web pages. This part of the code comes from Apple and is stored in the/third_party/webkit directory. WebKit is mainly composed of "WebCore", which represents the core layout function and "JavaScriptCore", which is used to run JavaScript. We only run JavaScriptCore during the test, and typically we replace it with our own high-performance V8 JavaScript engine. In fact, we're not exactly using the layer that Apple calls "WebKit", which is an embedded API between WebCore and OS X applications such as Safari. For convenience, we often refer to the code learned from Apple as "WebKit".
The WebKit port
At the lowest level, we have our WebKit "port". This is our implementation of the required platform-related features that interact with platform-independent WebCore code. These files are on the WebKit tree, usually in the Chromium directory, or in a file that is suffixed with chromium. Most of our ports are actually OS-Independent: You can think of it as WebCore "Chromium port". However, some aspects, such as font rendering, must be handled differently on different platforms.
- Network communication is handled by our multi-process resource loading system rather than jumping directly from the render thread to the operating system processing
- The image uses the Skia graphics library developed for Android. This is a cross-platform graphics library that handles all graphics and images in addition to text. Skia in the/third_party/skia. The main entrance to graphics operations is/webkit/port/platform/graphics/graphicscontextskia.cpp. It uses a lot of other files in this directory, as well as the files in the/BASE/GFX.
The WebKit glue (glue)
Chromium applications use different types, coding styles, and code layouts and third-party WebKit code. WebKit Glue uses the Google encoding tradition and type for WebKit to provide a more convenient embedded API (for example, we use std::string rather than webcore::string, using gurl instead of Kurl). The glue code is located in/webkit/glue. Glue objects typically have a similar name to the WebKit object, but have a Web prefix at the beginning. For example, Webcore::frame becomes a webframe.
The WebKit glue layer isolates other parts of the chromium code from the WebCore data type to help reduce the impact of webcore changes on the chromium code base. Therefore, the WebCore data type is never used directly by chromium. In order to chromium the convenience, need to touch some WebCore object, will add the API WebKit glue layer.
The test shell application is a bare web browser for testing our WebKit port and glue code. It uses the same glue interface as chromium when communicating with WebKit. It provides developers with a simple way to test new code without ignoring the many complex browser features, threads, and processes. This application is also used to run automated webkit tests. However, the disadvantage of the test shell is that it does not practice webkit in a multi-process manner like chromium. Content modules are embedded in an application called "Content shell," which can be used for testing work very quickly.
Renderer process
Chromium's browser process uses a glue interface embedded in our WebKit port, which does not contain much code: It works primarily as a renderer-side to the browser's IPC channel. The most important class in the renderer is Renderview, located in/content/renderer/render_view_impl.cc. This object represents a Web page. It handles all navigation-related commands with the browser. It drives Renderwidget to provide drawing and input event handling.
Renderview and the browser process communicate with the browser process through the global (per renderer process) Renderprocess object.
Where is the difference between Faq:renderwidget and renderviewhost? Renderwidget is mapped to a Webcore::widget object by implementing an abstract interface (called webwidgetdelegate) in the glue layer. Basically a window on the screen receives input events and what we draw in. A renderview inherits from the Renderwidget, and is a tab or a fill out the contents of the window. In addition to drawing and component input events, it also handles navigation directives. In only one case, renderwidget can exist without Renderview, which is the drop-down selection box in the Web page. The drop-down selection box must be rendered with native window so that they can appear above any other space and eject if necessary. These windows need to draw and accept input, but they do not have a separate Web page (renderview).
Threads in the renderer
Each renderer has two threads (view a multi-process schema page to view the chart, or threading in chromium to understand how to program them). The render thread is the primary object, such as Renderview and all the WebKit code where it runs. When it communicates with the browser, the message is initially sent to the main thread, and the main thread distributes the message to the browser process in turn. In other cases, this allows us to synchronously send messages from the renderer to the browser. This can be used for a small amount of operations when a result from the browser is used for subsequent operations. One example is that JavaScript requests a cookie from a Web page. The renderer thread blocks, and the main thread queues all received messages until the correct response is received. At this point, any received messages are suddenly sent to the renderer thread to perform normal processing.
Browser process
Underlying browser Process object
All IPC that communicates with the renderer process is done in the browser's I/O thread. This thread also handles all network communication so that it is not interfered by the user interface.
When a Renderprocesshost object is initialized on the main thread (when the user interface is running), it creates a new renderer process and a channel proxy IPC object (with a named pipe leading to the renderer), Automatically forwards all messages back to the UI thread's renderprocesshost. A resourcemessagefilter will be installed on this channel and it will filter the messages we specify to be processed directly on I/O threads (such as network requests). This filter takes place in the resourcemessagefilter::onmessagereceived.
The renderprocesshost in the UI thread is responsible for distributing all view-related messages to the appropriate renderviewhost (which handles a limited number of view-related messages on its own). This distribution occurs in renderprocesshost::onmessagereceived.
Upper-level Browser Process object
The view-related message appears in renderviewhost::onmessagereceived. Most of the messages are processed here, and the remainder is forwarded to the Renderwidgethost base class. These two objects are mapped to Renderview and Renderwidget in the renderer (see "renderer process" above to understand what they mean). Each platform has a view class (renderwidgethostview[aura| gtk| mac| Win]) to integrate into the native view system.
Above the Renderview/widget is the Webcontents object, and most of the messages actually end up in the function call of this object. A webcontent represents the content of a Web page. It is the top-level object of the content module and is responsible for displaying the Web page in a rectangular view. See the Content Modules page for more information.
The Webcontents object is contained in a tabcontentswrapper, which is located in chrome/. Responsible for the tab page.
Description sample
Additional examples (including navigation and startup-related code) are in getting Around the Chromium source code.
The life cycle of the SET cursor message
The set cursor is an example of a typical message that the renderer sends to the browser. On the renderer side, here's what happens:
The set cursor message is generated internally by WebKit, usually as a response to an input event. Sets the cursor message to start at Renderwidget::setcursor in content/renderer/render_widget.cc.
It will call Renderwidget::send to distribute the message. This method is also used by Renderview to distribute messages to browser. It will call Renderthread::send.
This invokes Ipc::syncchannel, which internally proxies the message to the main thread of the renderer and sends it to the named pipe for sending to the browser.
Then the browser gets control:
The ipc::channelproxy in Renderprocesshost receives all messages through the browser's I/O thread. It first sends them through Resourcemessagefilter (it distributes the network requests directly on the I/O thread and related messages). Since our message was not filtered out, it continues to be sent to the browser's UI thread (Ipc::channelproxy to do this internally).
The Renderprocesshost::o in content/browser/renderer_host/render_process_host_impl.cc Nmessagereceived gets the message for all view in the corresponding render process. It processes several messages directly and forwards the remainder to the appropriate renderviewhost corresponding to the source renderview that sent the message.
The message arrives at the renderviewhost::onmessagereceived in content/browser/renderer_host/render_view_host_impl.cc. Many of the messages are handled here, but we are not at this point because it is a message from renderwidget that is handled by Renderwidgethost.
All the unhandled messages in Renderviewhost are automatically forwarded to Renderwidgethost, including our settings cursor message.
This message mapped to content/browser/renderer_host/render_view_host_impl.cc eventually receives a message in Renderwidgethost::onmsgsetcursor, and call the appropriate UI function to set the mouse cursor.
Life cycle of a "mouse click" message
Sending a mouse click is an example of a classic browser to renderer.
Windows messages are received by Renderwidgethostviewwin::onmouseevent in the browser's UI thread, and then called Forwardmouseeventtorenderer in the same class.
The forwarding function packages the input time as a cross-platform webmouseevent and finally sends it to the renderwidgethost it is associated with.
Renderwidgethost::forwardinputevent creates an IPC message viewmsg_handleinputevent, serializes the Webinputevent object, Then call Renderwidgethost::send.
This is just forwarding to your own renderprocesshost::send function, which will take turns sending the message to Ipc::channelproxy.
Internally, Ipc::channelproxy proxies the message to the browser's I/O thread and writes it to the corresponding named pipe in the renderer.
Note that many kinds of messages are created in webcontents, especially for navigation classes. These messages follow a similar path from webcontents to Renderviewhost.
The renderer then gets control:
The ipc::channel of the main thread of the renderer reads the message sent by the browser and then ipc::channelproxy the message to the render thread.
Renderview::onmessagereceived got the news. Many kinds of messages are dealt with directly here. Since the Click event is not, it continues to go down (along with all other messages that are not processed) to renderwidget::onmessagereceived, which will turn the message to Renderwidget::onhandleinputevent.
The input event is given to Webwidgetimpl::handleinputevent, where it is converted into a WebKit platformmouseevent class, which is then handed to the Webcore::widget class within WebKit.
"Translation" chromium how to display Web pages