{"id":57,"date":"2021-12-13T10:23:04","date_gmt":"2021-12-13T10:23:04","guid":{"rendered":"http:\/\/blogs.igalia.com\/jkim\/?p=57"},"modified":"2021-12-14T04:35:30","modified_gmt":"2021-12-14T04:35:30","slug":"mojo-conversion-in-printing","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/jkim\/2021\/12\/13\/mojo-conversion-in-printing\/","title":{"rendered":"Mojo conversion in printing"},"content":{"rendered":"\n\n<h2 class=\"wp-block-heading\">[from the renderer to the browser]<\/h2>\n\n\n\n\nFor the past few years, Chromium has put effort into the conversion of the legacy IPC system to Mojo.<br><br><br>\n\n\n\nIf you need information about Mojo, please take a look at the documents and a video below.\n\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/main:mojo\/\">Chromium&#8217;s <code>mojo\/<\/code> directory<\/a><\/li><li><a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/main:docs\/mojo_and_services.md\">Intro to Mojo &amp; Services<\/a><\/li><li><a href=\"https:\/\/www.youtube.com\/watch?v=o-nR7enXzII\">Mojo &#8211; Chrome\u2019s inter-process communication system (Chrome University 2019)<\/a><\/li><\/ul>\n\n\n\n\n<br>Igalia also joined the task, and we converted the old-style IPC communication into Mojo messages. The highest priority was the conversion for the messages in \/\/content area, and then we expanded into other components. Regarding the work on Mojo conversion by Igalia, please see <a href=\"https:\/\/mariospr.org\/2020\/07\/08\/chromium-now-migrated-to-the-new-c-mojo-types\/\">the blog post<\/a> from one of my teammates, Mario.<br><br>\n\n\n\nIn this blog post, I\u2019d like to talk about the Mojo conversion in the printing module. I gave a small<a href=\"https:\/\/www.youtube.com\/watch?v=VrEP7SPfQVM&amp;t=2682s\"> talk<\/a> about this during BlinkOn14 lightning talk.<br><br>\n\n\n\nChromium architecture is based on the<a href=\"https:\/\/www.chromium.org\/developers\/design-documents\/multi-process-architecture\"> multiprocess<\/a> model and a big amount of IPC messages are for the communication between the browser process and the renderer process. The printing module also communicates with both of them. When I started to work on the Mojo conversion in the printing module, the conversion from the browser to the renderer had already been completed. So, I looked into the messages from the renderer to the browser.<br><br><br>\n\n\n\n\n<h1 class=\"wp-block-heading\">Printing in Chromium<\/h1>\n\n\n\n\nI knew that the printing functionality is great while I was using the Chromium browser, but I was not aware that it has a lot of features with consideration of various environments. On the desktop, you could use it through<br><br>\n\n\n\n\n<ul class=\"wp-block-list\"><li>window.print() from javascript code.<\/li><li>Keyboard shortcut (e.g. ctrl+p)<\/li><li>From the context menu: print a page or print a selection.<\/li><li>The three dots menu<\/li><\/ul>\n\n\n\n\nIt might have more entry points I don\u2019t know yet.<br><br><br>\n\n\n\nOnce it arrives at the printing main code, it has almost similar code flow but many issues I faced were caused by these various entrance points and use cases. If you have used the printing from Chromium, I believe you\u2019re aware of the printing preview. But, did you know that you could also directly use the printing native menu, skipping the printing preview? I didn\u2019t know it. To disable the print preview,<br>\n\n\n\n\n<pre class=\"wp-block-preformatted\">Command line Switch option: --disable-print-preview\nKeyboard shortcut:\n  - Preview : ctrl+p\n  - Without Preview : ctrl+shift+p\n<\/pre>\n\n\n\n\nAnd, the printing module also supports printing on the headless and Android WebView. Whenever the CL related to the Mojo conversion landed, I tried to verify all the possible combinations but it always contained regressions.<br><br><br><br>\n\n\n\n\n<h1 class=\"wp-block-heading\">Printing with legacy IPC vs Printing with Mojo<\/h1>\n\n\n\n\nHere are legacy IPC messages. You can see how many messages the printing module had and how they were distributed.\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blogs.igalia.com\/jkim\/files\/2021\/12\/UsingLegacyIPC-1024x541.png\" alt=\"Using legacy IPC\" \/><\/figure>\n\n\n\n<br>And, the next is how they have been changed now. You can see each end point.\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blogs.igalia.com\/jkim\/files\/2021\/12\/UsingMojo-1024x348.png\" alt=\"Using Mojo\" \/><\/figure>\n\n\n\nFor the interfaces added, you could refer to <a href=\"https:\/\/source.chromium.org\/chromium\/chromium\/src\/+\/main:components\/printing\/common\/print.mojom\">\/\/components\/printing\/common\/print.mojom<\/a>.\n\n\n\n<br><br>So why do we want to use Mojo instead of the legacy IPC? Legacy IPC is deprecated in Chromium and Mojo helps to refactor Chromium into a large set of smaller services. For more detail, please refer to this <a href=\"https:\/\/chromium.googlesource.com\/chromium\/src.git\/+\/51.0.2704.48\/docs\/mojo_in_chromium.md\">document<\/a>. With the Mojo conversation in printing, we also removed multiple layers in printing for legacy IPC.<br><br><br>\n\n\n\n\n<h2 class=\"wp-block-heading\">Replacing EnableMessagePumping()<\/h2>\n\n\n\n\nThere were a few challenges while working on the printing Mojo conversion. One of them was when I needed to find something to replace EnableMessagePumping(). That is a function that supports pumping messages while a sync message is waiting for a reply. It was not used in many places because it could increase complexity during IPC and the messages used it or the use cases had been cleaned up already. In the printing module, there were two legacy IPC messages using it. After much deliberation on how to handle this part, I defined a sync message and passed a callback that quits the runloop. Then, the nested runloop allows running tasks while it\u2019s waiting for a reply.<br><br><br>\n\n\n\n\n<h1 class=\"wp-block-heading\">A racing issue<\/h1>\n\n\n\n\nThere were also some interesting issues. One of them was related to handling the printing result of multiple renderer processes. When there is more than one renderer process by subframes, the browser process manages all the results from each renderer. In that case, there was a racing issue like below.\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blogs.igalia.com\/jkim\/files\/2021\/12\/RacingIssue-1024x572.png\" alt=\"A racing issue\"><\/figure>\n\n\n\nThe sub frame should be handled after the compositor for the main frame is created but it could be handled before the main frame. So, it\u2019s been updated with queuing the sub frame if the compositor is not created and handling the queue after the compositor is created.<br><br><br>\n\n\n\n\n<h1 class=\"wp-block-heading\">Wrap up<\/h1>\n\n\n\n\nWith the Mojo conversion in the printing module, I\u2019ve naturally cleaned up classes, structures, and files that are no longer necessary. \\o\/<br><br><br>\n\n\n\nThere were a few more problems after I thought the work was done, but with the help of many people I was able to solve them safely. Thanks a lot, all people who reviewed CLs, reported issues, and discussed how to fix them.<br><br><br>\n","protected":false},"excerpt":{"rendered":"<p>[from the renderer to the browser] For the past few years, Chromium has put effort into the conversion of the legacy IPC system to Mojo. If you need information about Mojo, please take a look at the documents and a &hellip; <a href=\"https:\/\/blogs.igalia.com\/jkim\/2021\/12\/13\/mojo-conversion-in-printing\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":55,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[12,10,11],"class_list":["post-57","post","type-post","status-publish","format-standard","hentry","category-chromium","tag-mojo","tag-mojofication","tag-printing"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/posts\/57","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/users\/55"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/comments?post=57"}],"version-history":[{"count":36,"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/posts\/57\/revisions"}],"predecessor-version":[{"id":112,"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/posts\/57\/revisions\/112"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/media?parent=57"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/categories?post=57"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/jkim\/wp-json\/wp\/v2\/tags?post=57"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}