Servo
A browser engine for the 21st century
Soledad Penadés
soledadpenades.com
@supersole
Servo
the parallel browser engine
designed for both applications and embedded use
(demo: Servo in action)
Why?
Why making a new browser? Aren't there enough?
New needs have arisen
users want safe performant apps running on their portable devices efficiently
developers want to embed part of, or entire browser engines on their apps
they would also like to not worry about C++ memory management or data races
Most modern browsers:
designed pre year 2000
for desktop computers
written in C++
Need to develop browser that...
supports new types of applications and devices
takes advantage of all hardware in a machine
and is secure and modular
Servo is an answer
to these issues
Tackling one problem
at a time
- Solid foundations: Rust
- Maximising usage of hardware via parallelisation
- Embeddable by design
Problem 1: building a solid foundation
Users' demands vs
programmer cost
- High interactivity (requires multithreading) (difficult to write in C++)
- To be able to trust their browser with their data (requires safe code) (safe C++ code is hard)
- Existing browsers = millions of lines of C/C++
- ~50% of Gecko critical bugs = consequence of using C++
=== C++ is a liability
Servo addresses those issues by using Rust, a new language which is memory safe by design
Typical C/C++ bugs:
- dangling pointers
- data races
- integer overflows
- buffer overflows
- iterator invalidations
^ all solved either by compile or run-time checks
Developers can focus on writing a great browser engine, not fighting with memory allocations
Rust also makes implementing parallelism foolproof
- Easy to partition vectors
- Lending references across threads
- Improved concurrency by reducing simultaneous access to data structures, and using message passing between components
Rust aims to be as fast (or faster) than C++, and safer than C++
"faster", as in faster software and faster developers
- fast by default = no need for (clever|maybe buggy) optimisations
- less time debugging C++ style errors = more time developing
- interoperable with C = use existing libraries to get started
(e.g. Servo uses Firefox's Spidermonkey JS engine) - has a package manager, Cargo = dependencies are versioned, reproducibility, etc
Problem 2: maximising usage of hardware
(to render websites)
But first... how does a browser render a website?
Note: this is going to be a (hopefully not too)
gross simplification
HTML
<body>
<div>
<p>Paragraph</p>
<p>
Paragraph 2
<span>(span)</span>
</p>
</div>
</body>
CSS
body { font-size: 100px; }
div { min-width: 10px; }
p { color: red; }
span { size: 50%; }
HTML parsing, DOM tree building
Style calculation per node, 1
Style calculation per node, 2
body { font-size: 100px; }
Style calculation per node, 3
p { color: red; }
Style calculation per node, 4
span { size: 50%; }
Flow construction
fragments: leaves
flows: containers, or formatting contexts
Flow construction, 2
fragments: leaves
flows: containers, or formatting contexts
Bubble inline size
Computes minimum inline width (size) per element
Assign inline size
(depends on parent size)
Assign block size
Finds flows height based on fragments' heights
Display list construction
Computes final position for everything...
and then it's off to the renderer!
Traditionally, this process has been very linear
Linear, in terms of time
Linear:
acceptable in the 90s 🎶
Linear:
unnacceptable in mobile
Parallelising is key in mobile platforms
- Slower processors, but many cores
- 4+ cores working at slower frequency = same performance as 1 core at highest frequency... and at just 40% of energy usage!
Parallelising can enable more complicated pages in all platforms
Servo does layout in parallel
Layout parallelism in Servo is implemented with a work stealing algorithm
- threads have a queue of works to complete
- if a thread needs more work it can take tasks from other queues
More optimisations: incremental layout
tries to minimise calculations where possible
- damage flags on flows and fragments
- list of what kinds of damage each CSS property causes
- e.g. colour change doesn't affect position or sizes
So far we've only described how Servo builds layout, but not how it renders it
Web Render
An OpenGL based renderer for CSS content
Making the paint step super fast
Why a new renderer?
Why not taking an existing one, e.g. Skia?
- They're general purpose renderers
- Designed for CPUs, not GPUs
- Web Render focuses on the CSS problem only
- Developers focus on declaring layout, not on browser implementation details
Web Render in a nutshell
- Works with display lists
- Draws into an OpenGL context
- Requires OpenGL ES 2.1 or OpenGL 3
- Retained mode (lots of optimisations possible)
- It's like a graphics game engine: very low level, and very fast
How it (roughly) works
1) Process display list
Text @ Rect(89px, 89px) at (8px, 23px)
SolidColor rgba(0, 0, 0, 0) Rect(28px, 72px) at (15px, 30px)
BoxShadow @ Rect(28px, 72px) at (16px, 31px)
2) Prepare resources
- glyphs - rendered on CPU (for now), uploaded as textures
- upload images - as textures
- paths, shadows - rendered with special shaders
^ resources retained from frame to frame
3) And draw!
Goodbye to...
- transformZ(0) to give elements their own accelerated layer
- transform: translate(...) instead of using top and left
- Painting as the bottleneck
- Jank!
Hello to...
- hundreds of frames per second
- using the GPU effectively
- less energy consumption to draw things on screen
- maybe using Web Render in your own app! (if you can describe your graphics using CSS)
(Web Render demos)
Problem 3: embedding
Servo is designed to be embedded
And you can take as many parts of Servo as you like:
a few components... or the entire browser!
Servo is modular
- Takes advantage of Rust's Cargo package manager ("like npm")
- Multirepo, decoupled
- Consumes packages from the ecosystem
- Contributes packages back to it
- Easier to pick up and also easier to replace parts
Servo is designed to be embedded
- Well defined, stable and well tested API
- Exposes a C interface
- Great to build mobile UIs, TV interfaces...
- Opens the door to new types of applications
What about the ✨future✨?
When can we use Servo as our main browser?
- Never (because it's just an engine)
- Today, via Oxidation
Oxidation
Integrating Rust code into Firefox
No need to wait until Servo is feature complete
- MP4 metadata parser (live since August!)
- URL parser
- CSS style calculation
- WebM demuxer
- ...
Community
- Really high standards - inherited from Rust
- Code of conduct
- In GitHub - where developers are
- Labelling bugs by difficulty (newcomers know what to pick)
- Having good bug descriptions
- Quick triaging and feedback
- Lots of bots automating stuff
- Weekly blog post (engaging contributors, recognising their work)
- Nice people!
Recap
1. Tackling one problem at a time
- Rust: Solid foundations
- Better use of hardware: parallelism, GPU
- Embedding