Google Chrome Browser source Analysis (vii) _ Google

Source: Internet
Author: User

When the last time that the received HTTP data was communicated to another thread through the pipeline, it did not send the data directly past, but rather sent the data in the shared memory handle to the past, to achieve efficient communication purposes. The following is an analysis of the resource processing process, what to do after receiving the message. The processing code for this message is as follows:

#001 void Resourcedispatcher::onreceiveddata (int request_id,

#002 Sharedmemoryhandle Shm_handle,

#003 int Data_len) {

#004//Acknowlegde The reception of this data.

responded to the message by saying that the data had been received.

#005 ipc::message::sender* Sender = Message_sender ();

#006 if (sender)

#007 Sender->send (

#008 New Viewhostmsg_datareceived_ack (Msg_routing_none, request_id));

#009

#010 Dcheck (shm_handle && data_len > 0) | | (!shm_handle &&!data_len));

Open the shared memory file, using a read-only method.

#011 sharedmemory Shared_mem (Shm_handle, true); Read Only

#012

Finds the request identification number of the resource that requested the download.

#013 Pendingrequestlist::iterator it = Pending_requests_.find (request_id);

If the corresponding request identification number is not found, it is returned directly without processing the data.

#014 if (it = = Pending_requests_.end ()) {

#015//This might happen for Kill () Ed requests on "WebKit end", so perhaps

#016//It shouldn ' t be a warning ...

#017 Dlog (WARNING) << "Got data for a nonexistant or finished request";

#018 return;

#019}

#020

The corresponding request identification number is found here, and the data is processed in the request information.

#021 pendingrequestinfo& request_info = it->second;

#022

#023 if (Data_len > 0 && shared_mem. Map (Data_len)) {

#024 Resource_log ("dispatching" << data_len << "bytes for" <<

#025 request_info.peer->geturlfordebugging ());

#026 const char* data = static_cast<char*> (Shared_mem.memory ());

#027 request_info.peer->onreceiveddata (data, Data_len);

#028}

#029}

The above function implementation receives the HTTP data, and puts the data into the requested buffer, but it does not know when to receive the data completes, obviously has another message to do this work, is the following class Resourcedispatcherhost function:

#001 bool onresponsecompleted (int request_id, const urlrequeststatus& status) {

#002 Receiver_->send (New Viewmsg_resource_requestcomplete (

#003 routing_id_, request_id, status));

#004

#005//If We still have a read buffer, then "about caching it for later ...

#006 if (spare_read_buffer_) {

#007 Read_buffer_.reset ();

#008} else if (Read_buffer_.get () && read_buffer_->memory ()) {

#009 spare_read_buffer_ = Read_buffer_.release ();

#010}

#011 return true;

#012}

In this function, by sending a message viewmsg_resource_requestcomplete to notify the resource process has completed the network data received, you can go to the next processing. The message is then processed in the resource process, and the next time the code is analyzed.




The last time you said that in class Resourcedispatcher you receive HTTP data messages and further process the data. So where do the Resourcedispatcher classes send the data they receive? It's a need for us to understand it. Through further tracking, it is found that the Resourcedispatcher::onreceiveddata function calls the Webcore::resourcehandleinternal class to process, that is, the received data thrown to the WebCore to deal with. As in the following code:

#001 void Resourcedispatcher::onreceiveddata (int request_id,

#002 Sharedmemoryhandle Shm_handle,

#003 int Data_len) {

#004//Acknowlegde The reception of this data.

#005 ipc::message::sender* Sender = Message_sender ();

......

#023 if (Data_len > 0 && shared_mem. Map (Data_len)) {

#024 Resource_log ("dispatching" << data_len << "bytes for" <<

#025 request_info.peer->geturlfordebugging ());

#026 const char* data = static_cast<char*> (Shared_mem.memory ());

#027 request_info.peer->onreceiveddata (data, Data_len);

#028}

#029}

The 27th line of code above is to call the WebCore class Resourcehandleinternal::onreceiveddata function, so that the data stored in the WebCore inside, that is, webkit inside. The calling procedure passes through the following faces:

1) Webcore::resourceloader::d idreceivedata

2) Webcore::subresourceloader::d idreceivedata

3) Webcore::loader::d idreceivedata

4) Webcore::cachedimage::d ata

This is to cache the image data so that the rendering engine can be invoked later. This time on the analysis to here, finally how to put the data into the WebKit to find out, the next time to see how WebKit is how to show the data.





The last time we talked about image caching, in many cases it was the display of text, the interpretation of HTML. To display the Web page, it must be first received from HTTP Web page data, and then use the HTML parser to explain the HTML language, and finally based on HTML to generate all the elements can be displayed, and then because these elements to generate BMP bitmap, so that only the BMP location to display in the window will be all right. This process looks simple, in fact, is a very complex process, now take you to in-depth analysis of the process, the basic WebKit process to make clear, but also the process of analyzing the Web page chrome. This process is as follows:

1) the Resourcedispatcher::onreceiveddata () resource assignment class receives the Web page data.

2) the Webcore::resourcehandleinternal::onreceiveddata () Webcore::resourcehandleinternal class receives the data.

3) Webcore::resourceloader::d idreceivedata () the resource load class receives the data.

4) Webcore::mainresourceloader::d idreceivedata () main resource class received the data.

5) Webcore::mainresourceloader::adddata () main resource class holds data.

6) The Webcore::frameloader::receiveddata () Framework load class holds the data.

7) WebCore::D ocumentloader::receiveddata () document loading class to save data.

8) WebCore::D ocumentloader::commitload () The document loading class submits all received data.

9) Webcore::frameloader::committedload () Framework loading class submission data.

Webframeloaderclient::committedload () page frame load class submit data.

Webframeimpl::D idreceivedata () Web Framework implementation class holds the submitted data.

The Webcore::frameloader::adddata () framework loads the class to hold the data.

Webcore::frameloader::write () writes Web page data to HTML buffer.

The Webcore::htmltokenizer::write () HTML non-terminal parser is saved.

Webcore::htmltokenizer::p rocesstoken () HTML non-terminal parser analyzes HTML data.

Webcore::htmlparser::p arsetoken () HTML Analyzer analyzes Web page data.

Webcore::htmlparser::insertnode () analyzes the nodes in a Web page and begins inserting.

Webcore::text::attach () discovers a text node and saves it.

Webcore::node::createrendererifneeded () Creates a node that can be rendered.

Webcore::text::createrenderer () begins creating a text rendering object.

Webcore::rendertext::rendertext () Creates a text rendering object RenderText.

From the above process, you can see that the analysis process is more complex, but finally the analysis of the Web page data this main line caught, other things, are for this main line and carried out. As long as follow this main line, the corresponding class further analysis, you can make the whole process clear. In the final step, the RenderObject object is generated, and all RenderObject objects are saved by generating a tree based on the analysis HMTL. When the interface is to be displayed, it is actually to traverse the entire RenderObject object tree. The next time to analyze how the interface shows these objects.



Through the last analysis, we see all Web page data after the HTML parser, will become a RenderObject object, then how these RenderObject objects are displayed to the interface. Now with this query to analyze the following code, this will certainly find a solution. How to find the entrance. In fact, you can start from the interface display class, you can see the Display interface window class name is called Chrome_renderwidgethosthwnd, with this class name, you can go to the code to see where it is.

#001 class Renderwidgethost;

#002 class Webmouseevent;

#003 class Webcursor;

#004

#005 typedef cwintraits<ws_child | Ws_clipchildren | Ws_clipsiblings, 0>

#006 renderwidgethosthwndtraits;

#007

#008 static const wchar_t* Const KRENDERWIDGETHOSTHWNDCLASS =

#009 L "Chrome_renderwidgethosthwnd";

You can see that the window class name is defined here and then followed by Krenderwidgethosthwndclass to find the display window, as follows:

#001 class Renderwidgethosthwnd:

#002 Public Cwindowimpl<renderwidgethosthwnd,

#003 CWindow,

#004 Renderwidgethosthwndtraits>

#005 public Renderwidgethostview {

#006 Public:

#007 Renderwidgethosthwnd (renderwidgethost* render_widget_host);

#008 virtual ~renderwidgethosthwnd ();

#009

#010 void Set_close_on_deactivate (bool close_on_deactivate) {

#011 close_on_deactivate_ = close_on_deactivate;

#012}

#013

#014 void Set_parent_hwnd (hwnd parent) {parent_hwnd_ = parent;}

#015

#016 declare_wnd_class_ex (krenderwidgethosthwndclass, cs_dblclks, 0);

With the above analysis, you can find the window class Renderwidgethosthwnd that shows the page, in which the main display position is in the void Renderwidgethosthwnd::onpaint (HDC dc) function, and its code is as follows:

#001 void Renderwidgethosthwnd::onpaint (HDC DC) {

#002 Dcheck (Render_widget_host_->process ()->channel ());

#003

#004 cpaintdc paint_dc (m_hwnd);

#005 Hbrush White_brush = reinterpret_cast

#006

#007 renderwidgethost::backingstore* Backing_store =

#008 Render_widget_host_->getbackingstore ();

#009

#010 if (backing_store) {

#011 gfx::rect Damaged_rect (paint_dc.m_ps.rcPaint);

#012

#013 Gfx::rect Bitmap_rect (

#014 0, 0, backing_store->size (). Width (), backing_store->size (). height ());

#015

#016 gfx::rect paint_rect = bitmap_rect. Intersect (Damaged_rect);

#017 if (!paint_rect. IsEmpty ()) {

#018 BitBlt (PAINT_DC.M_HDC,

#019 paint_rect.x (),

#020 Paint_rect.y (),

#021 paint_rect.width (),

#022 paint_rect.height (),

#023 BACKING_STORE->DC (),

#024 paint_rect.x (),

#025 Paint_rect.y (),

#026 srccopy);

#027}

......

#058}

In fact, this function is through the following send a message to another process to render BMP pictures,

Send (New Viewmsg_repaint (Routing_id_, view_size));

Then who will receive the Viewmsg_repaint message. To continue to look carefully, you will be dealt with in the following class functions:

void Renderwidget::onmsgrepaint (const gfx::size& size_to_paint)

In this function, it is not the final result, it will invoke other threads to handle the rendering in order to achieve asynchronous results. Its invocation process is as follows:

1) Renderwidget::D odeferredpaint () line Chengri Start rendering Web page display

2) Renderwidget::P aintrect () window starts to display

3) Webviewimpl::P aint () The Web view class begins to display.

4) Webframeimpl::P aint () The Web framework class begins to display.

5) Webcore::scrollview::p aint () scrolling window display.

6) Webcore::frame::p aint () the frame shown in WebCore.

7) Webcore::renderlayer::p aint () layered display.

8) Webcore::renderlayer::p Aintlayer ()

9) Webcore::renderblock::p aint () shows each area in each layer.

Webcore::renderblock::p aintobject () displays the objects in this area.

Webcore::renderblock::p aintcontents () shows what needs to be displayed.

Webcore::renderflow::p aintlines () You need to display text here.

Webcore::rootinlinebox::p aint () starts to display a line of text.

Webcore::inlineflowbox::p aint () to arrange one line of text.

Webcore::inlinetextbox::p aint ()

Webcore::graphicscontext::d Rawtext () for a single text display.

Webcore::font::d Rawtext () This invokes the font class to turn the encoding of the text into a bitmap.

Webcore::font::d rawsimpletext () This shows the bitmap in the interface memory.

Through the above analysis, you can see that the process of displaying a string of words is such a complicated process. Other pictures show the same process, all of them into bitmaps, and then layered display. So how does JavaScript appear? This will be more complicated than the above process, and then analyze it carefully. Next time, take a closer look at some of the class features in these processes.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.