Planet Igalia Chromium

March 15, 2017

Manuel Rego

CSS Grid Layout is Here to Stay

It’s been a long journey but finally CSS Grid Layout is here! 🚀 In the past week, Chrome 57 and Firefox 52 were released, becoming the first browsers to ship CSS Grid Layout unprefixed (Explorer/Edge has been shipping an older, prefixed version of the spec since 2012). Not only that, but Safari will hopefully be shipping it very soon too.

I’m probably biased after having worked on it for a few years, but I believe CSS Grid Layout is going to be a big step in the history of the Web. Web authors have been waiting for a solution like this since the early days of the Web, and now they can use a very powerful and flexible layout module supported natively by the browser, without the need of any external frameworks.

Igalia has been playing a major role in the implementation of CSS Grid Layout in Chromium/Blink and Safari/WebKit since 2013 sponsored by Bloomberg. This is a blog post about that successful collaboration.

A blast from the past

Grids are not something new at all, since we can even find references to them in some of the initial discussions of the CSS creators. Next is an excerpt from a mail by Håkon Wium Lie in June 1995 to www-style:

Grids! Let the style sheet carve up the canvas into golden rectangles, and use an expert system to lay out the elements!! Ok, drop the expert system and define a set of simple rules that we hardcode.. whoops! But grids do look nice!

-h&kon

Since that time the Web hasn’t stopped moving and there have been different solutions and approaches to try to solve the problem of having grid-based designs in HTML/CSS.

At the beginning of the decade Microsoft started to work on what eventually become the CSS Grid Layout initial specification. This spec was based on the Internet Explorer 10 implementation and the experience gathered by Microsoft during its development. IE10 was released in 2012, shipping a prefixed version of that initial spec.

Then Google started to add support to WebKit at the end of 2011. At that time, WebKit was the engine used by both Chromium and Safari; later in 2012 it would be forked to create Blink.

Meanwhile, Mozilla had not started the Grid implementation in Firefox as they had some conflicts with their XUL grid layout type.

Igalia and Bloomberg collaboration

Bloomberg uses Chromium and they were looking forward to having a proper solution for their layout requirements. They detected performance issues due to the limitations of the current layout modules available on the Web. They see CSS Grid Layout as the right way to fix those problems and cover their needs.

Bloomberg decided to push CSS Grid Layout implementation as part of the collaboration with Igalia. My colleagues, Sergio Villar and Xan López, started to work on CSS Grid Layout around the summer of 2013. In 2014, Javi Fernández and I replaced Xan, joining the effort as well. We’ve been working on this for more than 3 years and counting.

At the beginning, we were working together with some Google folks but later Igalia took the lead role in the development of the specification. The spec has evolved and changed quite a lot since 2013, so we’ve had to deal with all these changes always trying to keep our implementations up to date, and at the same time continue to add new features. As the codebase in Blink and WebKit was still sharing quite a lot of things after the fork, we were working on both implementations at the same time.

Igalia and Bloomberg working together to build a better web Igalia and Bloomberg working together to build a better web

The results of this collaboration have been really satisfactory, as now CSS Grid Layout has shipped in Chromium and enabled by default in WebKit too (which will hopefully mean that it’ll be shipped in the upcoming Safari 10.1 release too).

Thanks @jensimmons for the feedback regarding Safari 10.1.

And now what?

Update your browsers, be sure you grab a version with Grid Layout support and start to use CSS Grid Layout, play with it, experiment and so on. We’d love to get bug reports and feedback about it. It’s too late to change the current version of the spec, but ideas for a future version are already being recorded in the CSS Working Group GitHub repository.

If you want to start with Grid Layout, there are plenty of resources available on the Internet:

It’s possible to think that now that CSS Grid Layout has shipped, it’s all over. Nothing is further from the truth as there is still a lot of work to do:

  • An important step would be to complete the W3C Test Suite. Igalia has been contributing to it and it’s currently imported into Blink and WebKit, but it doesn’t cover the whole spec yet.
  • There are some missing features in the current implementations. For example, nobody supports subgrids yet, web authors tell us that they would love to have them available. Another example, in Blink and WebKit is that we are still finishing the support for baseline alignment.
  • When bugs and issues appear they will need to be fixed and some might even imply some minor modifications to the spec.
  • Performance optimizations should be done. CSS Grid Layout is a huge spec so the biggest part effort so far has been done in the implementation. Now it’s time to improve performance of different use cases.
  • And as I explained earlier, people are starting to think about new features for a future version of the spec. Progress won’t stop now.

Acknowledgements

First of all, it’s important to highlight once again Bloomberg’s role in the development of CSS Grid Layout. Without their vision and support it probably would not be have shipped so soon.

But this is not an individual effort, but something much bigger. I’ll mention several people next, but I’m sure I’ll forget a lot of them, so please forgive me in advance.

So big thanks to:

  • The Microsoft folks who started the spec.
  • The current spec editors: Elika J. Etemad (fantasai), Rossen Atanassov, and Tab Atkins Jr. Especially fantasai & Tab, who have been dealing with most of the issues we have reported.
  • The whole CSS Working Group for their work on this spec.
  • Our reviewers in both Blink and WebKit: Christian Biesinger, Darin Adler, Julien Chaffraix, and many other.
  • Other implementors: Daniel Holbert, Mats Palmgren, etc.
  • People spreading the word about CSS Grid Layout: Jen Simmons, Rachel Andrew, etc.
  • The many other people I’m missing in this list who helped to make CSS Grid Layout the newest layout module for the Web.

Thanks to you all! 😻 And particularly to Bloomberg for letting Igalia be part of this amazing experience. We’re really happy to have walked this path together and we really hope to do more cool stuff in the future.

Translations

March 15, 2017 11:00 PM

February 27, 2017

Jacobo Aragunde

GENIVI-fying Chromium, part 2

In the previous blog post, we introduced the work to port Chromium to the GENIVI Development Platform (GDP). We have continued working to improve the integration, and make everything easier to build.

In first place, we are now using the latest code from the Ozone-Wayland project that builds on top of Chromium 53 instead of Chromium 48. We have rebased the meta-browser recipes for the newer version and contributed the patch to the upstream project, together with other patches to clean the build process and to fix issues on certain platforms.

Some issues detected in the earlier steps of the integration were addressed. The aspect ratio of the browser window has been modified to fit the GDP demonstration HMI. A performance degradation when playing video had also been detected, the problem was not actually in Chromium, Pulseaudio was taking all the CPU away from the browser processes when using the default null sink. We fixed it by setting Alsa as the default sink with the command pacmd "set-default-sink AlsaPrimary" (do it in /etc/pulse/default.pa to make the change persistent). We are obviously bypassing the GENIVI Audio Manager here, it should be integrated at a later point.

We are in the process to merge our patches into the GENIVI platform, to make the Chromium browser part of the default build. You currently have to use our fork of meta-genivi-dev, while the meta-browser layer has already been added as a submodule and it’s not necessary to explicitly add it.

Finally, we have been testing how Chromium and Ozone-Wayland behave in multi-seat environments using the Wayland IVI Extension and the IVI Layer Manager libraries to have full control of screens, layers, surfaces and focus. We have extracted some conclusions that will allow us to make Chromium behave as expected in this scenario.

Chromium on a multi-seat environment

All the work we have done is publicly available already. You may try it by:

  • Setting up GDP master for your board. Make sure you are using the latest master to get the meta-browser layer automatically.
  • While review is ongoing, you may add our fork as a new remote for the meta-genivi-dev submodule and switch to the chromium-integration branch.
  • Finally, just bitbake your image, the Chromium browser has been made part of the default image in one of the meta-genivi-dev patches.

A warning about platforms: please notice we are currently using a Minnowboard as a test platform. There is a known issue on Raspberry Pi that we hope will be fixed soon. Regarding R-Car Gen. 2 boards, we think it should work, we have ran Chromium there before but not recently.

This work is performed by Igalia and sponsored by GENIVI through the Challenge Grant Program. Thank you!

GENIVI logo

by Jacobo Aragunde Pérez at February 27, 2017 01:16 PM

January 22, 2017

Frédéric Wang

Mus Window System

Update 2017/02/01: The day I published this blog post, the old mus client library was removed. Some stack traces were taken during the analysis Antonio & I made in fall 2016, but they are now obsolete. I’m updating the blog in order to try and clarify things and fix possible inaccuracies.

TL; DR

Igalia has recently been working on making Chromium Desktop run natively on Ozone/Wayland thanks to support from Renesas. This is however still experimental and there is a lot of UI work to do. In order to facilitate discussion at BlinkOn7 and more specifically how browser windows are managed, we started an analysis of the Chromium Window system. An overview is provided in this blog post.

Introduction

Antonio described how we were able to get upstream Chromium running on Linux/Ozone/Wayland last year. However for that purpose the browser windows were really embedded in the “ash” environment (with additional widgets) which was itself drawn in an Ozone/Wayland window. This configuration is obviously not ideal but it at least allowed us to do some initial experiments and to present demos of Chromium running on R-Car M3 at CES 2017. If you are interested you can check our ces-demos-2017 and meta-browser repositories on GitHub. Our next goal is to have all the browser windows handled as native Ozone/Wayland windows.

In a previous blog post, I gave an overview of the architecture of Ozone. In particular, I described classes used to handle Ozone windows for the X11 or Wayland platforms. However, this was only a small part of the picture and to understand things globally one really has to take into account the classes for the Aura window system and Mus window client & server.

Window-related Classes

Class Hierarchy

A large number of C++ classes and types are involved in the chromium window system. The following diagram provides an overview of the class hierarchy. It can merely be divided into four parts:

  • In blue, the native Ozone Windows and their host class in Aura.
  • In red and orange, the Aura Window Tree.
  • In purple, the Mus Window Tree (client-side). Update 2017/02/01: These classes have been removed.
  • In green and brown, the Mus Window Tree (server-side) and its associated factories.

Windowing System

I used the following convention which is more or less based on UML:

  • Rectangles represent classes/interfaces while ellipses represent enums, types, defines etc. You can click them to access the corresponding C++ source file.
  • Inheritance is indicated by a white arrow to the base class from the derived class. For implementation of Mojo interfaces, dashed white arrows are used.
  • Other associations are represented by an arrow with open or diamond head. They mean that the origin of the arrow has a member involving one or more instances of the pointed class, you can hover over the arrow head to see the name of that class member.

Native Ozone Windows (blue)

ui::PlatformWindow is an abstract class representing a single window in the underlying platform windowing system. Examples of implementations include ui::X11WindowOzone or ui::WaylandWindow.

ui::PlatformWindow can be stored in a ui::ws::PlatformDisplayDefault which implements the ui::PlatformWindowDelegate interface too. This in turn allows to use platform windows as ui::ws::Display. ui::ws::Display also has an associated delegate class.

aura::WindowTreeHost is a generic class that hosts an embedded aura:Window root and bridges between the native window and that embedded root window. One can register instance of aura::WindowTreeHostObserver as observers. There are various implementations of aura::WindowTreeHost but we only consider aura::WindowTreeHostPlatform here.

Native ui::PlatformWindow windows are stored in an instance of aura::WindowTreeHostPlatform which also holds the gfx::AcceleratedWidget to paint on. aura::WindowTreeHostPlatform implements the ui::PlatformWindowDelegate so that it can listen events from the underlying ui::PlatformWindow.

aura::WindowTreeHostMus is a derived class of aura::WindowTreeHostPlatform that has additional logic make it usable in mus. One can listen changes from aura::WindowTreeHostMus by implementing the aura::WindowTreeHostMusDelegate interface.

Aura Windows (orange)

aura::Window represents windows in Aura. One can communicate with instances of that class using a aura::WindowDelegate. It is also possible to listen for events by registering a list of aura::WindowObserver.

aura::WindowPort defines an interface to enable aura::Window to be used either with mus via aura::WindowMus or with the classical environment via aura::WindowPortLocal. Here, we only consider the former.

WindowPortMus holds a reference to a aura::WindowTreeClient. All the changes to the former are forwarded to the latter so that we are sure they are propagated to the server. Conversely, changes received by aura::WindowTreeClient are sent back to WindowPortMus. However, aura::WindowTreeClient uses an intermediary aura::WindowMus class for that purpose to avoid that the changes are submitted again to the server.

Aura Window Tree Client (red)

aura::WindowTreeClient is an implementation of the ui::mojom::WindowManager and ui::mojom::WindowTreeClient Mojo interfaces for Aura. As in previous classes, we can associate to it a aura::WindowTreeClientDelegate or register a list of aura::WindowTreeClientObserver.

aura::WindowTreeClient also implements the aura::WindowManagerClient interface and has as an associated aura::WindowManagerDelegate. It has a set of roots aura::WindowPortMus which serve as an intermediary to the actual aura:Window instances.

In order to use an Aura Window Tree Client, you first create it using a Mojo connector, aura::WindowTreeClientDelegate as well as optional aura::WindowManagerDelegate and Mojo interface request for ui::mojom::WindowTreeClient. After that you need to call ConnectViaWindowTreeFactory or ConnectAsWindowManager to connect to the Window server and create the corresponding ui::mojom::WindowTree connection. Obviously, AddObserver can be used to add observers.

Finally, the CreateWindowPortForTopLevel function can be used to request the server to create a new top level window and associate a WindowPortMus to it.

Mus Window Tree Client (purple)

Update 2017/02/01: These classes have been removed.

ui::WindowTreeClient is the equivalent of aura:WindowTreeClient in mus. It implements the ui::mojom::WindowManager and ui::mojom::WindowTreeClient Mojo interfaces. It derives from ui::WindowManagerClient, has a list of ui::WindowTreeClientObserver and is associated to ui::WindowManagerDelegate and ui::WindowTreeClientDelegate.

Regarding windows, they are simpler than in Aura since we only have one class ui::Window class. In a similar way as Aura, we can register ui::WindowObserver. We can also add ui::Window as root windows or embedded windows of ui::WindowTreeClient.

In order to use a Mus Window Tree Client, you first create it using a ui::WindowTreeClientDelegate as well as optional ui::WindowManagerDelegate and Mojo interface request for ui::mojom::WindowTreeClient. After that you need to call ConnectViaWindowTreeFactory or ConnectAsWindowManager to connect to the Window server and create the corresponding ui::mojom::WindowTree connection. Obviously, AddObserver can be used to add observers.

Finally, the NewTopLevelWindow and NewWindow functions can be used to create new windows. This will cause the corresponding functions to be called on the connected ui::mojom::WindowTree.

Mus Window Tree Server (green and brown)

We just saw the Aura and Mus window tree clients. The ui::ws::WindowTree Mojo interface is used to for the window tree server and is implemented in ui::ws::WindowTree. In order to create window trees, we can use either the ui::ws::WindowManagerWindowTreeFactory or the ui::ws::WindowTreeFactory which are available through the corresponding ui::mojom::WindowManagerWindowTreeFactory and ui::mojom::WindowTreeFactory Mojo interfaces.

ui::ws::WindowTreeHostFactory implements the ui::ws::WindowTreeHostFactory Mojo interface. It allows to create ui::mojom::WindowTreeHost, more precisely ui::ws::Display implementing that interface. Under the hood, ui::ws::Display created that way actually have an associated ws::DisplayBinding creating a ui::ws::WindowTree. Of course, the display also has a native window associated to it.

Mojo Window Tree APIs (pink)

Update 2017/02/01: The Mus client has been removed. This section only applies to the Aura client.

As we have just seen in previous sections the Aura and Mus window systems are very similar and in particular implement the same Mojo ui::mojom::WindowManager and ui::mojom::WindowTreeClient interfaces. In particular:

  • The ui::mojom::WindowManager::WmCreateTopLevelWindow function can be used to create a new top level window. This results in a new windows (aura::Window or ui::Window) being added to the set of embedded windows.

  • The ui::mojom::WindowManager::WmNewDisplayAdded function is invoked when a new display is added. This results in a new window being added to the set of window roots (aura::WindowMus or ui::Window).

  • The ui::mojom::WindowTreeClient::OnEmbed function is invoked when Embed is called on the connected ui::mojom::WindowTree. The window parameter will be set as the window root (aura:WindowMus or ui:Window). Note that we assume that the set of roots is empty when such an embedding happens.

Note that for Aura Window Tree Client, the creation of new aura::WindowMus window roots implies the creation of the associated aura::WindowTreeHostMus and aura::WindowPortMus. The creation of the new aura:Window window by aura::WmCreateTopLevelWindow is left to the corresponding implementation in aura::WindowManagerDelegate.

On the server side, the ui::ws::WindowTree implements the ui::mojom::WindowTree mojo interface. In particular:

  • The ui::mojom::WindowTree::Embed function can be used to embed a WindowTreeClient at a given window. This will result of OnEmbed being called on the window tree client.

  • The ui::mojom::WindowTree::NewWindow function can be used to create a new window. It will call OnChangeCompleted on the window tree client.

  • The ui::mojom::WindowTree::NewTopLevelWindow function can be used to request the window manager to create a new top level window. It will call OnTopLevelCreated (or OnChangeCompleted in case of failure) on the window tree client.

Analysis of Window Creation

Chrome/Mash

In our project, we are interested in how Chrome/Mash windows are created. When the chrome browser process is launched, it takes the regular content/browser startup path. That means in chrome/app/chrome_main.cc it does not take the ::MainMash path, but instead content::ContentMain. This is the call stack of Chrome window creation within the mash shell:

#1 0x7f7104e9fd02 ui::WindowTreeClient::NewTopLevelWindow()
#2 0x5647d0ed9067 BrowserFrameMus::BrowserFrameMus()
#3 0x5647d09c4a47 NativeBrowserFrameFactory::Create()
#4 0x5647d096bbc0 BrowserFrame::InitBrowserFrame()
#5 0x5647d0877b8a BrowserWindow::CreateBrowserWindow()
#6 0x5647d07d5a48 Browser::Browser()
...

Update 2017/02/01: This has changed since the time when the stack trace was taken. The BrowserFrameMus constructor now creates a views:DesktopNativeWidgetAura and thus an aura::Window.

The outtermost window created when one executes chrome --mash happens as follows. When the UI service starts (see Service::OnStart in services/ui/service.cc), an instance of WindowServer is created. This creations triggers the creation of a GpuServiceProxy instance. See related snippets below:

void Service::OnStart() {
  (...)
  // Gpu must be running before the PlatformScreen can be initialized.
  window_server_.reset(new ws::WindowServer(this));
  (..)
}

WindowServer::WindowServer(WindowServerDelegate* delegate)
: delegate_(delegate),
  (..)
  gpu_proxy_(new GpuServiceProxy(this)),
  (..)
{ }

GpuServiceProxy, then, starts off the GPU service initialization. By the time the GPU connection is established, the following callback is called: GpuServiceProxy::OnInternalGpuChannelEstablished. This calls back to WindowServer::OnGpuChannelEstablished, which calls Service::StartDisplayInit. The later schedules a call to PlatformScreenStub::FixedSizeScreenConfiguration. This finally triggers the creation of an Ozone top level window via an ui::ws::Display:

#0 base::debug::StackTrace::StackTrace()
#1 ui::(anonymous namespace)::OzonePlatformX11::CreatePlatformWindow()
#2 ui::ws::PlatformDisplayDefault::Init()
#3 ui::ws::Display::Init()
#4 ui::ws::DisplayManager::OnDisplayAdded()
#5 ui::ws::PlatformScreenStub::FixedSizeScreenConfiguration()
(..)

On the client-side, the addition of a new display will cause aura::WindowTreeClient::WmNewDisplayAdded to be called and will eventually lead to the creation of an aura::WindowTreeHostMus with the corresponding display id. As shown on the graph, this class derives from aura::WindowTreeHost and hence instantiates an aura::Window.

Mus demo

The Chromium source code contains a small mus demo that is also useful do experiments. The demo is implemented via a class with the following inheritance:

class MusDemo : public service_manager::Service,
                public aura::WindowTreeClientDelegate,
                public aura::WindowManagerDelegate

i.e. it can be started as Mus service and handles some events from aura:WindowTreeClient and aura::WindowManager.

When the demo service is launched, it creates a new Aura environment and an aura::WindowTreeClient, it does the Mojo request to create an ui::WindowTree and then performs the connection:

#0 aura::WindowTreeClient::ConnectAsWindowManager()
#1 ui::demo::MusDemo::OnStart()
#2 service_manager::ServiceContext::OnStart()

Similarly to Chrome/Mash, a new display and its associated native window is created by the UI:

#0 ui::ws::WindowTree::AddRootForWindowManager()
#1 ui::ws::Display::CreateWindowManagerDisplayRootFromFactory()
#2 ui::ws::Display::InitWindowManagerDisplayRoots()
#3 ui::ws::PlatformDisplayDefault::OnAcceleratedWidgetAvailable()
#4 ui::X11WindowBase::Create()
#5 ui::(anonymous namespace)::OzonePlatformX11::CreatePlatformWindow()
#6 ui::ws::PlatformDisplayDefault::Init()
#7 ui::ws::Display::Init()
#8 ui::ws::DisplayManager::OnDisplayAdded()

The Aura Window Tree Client listens the changes and eventually aura::WindowTreeClient::WmNewDisplayAdded is called. It then informs its MusDemo delegate so that the display is added to the screen display list

#0 DisplayList::AddDisplay
#1 ui::demo::MusDemo::OnWmWillCreateDisplay
#2 aura::WindowTreeClient::WmNewDisplayAddedImpl
#3 aura::WindowTreeClient::WmNewDisplayAdded

…and the animated bitmap window is added to the Window Tree:

#0  ui::demo::MusDemo::OnWmNewDisplay
#1  aura::WindowTreeClient::WmNewDisplayAddedImpl
#2  aura::WindowTreeClient::WmNewDisplayAdded

Update 2017/02/01: Again, aura::WindowTreeClient::WmNewDisplayAdded will lead to the creation of an aura Window.

Conclusion

Currently, both Chrome/Mash or Mus demo create a ui::ws::Display containing a native Ozone window. The Mus demo class uses the Aura WindowTreeClient to track the creation of that display and pass it to the Mus Demo class. The actual chrome browser window is created inside the native Mash window using a Mus WindowTreeClient. Again, this is not what we want since each chrome browser should have its own native window. It will be interesting to first experiment multiple native windows with the Mus demo.

Update 2017/02/01: aura::WindowTreeClient is now always used to create Aura Windows for both external windows (corresponding to a display & a native window) and internal windows. However, we still want all chrome browser to be external windows.

Igalia Logo
Renesas Logo

It seems that the Ozone/Mash work has been mostly done with ChromeOS in mind and will probably need some adjustments to make things work on desktop Linux. We are very willing to discuss this and other steps for Desktop Chrome Wayland/Ozone in details with Google engineers. Antonio will attend BlinkOn7 next week and will be very happy to talk with you so do not hesitate to get in touch!

January 22, 2017 11:00 PM

January 11, 2017

Jacobo Aragunde

GENIVI-fying Chromium

In the last weeks, I’ve been working to integrate Chromium in the GENIVI Development Platform (GDP).

GENIVI provides a platform tailored for the needs of the In-Vehicle Infotainment (IVI) industry. It’s interesting to highlight their early adoption of Wayland for the graphic stack and the development of the Wayland IVI extension to fulfil the specific needs of IVI window manager implementations.

In GDP application model, apps are under control of systemd, which takes care of starting and stopping them. Through the ivi-application protocol, applications register their surfaces to be managed by HMI central controller. This HMI controller will be in charge of manipulating the surfaces belonging to applications for presentation to the user, using the ivi-controller protocol. In the end, the Wayland compositor will compose the surfaces on screen.

The first step was to build Chromium for the target platform. GDP can be built with Yocto, and the meta-browser layer provides a set of recipes to build Chromium, among other browsers. Support for Chromium on Wayland is granted by the Ozone-Wayland project, developed mainly by Intel. We had already used this combination of software to run Chromium on embedded platforms, and made contributions to it.

To achieve the integration with the GDP application model, we need to put some files in place so the browser can be controlled by systemd and the HMI controller has some knowledge about its existence. We extend the chromium-wayland recipe with a .bbappend file added to the GDP recipes. With everything in place, and one additional dependency from meta-openembedded, we are able to add Chromium to a GDP image and build.

Chromium on GDP

If you want to reproduce the build yourself before everything is integrated, you can already do it:

  • Get the GENIVI development platform and follow instructions to set GDP master up for your board.
  • Get the meta-browser layer and add it to your conf/bblayers.conf. I currently recommend to use the branch ease-chromium-wayland-build from this fork, as it contains some cleanup patches that haven’t been integrated yet. EDIT: patches have been merged into upstream meta-browser, no need to use the fork now!
  • You should already have the meta-openembedded submodule, so add meta-openembedded/meta-gnome to your conf/bblayers.conf.
  • Get the integration patch and add it into the meta-genivi-dev submodule. You may add this fork as a new remote and change to the chromium-integration branch, or you could just wget the patch and apply it locally. EDIT: the patch has been amended several times, links were updated.
  • Add chromium-wayland to your IMAGE_INSTALL_append in conf/local.conf. Now you may bitbake your image.

Next steps include integrating my patches into mainline development of their respective projects, rebasing meta-browser to use the latest possible version of Chromium, trying more platforms (currently working on a Minnowboard) and general fine-tuning by fixing issues like the weird proportions of the browser window when running on GDP.

This work is performed by Igalia and sponsored by GENIVI through the Challenge Grant Program. Thank you!

GENIVI logo

by Jacobo Aragunde Pérez at January 11, 2017 06:00 PM

January 08, 2017

Manuel Rego

Coloring the insertion caret

On the last weeks Igalia has been working in adding support for caret-color property on Blink. This post is a summary of the different tasks done to achieve it.

First steps

Basically I started investigating a little bit the state of art. caret-color is defined in the spec called CSS Basic User Interface Module Level 3, it’s a Candidate Recommendation so browsers should be happy to implement it. However the property is marked as at-risk due to the lack of implementations (I talked to the spec editor, Florian Rioval, to confirm it).

Update: caret-color is no longer at-risk thanks to Chromium and Firefox implementations.

Then the first thing was to send the Intent to Implement and Ship: CSS UI: caret-color property mail to blink-dev. The feedback was possitive as it’s a small change without a big impact, and the intent was approved.

Initial support

My colleague Claudio Saavedra had already implemented caret-color support for Bloomberg in their downstream port a few years ago. And they have been using it successfully on the terminals. In addition, as you can see in this mail by Lea Verou on the CSS Working Group (CSS WG) mailing list, there’s a clear author demand for more control over the caret color.

Basically the task was adding a new CSS property to the Blink parser and change the color of the insertion caret to use it. The latter was basically changing a line and using caret-color instead of color to determine it.

Adding the CSS property was not hard, but there’s something special regarding caret-color as it’s the first color property that accepts auto as value. So far auto is going to be implemented as currentColor, but in the future it can be tweaked to “ensure good visibility and contrast with the surrounding content”. For that reason the patch needed some extra work on top of a regular color.

caret-color example caret-color example

Making caret-color animatable

The next step was making caret-color animatable. Again this would be fairly easy if it was a regular color, but due to the auto value it needed some special changes.

The important thing here is that auto is not interpolable, so if you do something like this:

  .foo {
    color: initial;
    caret-color: auto;
    transition: all 1s;
  }
  .foo:hover {
    color: green;
    caret-color: lime;
  }

The color of the text will interpolate from black to green, but the color of the insertion caret will do a discrete jump from black to lime. This might be seen as a weird behavior, but it was discussed and verified with the CSS WG.

Anyway the patch has landed and you can now enjoy your rainbow caret! 🌈

caret-color animation example

The resolved value

Another thing that was clarified with the CSS WG is related to the resolved value of caret-color property.

In CSS you can have specified value, computed value, used value and resolved value. This is not the post to explain on this, so I’ll jump directly into the details of what was related to caret-color implementation.

For color properties we’re used to have as resolved value (the one returned by getComputedStyle()) the used value, a numeric color with a format like rgb(X, X, X). For example, in the following snippet you would get as resolved value rgb(0, 255, 0) in the console log:

  <div id="test" style="color: lime; background-color: currentColor;"></div>
  <script>
    console.log(window.getComputedStyle(document.getElementById("test")).backgroundColor);
  </script>

However, that was not in the specs, and initially caret-color tests were checking that the resolved value was auto or currentColor. This has been modified and now it’ll behave like the rest of the color properties.

W3C Test Suite

Of course we need tests for all this stuff, but Florian had already created a few tests related to caret-color on the csswg-test repository. So I used them as base and contributed a few more to check all the stuff needed regarding the implementation.

The good news is that now there are 21 tests checking caret-color that are upstream on the W3C repository and can be used by the rest of browsers to verify the interoperability.

This test suite is being used in Blink to verify that the current implementation is spec compatible. Right now only 1 test is failing due to a known bug regarding animations.

Conclusions

caret-color support is already available on Chrome Canary, and it’ll be hitting stable in Chrome 57. Please start playing with it and let me know if you find any issue.

The good news is that thanks to all the discussions inside the CSS WG, Firefox implementation got reactivated and caret-color is supported there now too! It’ll be included in Firefox 53. Also Mozilla folks have wrote the documentation at MDN.

Regarding other browsers, in WebKit the bug has been reported and Blink patches could be somehow ported; in Edge I added a new feature request vote for it if you’re interested.

Acknowledgements

First I’d like to thank Bloomberg for sponsoring, once again, Igalia to do this work. It’s really nice to keep adding valuable features to the web.

This is the kind of things where Igalia can be the perfect partner for your company. Some features that might be interesting for your organization but are not in the roadmap or priorities of the browser vendors. We can help to discuss the feature with the standards body and push to get it implemented on the open source browsers. Of course, not everything will be accepted upstream, but in some situations (like the caret-color property), it’s possible to make it for real.

If you’d like to do this kind of work in Igalia, don’t miss the opportunity to join us. We’ve recently opened a position for a Chromium developer, take a look to it and send us your application if you’re interested.

Igalia and Bloomberg working together to build a better web Igalia and Bloomberg working together to build a better web

Also thanks to Florian Rioval for replying so fast to all my questions and doubts regarding caret-color and the spec. He was very kind quickly reviewing all my tests for the W3C csswg-test repo.

Finally thanks to the reviewers (specially Alan Cutter and Timothy Loh) and other people commenting on the different issues for all your patience with me. 😄

January 08, 2017 11:00 PM

December 21, 2016

Frédéric Wang

¡Igalia is hiring!

If you read this blog, you probably know that I joined Igalia early this year, where I have been involved in projects related to free software and web engines. You may however not be aware that Igalia has a flat & cooperative structure where all decisions (projects, events, recruitments, company agreements etc) are voted by members of an assembly. In my opinion such an organization allows to take better decisions and to avoid frustrations, compared to more traditional hierarchical organizations.

After several months as a staff, I finally applied to become an assembly member and my application was approved in November! Hence I attended my first assembly last week where I got access to all the internal information and was also able to vote… In particular, we approved the opening of two new job positions. If you are interested in state-of-the-art free software projects and if you are willing to join a company with great human values, you should definitely consider applying!

December 21, 2016 11:00 PM

December 02, 2016

Frédéric Wang

Chromium on R-Car M3 & AGL/Wayland

As my fellow igalian Antonio Gomes explained on his blog, we have recenly been working on making the master branch of Chromium run on Linux Desktop using the upstream Ozone/Wayland backend. This effort is supported by Renesas and they were interested to rely on these recent developments to showcase Chromium running on the latest generation of their R-Car systems-on-chip for automotive applications. Ideally, they were willing to see this happening for the Automotive Grade Linux distribution.

Igalia Logo
Renesas Logo

Luckily, support for R-Car M3 was already available in the development branch of AGL and the AGL instructions for R-Car M2 actually worked pretty well for M3 too mutatis mutandis. There is also an OpenEmbedded/Yocto BSP layer for Chromium but unfortunately Wayland is only supported up to m48 (using the Ozone backend from Intel’s fork) and X11 is only supported up to m52. Hence we created a (for-now-private) fork of meta-browser that:

  • Uses the latest development version of Chromium, in particular the Linux/Ozone/Mash/Wayland support Igalia has been working on recently.
  • Relies on the new GN build system rather than the deprecated GYP one.
  • Supports the ARM64 architecture instead of just ARM32.
  • Installs more resources such as Mojo service manifests.
  • Applies more patches (e.g. build fixes or the workaround for issue 2485673002).

Renesas also provided us some R-Car M3 boards. I received my package this week and hence was able to start playing with it on Wednesday. Again, the AGL instructions for R-Car M2 apply well to M3 and the elinux page is very helpful to understand the various parts of the board. After having started AGL on the board and opened a Weston terminal (using mouse & keyboard as on the video or using ssh) I was able to run chromium via the following command:

/usr/bin/chromium/chrome --mash --ozone-plaform=wayland \
                         --user-data-dir=/tmp/user-data-dir \
                         --no-sandbox

The first line is the usual command currently used to execute Ozone/Mash/Wayland. The second line works around the fact that the AGL demo is running as root. The third line disables sandbox because the deprecated setuid sandbox does not work with Ozone and the newer user namespaces sandbox is not supported by the AGL kernel.

The following video a gives an overview of the hardware preparation as well as some basic tests with bouncyballs.org and webengineshackfest.org:

You can see that chromium runs relatively smoothly but we will do more testing to confirm these initial experiments. Also, we find the general issues with Linux/Ozone/Mash (internal VS external windows, no fullscreen, keyboard restricted to US layout, unwanted ChromeOS widgets etc) but we expect to continue to collaborate with Google to fix these bugs!

December 02, 2016 11:00 PM