Update in-tree docs to point to the new book (#32743)

* Update in-tree docs to point to the new book

* Revive build setup section in README as quickstart guide

* Apply feedback about titles
This commit is contained in:
Delan Azabani 2024-07-09 23:42:00 +08:00 committed by GitHub
parent 72e6a1f007
commit 34d9be70f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 63 additions and 1413 deletions

View file

@ -1,92 +1,5 @@
# Contributing to Servo
Servo welcomes contribution from everyone. Here are the guidelines if you are
thinking of helping us:
## Contributions
Contributions to Servo or its dependencies should be made in the form of GitHub
pull requests. Each pull request will be reviewed by a core contributor
(someone with permission to land patches) and either landed in the main tree or
given feedback for changes that would be required. All contributions should
follow this format, even those from core contributors.
Should you wish to work on an issue, please claim it first by commenting on
the GitHub issue that you want to work on it. This is to prevent duplicated
efforts from contributors on the same issue.
Head over to [Servo Starters](https://starters.servo.org/) to find
good tasks to start with. If you come across words or jargon that do not make
sense, please check [the glossary](docs/glossary.md) first. If there's no
matching entry, please make a pull request to add one with the content `TODO`
so we can correct that!
See [`HACKING_QUICKSTART.md`](docs/HACKING_QUICKSTART.md) for more information
on how to start working on Servo.
## Pull request checklist
- Branch from the main branch and, if needed, rebase to the current main branch
before submitting your pull request. If it doesn't merge cleanly with main
you may be asked to rebase your changes.
- Commits should be as small as possible, while ensuring that each commit is
correct independently (i.e., each commit should compile and pass tests).
- Commits should be accompanied by a Developer Certificate of Origin
(http://developercertificate.org) sign-off, which indicates that you (and
your employer if applicable) agree to be bound by the terms of the
[project license](LICENSE). In git, this is the `-s` option to `git commit`.
- If your patch is not getting reviewed or you need a specific person to review
it, you can @-reply a reviewer asking for a review in the pull request or a
comment, or you can ask for a review in [the Servo chat](https://servo.zulipchat.com/).
- Add tests relevant to the fixed bug or new feature. For a DOM change this
will usually be a web platform test; for layout, a reftest. See our [testing
guide](https://github.com/servo/servo/wiki/Testing) for more information.
For specific git instructions, see [GitHub workflow 101](https://github.com/servo/servo/wiki/Github-workflow).
## Running tests in pull requests
When you push to a pull request, GitHub automatically checks that your changes have no compilation, lint, or tidy errors.
To run unit tests or Web Platform Tests against a pull request, add one or more of the labels below to your pull request. If you do not have permission to add labels to your pull request, add a comment on your bug requesting that they be added.
| Label | Effect |
|---|---|
| `T-full` | Unit tests: Linux, macOS, Windows<br>Layout tests: Linux, macOS<br>Legacy layout tests: Linux, macOS |
| `T-linux-wpt-2013` | Unit tests: Linux<br>Legacy layout tests: Linux |
| `T-linux-wpt-2020` | Unit tests: Linux<br>Layout tests: Linux |
| `T-macos` | Unit tests: macOS |
| `T-windows` | Unit tests: Windows |
## AI contributions
Contributions must not include content generated by large language models or other probabilistic tools, including but not limited to Copilot or ChatGPT. This policy covers code, documentation, pull requests, issues, comments, and any other contributions to the Servo project.
For now, were taking a cautious approach to these tools due to their effects — both unknown and observed — on project health and maintenance burden. This field is evolving quickly, so we are open to revising this policy at a later date, given proposals for particular tools that mitigate these effects. Our rationale is as follows:
**Maintainer burden:** Reviewers depend on contributors to write and test their code before submitting it. We have found that these tools make it easy to generate large amounts of plausible-looking code that the contributor does not understand, is often untested, and does not function properly. This is a drain on the (already limited) time and energy of our reviewers.
**Correctness and security:** Even when code generated by AI tools does seem to function, there is no guarantee that it is correct, and no indication of what security implications it may have. A web browser engine is built to run in hostile execution environments, so all code must take into account potential security issues. Contributors play a large role in considering these issues when creating contributions, something that we cannot trust an AI tool to do.
**Copyright issues:** Publicly available models are trained on copyrighted content, both accidentally and intentionally, and their output often includes that content verbatim. Since the legality of this is uncertain, these contributions may violate the licenses of copyrighted works.
**Ethical issues:** AI tools require an unreasonable amount of energy and water to build and operate, their models are built with heavily exploited workers in unacceptable working conditions, and they are being used to undermine labor and justify layoffs. These are harms that we do not want to perpetuate, even if only indirectly.
## Conduct
Servo Code of Conduct is published at <https://servo.org/coc/>.
## Communication
Servo contributors frequent the [Servo Zulip chat](https://servo.zulipchat.com/).
## Technical Steering Committee
Technical oversight of the Servo Project is provided by the
[Technical Steering Committee](https://github.com/servo/project/blob/main/governance/tsc/README.md).
Moved to the Servo book:
- [Contributing to Servo](https://book.servo.org/contributing.html)

209
README.md
View file

@ -4,75 +4,44 @@ Servo is a prototype web browser engine written in the
[Rust](https://github.com/rust-lang/rust) language. It is currently developed on
64-bit macOS, 64-bit Linux, 64-bit Windows, and Android.
Servo welcomes contribution from everyone. See
[`CONTRIBUTING.md`](CONTRIBUTING.md) and [`HACKING_QUICKSTART.md`](docs/HACKING_QUICKSTART.md)
for help getting started.
Servo welcomes contribution from everyone. Check out [The Servo Book](https://book.servo.org) to get started, or go to [servo.org](https://servo.org/) for news and guides.
Visit the [Servo Project page](https://servo.org/) for news and guides.
## Getting started
## Getting Servo
``` sh
git clone https://github.com/servo/servo
cd servo
```
- Your CARGO_HOME needs to point to (or be in) the same drive as your
Servo repository ([#28530](https://github.com/servo/servo/issues/28530)).
- The Servo repository is big! If you have an unreliable network connection, consider
[making a shallow clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/).
## Build Setup
* [macOS](#macos)
* [Linux](#Linux)
* [Windows](#windows)
* [Android](https://github.com/servo/servo/wiki/Building-for-Android)
If these instructions fail or you would like to install dependencies
manually, try the [manual build setup][manual-build].
For more detailed build instructions, see the Servo book under [Setting up your environment](https://book.servo.org/hacking/setting-up-your-environment.html), [Building Servo](https://book.servo.org/hacking/building-servo.html), and [Building for Android](https://book.servo.org/hacking/building-for-android.html).
### macOS
- Ensure that the version showed by `python --version` is >= 3.10:
- Install [Xcode](https://developer.apple.com/xcode/)
- Install [Homebrew](https://brew.sh/)
- Run `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`. Ensure that `rust`
and `cargo` are available commands &mdash; you may need to restart your shell.
- Run `./mach bootstrap`<br/>
*Note: This will install the recommended version of GStreamer globally on your system.*
- Download and install [`python`](https://www.python.org/downloads/macos/), [Xcode](https://developer.apple.com/xcode/), and [`brew`](https://brew.sh/)
- Install `rustup`: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
- Restart your shell to make sure `cargo` is available
- Install the other dependencies: `./mach bootstrap`
- Build servoshell: `./mach build`
### Linux
- Run `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`. Ensure that `rust`
and `cargo` are available commands &mdash; you may need to restart your shell.
- Install Python (version >= 3.10):
- **Debian-like:** Run `sudo apt install python3-pip python3-venv`
- **Fedora:** Run `sudo dnf install python3 python3-pip python3-devel`
- **Arch:** Run `sudo pacman -S --needed python python-pip`
- **Gentoo:** Run `sudo emerge dev-python/pip`
- Run `./mach bootstrap`
- Install `curl` and `python`:
- Arch: `sudo pacman -S --needed curl python python-pip`
- Debian, Ubuntu: `sudo apt install curl python3-pip python3-venv`
- Fedora: `sudo dnf install curl python3 python3-pip python3-devel`
- Gentoo: `sudo emerge net-misc/curl dev-python/pip`
- Install `rustup`: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
- Restart your shell to make sure `cargo` is available
- Install the other dependencies: `./mach bootstrap`
- Build servoshell: `./mach build`
### Windows
- Download and run [`rustup-init.exe`](https://win.rustup.rs/)
- Make sure to select *Quick install via the Visual Studio Community
installer* or otherwise install Visual Studio 2022.
- In the *Visual Studio Installer* ensure the following components are installed for Visual Studio 2022:
- **Windows 10 SDK (10.0.19041.0)** (`Microsoft.VisualStudio.Component.Windows10SDK.19041`)
- **MSVC v143 - VS 2022 C++ x64/x86 build tools (Latest)** (`Microsoft.VisualStudio.Component.VC.Tools.x86.x64`)
- **C++ ATL for latest v143 build tools (x86 & x64)** (`Microsoft.VisualStudio.Component.VC.ATL`)
- **C++ MFC for latest v143 build tools (x86 & x64)** (`Microsoft.VisualStudio.Component.VC.ATLMFC`)
- Install [chocolatey](https://chocolatey.org/)
- Install [Python 3.11](https://www.python.org/downloads/windows/)
- Run `mach bootstrap`
+ *This will install CMake, Git, and Ninja via choco in an
Administrator console. Allow the scripts to run and once
the operation finishes, close the new console.*
- Run `refreshenv`
See also [Windows Troubleshooting Tips][windows-tips].
- Download and install [`python`](https://www.python.org/downloads/windows/), [`choco`](https://chocolatey.org/install#individual), and [`rustup`](https://win.rustup.rs/)
- Be sure to select *Quick install via the Visual Studio Community installer*
- In the Visual Studio Installer, ensure the following components are installed:
- **Windows 10 SDK (10.0.19041.0)** (`Microsoft.VisualStudio.Component.Windows10SDK.19041`)
- **MSVC v143 - VS 2022 C++ x64/x86 build tools (Latest)** (`Microsoft.VisualStudio.Component.VC.Tools.x86.x64`)
- **C++ ATL for latest v143 build tools (x86 & x64)** (`Microsoft.VisualStudio.Component.VC.ATL`)
- **C++ MFC for latest v143 build tools (x86 & x64)** (`Microsoft.VisualStudio.Component.VC.ATLMFC`)
- Restart your shell to make sure `cargo` is available
- Install the other dependencies: `.\mach bootstrap`
- Build servoshell: `.\mach build`
### Android
@ -94,126 +63,4 @@ See also [Windows Troubleshooting Tips][windows-tips].
"platforms;android-33" \
"system-images;android-33;google_apis;x86_64"
```
For information about building and running the Android build, see
the [Android documentation][android-docs].
## Building
Servo is built with [Cargo](https://crates.io/), the Rust package manager.
We also use Mozilla's Mach tools to orchestrate the build and other tasks.
You can call Mach like this:
On Unix systems:
```
./mach [command] [arguments]
```
On Windows Commandline:
```
mach.bat [command] [arguments]
```
The examples below will use Unix, but the same applies to Windows.
### The Rust compiler
Servo's build system uses rustup.rs to automatically download a Rust compiler.
This is a specific version of Rust Nightly determined by the
[`rust-toolchain.toml`](https://github.com/servo/servo/blob/main/rust-toolchain.toml) file.
### Normal build
To build Servo in development mode.
This is useful for development, but the resulting binary is very slow:
``` sh
./mach build --dev
./mach run tests/html/about-mozilla.html
```
### Release build
For benchmarking, performance testing, or real-world use.
Add the `--release` flag to create an optimized build:
``` sh
./mach build --release
./mach run --release tests/html/about-mozilla.html
```
### Android build
For an armv7 Android build run the following command.
```shell
./mach build --android
```
### Checking for build errors, without building
If youre making changes to one crate that cause build errors in another crate,
consider this instead of a full build:
```sh
./mach check
```
It will run `cargo check`, which runs the analysis phase of the compiler
(and so shows build errors if any) but skips the code generation phase.
This can be a lot faster than a full build,
though of course it doesnt produce a binary you can run.
## Running
Run Servo with the command:
```sh
./servo [url] [arguments] # if you run with nightly build
./mach run [url] [arguments] # if you run with mach
# For example
./mach run https://www.google.com
```
### Commandline Arguments
- `-p INTERVAL` turns on the profiler and dumps info to the console every
`INTERVAL` seconds
- `-s SIZE` sets the tile size for painting; defaults to 512
- `-z` disables all graphical output; useful for running JS / layout tests
- `-Z help` displays useful output to debug servo
### Keyboard Shortcuts
- `Ctrl`+`L` opens URL prompt (`Cmd`+`L` on Mac)
- `Ctrl`+`R` reloads current page (`Cmd`+`R` on Mac)
- `Ctrl`+`-` zooms out (`Cmd`+`-` on Mac)
- `Ctrl`+`=` zooms in (`Cmd`+`=` on Mac)
- `Alt`+`left arrow` goes backwards in the history (`Cmd`+`left arrow` on Mac)
- `Alt`+`right arrow` goes forwards in the history (`Cmd`+`right arrow` on Mac)
- `Ctrl`+`Q` exits Servo (`Cmd`+`Q` on Mac)
- `Esc` exits fullscreen
### Runtime dependencies
#### Linux
* `GStreamer` >=1.18
* `gst-plugins-base` >=1.18
* `gst-plugins-good` >=1.18
* `gst-plugins-bad` >=1.18
* `gst-plugins-ugly` >=1.18
* `libXcursor`
* `libXrandr`
* `libXi`
* `libxkbcommon`
* `vulkan-loader`
## Developing
There are lots of mach commands you can use. You can list them with `./mach
--help`.
The generated documentation can be found on https://doc.servo.org/servo/index.html
[manual-build]: https://github.com/servo/servo/wiki/Building#manual-build-setup
[windows-tips]: https://github.com/servo/servo/wiki/Building#troubleshooting-the-windows-build
[android-docs]: https://github.com/servo/servo/wiki/Building-for-Android
- Follow the instructions above for the platform you are building on

View file

@ -1,32 +1,7 @@
Command Line Arguments
========================
# General
# Command line arguments
You can see available commands with:
```
./mach -h
./mach <sub-command> -h
```
Only arguments that need more explanation will be documented here.
Moved to the Servo book:
# Run
## Enable Experimental Features
Use `--pref` to enable experimental features like experimental DOM APIs, JavaScript APIs and CSS properties.
e.g. To enable Web VR and Bluetooth features:
```
./mach run -d -- --pref dom.webvr.enabled --pref dom.bluetooth.enabled ...
```
You can find all the available preferences at [resources/prefs.json](../resources/prefs.json).
# Debugging
## Remote Debugging
Use `--devtools 6000` to start the devtools server on port 6000.
e.g.
```
./mach run -d --devtools=6000 https://servo.org
```
To connect to the server, follow [this guide](https://developer.mozilla.org/en-US/docs/Tools/Remote_Debugging/Debugging_Firefox_Desktop#Connect).
- [Running servoshell](https://book.servo.org/running-servoshell.html)
- Hacking on Servo
- [Running servoshell](https://book.servo.org/hacking/running-servoshell.html)

View file

@ -1,425 +1,5 @@
# Hacking Servo - Quickstart
This guide covers the basic things one needs to know to start hacking Servo.
It doesn't cover how Servo works or how to use Git effectively (see the
[documentation](#documentation) section for those), but describes how to
set up your environment to compile, run, and debug Servo.
Moved to the Servo book:
- [Building Servo](#building-servo)
- [Running Servo](#running-servo)
- [mach](#mach)
- [mach and Servo options](#mach-and-servo-options)
- [Some basic Rust](#some-basic-rust)
- [Cargo and crates](#cargo-and-crates)
- [Working on a crate](#working-on-a-crate)
- [Editor support](#editor-support)
- [Visual Studio Code](#visual-studio-code)
- [Debugging](#debugging)
- [Logging](#logging)
- [println!()](#println)
- [Debugger](#debugger)
- [Tests](#tests)
- [Updating a test](#updating-a-test)
- [Add a new test](#add-a-new-test)
- [Debugging a test](#debugging-a-test)
- [Documentation](#documentation)
- [Ask questions](#ask-questions)
## Building Servo
Building Servo is quite easy. Install the prerequisites described in the [README](../README.md) file, then type:
```shell
./mach build -d
```
There are three main build profiles, which you can build and use independently of one another:
- debug builds, which allow you to use a debugger (lldb)
- release builds, which are slower to build but more performant
- production builds, which are used for official releases only
| profile | mach option | optimised? | debug<br>info? | debug<br>assertions? | finds resources in<br>current working dir? |
| ---------- | ---------------------- | ---------- | -------------- | -------------------- | ------------------------------------------ |
| debug | `-d` | no | yes | yes | yes |
| release | `-r` | yes | no | yes(!) | yes |
| production | `--profile production` | yes | yes | no | no |
You can change these settings in a servobuild file (see [servobuild.example](../servobuild.example)) or in the root [Cargo.toml](../Cargo.toml).
## Running Servo
The servo binary is located in `target/debug/servo` (or `target/release/servo`). You can directly run this binary, but we recommend using `./mach` instead:
```shell
./mach run -d -- https://github.com
```
… is equivalent to:
```shell
./target/debug/servo https://github.com
```
If you build with `-d`, run with `-d`. If you build with `-r`, run with `-r`.
## mach
`mach` is a python utility that does plenty of things to make our life easier (build, run, run tests, update dependencies… see `./mach --help`). Beside editing files and git commands, everything else is done via `mach`.
```shell
./mach run -d [mach options] -- [servo options]
```
The `--` separates `mach` options from `servo` options. This is not required, but we recommend it. `mach` and `servo` have some options with the same name (`--help`, `--debug`), so the `--` makes it clear where options apply.
### mach and Servo options
This guide only covers the most important options. Be sure to look at all the available mach commands and the servo options:
```shell
./mach --help # mach options
./mach run -- --help # servo options
./mach build # Build servo with the default configuration
./mach build --use-crown # Enable the crown linting tool - recommended when hacking on DOM code.
```
## Some basic Rust
Even if you have never seen any Rust code, it's not too hard to read Servo's code. But there are some basics things one must know:
- [Match](https://doc.rust-lang.org/stable/rust-by-example/flow_control/match.html) and [Patterns](https://doc.rust-lang.org/book/ch18-00-patterns.html)
- [Options](https://doc.rust-lang.org/stable/rust-by-example/std/option.html)
- [Expression](https://doc.rust-lang.org/stable/rust-by-example/expression.html)
- [Traits](https://doc.rust-lang.org/stable/rust-by-example/trait.html)
- That doesn't sound important, but be sure to understand how `println!()` works, especially the [formatting traits](https://doc.rust-lang.org/std/fmt/#formatting-traits)
This won't be enough to do any serious work at first, but if you want to navigate the code and fix basic bugs, that should do it. It's a good starting point, and as you dig into Servo source code, you'll learn more.
For more exhaustive documentation:
- [doc.rust-lang.org](https://doc.rust-lang.org)
- [rust by example](https://doc.rust-lang.org/stable/rust-by-example)
### Cargo and crates
A Rust library is called a crate. Servo uses plenty of crates. These crates are dependencies. They are listed in files called `Cargo.toml`. Servo is split into components and ports (see `components` and `ports` directories). Each has its own dependencies, and each has its own `Cargo.toml` file.
`Cargo.toml` files list the dependencies. You can edit this file.
For example, `components/net_traits/Cargo.toml` includes:
```
[dependencies.stb_image]
git = "https://github.com/servo/rust-stb-image"
```
But because `rust-stb-image` API might change over time, it's not safe to compile against the `HEAD` of `rust-stb-image`. A `Cargo.lock` file is a snapshot of a `Cargo.toml` file which includes a reference to an exact revision, ensuring everybody is always compiling with the same configuration:
```
[[package]]
name = "stb_image"
source = "git+https://github.com/servo/rust-stb-image#f4c5380cd586bfe16326e05e2518aa044397894b"
```
This file should not be edited by hand. In a normal Rust project, to update the git revision, you would use `cargo update -p stb_image`, but in Servo, use `./mach cargo-update -p stb_image`. Other arguments to cargo are also understood, e.g. use --precise '0.2.3' to update that crate to version 0.2.3.
See [Cargo's documentation about Cargo.toml and Cargo.lock files](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html).
### Working on a crate
As explained above, Servo depends on a lot of libraries, which makes it very modular. While working on a bug in Servo, you'll often end up in one of its dependencies. You will then want to compile your own version of the dependency (and maybe compiling against the HEAD of the library will fix the issue!).
For example, I'm trying to bring some cocoa events to Servo. The Servo window on Desktop is constructed with a library named [winit](https://github.com/rust-windowing/winit). winit itself depends on a cocoa library named [cocoa-rs](https://github.com/servo/cocoa-rs). When building Servo, magically, all these dependencies are downloaded and built for you. But because I want to work on this cocoa event feature, I want Servo to use my own version of _winit_ and _cocoa-rs_.
This is how my projects are laid out:
```
~/my-projects/servo/
~/my-projects/cocoa-rs/
```
Both folder are git repositories.
To make it so that servo uses `~/my-projects/cocoa-rs/`, first ascertain which version of the crate Servo is using and whether it is a git dependency or one from crates.io.
Both information can be found using, in this example, `cargo pkgid cocoa`(`cocoa` is the name of the package, which doesn't necessarily match the repo folder name).
If the output is in the format `https://github.com/servo/cocoa-rs#cocoa:0.0.0`, you are dealing with a git dependency and you will have to edit the `~/my-projects/servo/Cargo.toml` file and add at the bottom:
```toml
[patch]
"https://github.com/servo/cocoa-rs#cocoa:0.0.0" = { path = '../cocoa-rs' }
```
If the output is in the format `https://github.com/rust-lang/crates.io-index#cocoa#0.0.0`, you are dealing with a crates.io dependency and you will have to edit the `~/my-projects/servo/Cargo.toml` in the following way:
```toml
[patch]
"cocoa:0.0.0" = { path = '../cocoa-rs' }
```
Both will tell any cargo project to not use the online version of the dependency, but your local clone.
For more details about overriding dependencies, see [Cargo's documentation](https://doc.crates.io/specifying-dependencies.html#overriding-dependencies).
## Editor support
### Visual Studio Code
Running plain `cargo` will cause problems! For example, you might get rust-analyzer extension errors
about build scripts like
- The style crate requires enabling one of its 'servo' or 'gecko' feature flags and, in the 'servo'
case, one of 'servo-layout-2013' or 'servo-layout-2020'.
- (if you are on NixOS) thread 'main' panicked at 'called \`Result::unwrap()\` on an \`Err\` value:
"Could not run \`PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=\\"1\\" PKG_CONFIG_ALLOW_SYSTEM_LIBS=\\"1\\"
\\"pkg-config\\" \\"--libs\\" \\"--cflags\\" \\"fontconfig\\"\`
- (if you are on NixOS) [ERROR rust_analyzer::main_loop] FetchWorkspaceError: rust-analyzer failed to load workspace: Failed to load the project at /path/to/servo/Cargo.toml: Failed to read Cargo metadata from Cargo.toml file /path/to/servo/Cargo.toml, Some(Version { major: 1, minor: 74, patch: 1 }): Failed to run `cd "/path/to/servo" && "cargo" "metadata" "--format-version" "1" "--manifest-path" "/path/to/servo/Cargo.toml" "--filter-platform" "x86_64-unknown-linux-gnu"`: `cargo metadata` exited with an error: error: could not execute process `crown -vV` (never executed)
This is because the rustflags (flags passed to the rust compiler) that standard `cargo` provides are
different to what `./mach` uses, and so every time Servo is built using `cargo` it will undo all the
work done by `./mach` (and vice versa).
You can override this in a `.vscode/settings.json` file:
```json
{
"rust-analyzer.check.overrideCommand": [
"./mach", "check", "--message-format=json" ],
"rust-analyzer.cargo.buildScripts.overrideCommand": [
"./mach", "check", "--message-format=json" ],
"rust-analyzer.rustfmt.overrideCommand": [ "./mach", "fmt" ]
}
```
If you are hacking on DOM code it is recommended to build servo with `./mach build --use-crown` and configure
rust-analyzer to do the same by adding `--use-crown` to the `rust-analyzer.check.overrideCommand`:
```json
{
"rust-analyzer.check.overrideCommand": [
"./mach", "check", "--message-format=json", "--use-crown" ],
"rust-analyzer.cargo.buildScripts.overrideCommand": [
"./mach", "check", "--message-format=json", "--use-crown" ],
"rust-analyzer.rustfmt.overrideCommand": [ "./mach", "fmt" ]
}
```
If that still causes problems, then supplying a different target directory should fix this (although it will increase
the amount of disc space used).
```json
{
"rust-analyzer.checkOnSave.overrideCommand": [
"./mach", "check", "--message-format=json", "--target-dir", "target/lsp" ],
"rust-analyzer.cargo.buildScripts.overrideCommand": [
"./mach", "check", "--message-format=json", "--target-dir", "target/lsp" ],
"rust-analyzer.rustfmt.overrideCommand": [ "./mach", "fmt" ]
}
```
If you are on NixOS, you should also set CARGO_BUILD_RUSTC in `.vscode/settings.json` as follows,
where `/nix/store/.../crown` is the output of `nix-shell etc/shell.nix --run 'command -v crown'`.
These settings should be enough to not need to run `code .` from within a `nix-shell etc/shell.nix`,
but it wouldnt hurt to try that if you still have problems.
```json
{
"rust-analyzer.server.extraEnv": {
"CARGO_BUILD_RUSTC": "/nix/store/.../crown"
}
}
```
When enabling rust-analyzers proc macro support, you may start to see errors like
- proc macro \`MallocSizeOf\` not expanded: Cannot create expander for /path/to/servo/target/debug/deps/libfoo-0781e5a02b945749.so: unsupported ABI \`rustc 1.69.0-nightly (dc1d9d50f 2023-01-31)\` rust-analyzer(unresolved-proc-macro)
This means rust-analyzer is using the wrong proc macro server, and you will need to configure the correct one manually. Use mach to query the current sysroot path, and copy the last line of output:
```
$ ./mach rustc --print sysroot
NOTE: Entering nix-shell etc/shell.nix
info: component 'llvm-tools' for target 'x86_64-unknown-linux-gnu' is up to date
/home/me/.rustup/toolchains/nightly-2023-02-01-x86_64-unknown-linux-gnu
```
Then configure either your sysroot path or proc macro server path in `.vscode/settings.json`:
```json
{
"rust-analyzer.procMacro.enable": true,
"rust-analyzer.cargo.sysroot": "[paste what you copied]",
"rust-analyzer.procMacro.server": "[paste what you copied]/libexec/rust-analyzer-proc-macro-srv"
}
```
## Debugging
### Logging
Before starting the debugger right away, you might want to get some information about what's happening, how, and when. Luckily, Servo comes with plenty of logs that will help us. Type these 2 commands:
```shell
./mach run -d -- --help
./mach run -d -- --debug help
```
A typical command might be:
```shell
./mach run -d -- -i -y 1 --debug dump-style-tree /tmp/a.html
```
… to avoid using too many threads and make things easier to understand.
On macOS, you can add some Cocoa-specific debug options:
```shell
./mach run -d -- /tmp/a.html -- -NSShowAllViews YES
```
You can also enable some extra logging (warning: verbose!):
```
RUST_LOG="debug" ./mach run -d -- /tmp/a.html
```
Using `RUST_LOG="debug"` is usually the very first thing you might want to do if you have no idea what to look for. Because this is very verbose, you can combine these with `ts` (`moreutils` package (apt-get, brew)) to add timestamps and `tee` to save the logs (while keeping them in the console):
```
RUST_LOG="debug" ./mach run -d -- -i -y 1 /tmp/a.html 2>&1 | ts -s "%.S: " | tee /tmp/log.txt
```
You can filter by crate or module, for example `RUST_LOG="layout::inline=debug" ./mach run …`. Check the [env_logger](https://docs.rs/env_logger) documentation for more details.
Use `RUST_BACKTRACE=1` to dump the backtrace when Servo panics.
### println!()
You will want to add your own logs. Luckily, many structures [implement the `fmt::Debug` trait](https://doc.rust-lang.org/std/fmt/#fmtdisplay-vs-fmtdebug), so adding:
```rust
println!("foobar: {:?}", foobar)
```
usually just works. If it doesn't, maybe some of foobar's properties don't implement the right trait.
### Debugger
To run the debugger:
```shell
./mach run -d --debug -- -y 1 /tmp/a.html
```
This will start `lldb` on Mac, and `gdb` on Linux.
From here, use:
```shell
(lldb) b a_servo_function # add a breakpoint
(lldb) run # run until breakpoint is reached
(lldb) bt # see backtrace
(lldb) frame n # choose the stack frame from the number in the bt
(lldb) thread list
(lldb) next / step / …
(lldb) print varname
```
And to search for a function's full name/regex:
```shell
(lldb) image lookup -r -n <name> #lldb
(gdb) info functions <name> #gdb
```
See this [lldb tutorial](https://lldb.llvm.org/tutorial.html) and this [gdb tutorial](http://www.unknownroad.com/rtfm/gdbtut/gdbtoc.html).
To inspect variables and you are new with lldb, we recommend using the `gui` mode (use left/right to expand variables):
```
(lldb) gui
┌──<Variables>───────────────────────────────────────────────────────────────────────────┐
│ ◆─(&mut gfx::paint_task::PaintTask<Box<CompositorProxy>>) self = 0x000070000163a5b0 │
│ ├─◆─(msg::constellation_msg::PipelineId) id │
│ ├─◆─(url::Url) _url │
│ │ ├─◆─(collections::string::String) scheme │
│ │ │ └─◆─(collections::vec::Vec<u8>) vec │
│ │ ├─◆─(url::SchemeData) scheme_data │
│ │ ├─◆─(core::option::Option<collections::string::String>) query │
│ │ └─◆─(core::option::Option<collections::string::String>) fragment │
│ ├─◆─(std::sync::mpsc::Receiver<gfx::paint_task::LayoutToPaintMsg>) layout_to_paint_port│
│ ├─◆─(std::sync::mpsc::Receiver<gfx::paint_task::ChromeToPaintMsg>) chrome_to_paint_port│
└────────────────────────────────────────────────────────────────────────────────────────┘
```
If lldb crashes on certain lines involving the `profile()` function, it's not just you. Comment out the profiling code, and only keep the inner function, and that should do it.
## Tests
This is boring. But your PR won't get accepted without a test. Tests are located in the `tests` directory. You'll see that there are a lot of files in there, so finding the proper location for your test is not always obvious.
First, look at the "Testing" section in `./mach --help` to understand the different test categories. You'll also find some `update-*` commands. It's used to update the list of expected results.
To run a test:
```
./mach test-wpt tests/wpt/yourtest
```
For your PR to get accepted, source code also has to satisfy certain tidiness requirements.
To check code tidiness:
```
./mach test-tidy
```
### Updating a test
In some cases, extensive tests for the feature you're working on already exist under tests/wpt:
- Make a release build
- run `./mach test-wpt --release --log-raw=/path/to/some/logfile`
- run [`update-wpt` on it](https://github.com/servo/servo/blob/main/tests/wpt/README.md#updating-test-expectations)
This may create a new commit with changes to expectation ini files. If there are lots of changes,
it's likely that your feature had tests in wpt already.
Include this commit in your pull request.
### Add a new test
If you need to create a new test file, it should be located in `tests/wpt/mozilla/tests` or in `tests/wpt/web-platform-tests` if it's something that doesn't depend on servo-only features. You'll then need to update the list of tests and the list of expected results:
```
./mach test-wpt --manifest-update
```
### Debugging a test
See the [debugging guide](./debugging.md) to get started in how to debug Servo.
## Documentation
- Servo's directory structure: [ORGANIZATION.md](./ORGANIZATION.md)
- https://doc.servo.org/servo/index.html
- https://github.com/servo/servo/wiki
- https://doc.rust-lang.org/rust-by-example/
- https://doc.rust-lang.org
- Cargo & crates: https://doc.crates.io/guide.html
- mach help: `./mach --help`
- servo options: `./mach run -- --help`
- servo debug options: `./mach run -- --debug help`
## Ask questions
### [Servos Zulip](https://servo.zulipchat.com/)
### Discord servers
The official [Rust Discord server](https://discordapp.com/invite/rust-lang) is a great place to ask Rust specific questions, including questions related to cargo.
- [Hacking on Servo](https://book.servo.org/hacking/mach.html)

View file

@ -1,110 +1,6 @@
# Servo's directory structure:
* components
* bluetooth
* Implementation of the bluetooth thread.
* bluetooth_traits
* APIs to the bluetooth crate for crates that don't want to depend on the bluetooth crate for build speed reasons.
* canvas
* Implementation of painting threads for 2D and WebGL canvases.
* canvas_traits
* APIs to the canvas crate for crates that don't want to depend on the canvas crate for build speed reasons.
* compositing
* Integration with OS windowing/rendering and event loop.
* constellation
* Management of resources for a top-level browsing context (ie. tab).
* devtools
* In-process server to allow manipulating browser instances via a remote Firefox developer tools client.
* devtools_traits
* APIs to the devtools crate for crates that don't want to depend on the devtools crate for build speed reasons.
* fonts
* Code for dealing with fonts and text shaping.
* fonts_traits
* APIs to the fonts crate for crates that don't want to depend on the fonts crate for build speed reasons.
* layout
* Converts page content into positioned, styled boxes and passes the result to the renderer.
* layout_thread
* Runs the threads for layout, communicates with the script thread, and calls into the layout crate to do the layout.
* msg
* Shared APIs for communicating between specific threads and crates.
* net
* Network protocol implementations, and state and resource management (caching, cookies, etc.).
* net_traits
* APIs to the net crate for crates that don't want to depend on the net crate for build speed reasons.
* plugins
* Syntax extensions, custom attributes, and lints.
* profile
* Memory and time profilers.
* profile_traits
* APIs to the profile crate for crates that don't want to depend on the profile crate for build speed reasons.
* script
* Implementation of the DOM (native Rust code and bindings to SpiderMonkey).
* script_layout_interface
* The API the script crate provides for the layout crate.
* script_traits
* APIs to the script crate for crates that don't want to depend on the script crate for build speed reasons.
* selectors
* CSS selector matching.
* servo
* Entry points for the servo application and libservo embedding library.
* style
* APIs for parsing CSS and interacting with stylesheets and styled elements.
* style_traits
* APIs to the style crate for crates that don't want to depend on the style crate for build speed reasons.
* util
* Assorted utility methods and types that are commonly used throughout the project.
* webdriver_server
* In-process server to allow manipulating browser instances via a WebDriver client.
* webgpu
* Implementation of threads for the WebGPU API.
* etc
* Useful tools and scripts for developers.
* mach
* A command-line tool to help with developer tasks.
* ports
* winit
* Embedding implementation for the `winit` windowing library.
* python
* servo
* Implementations of servo-specific mach commands.
* tidy
* Python package of code lints that are automatically run before merging changes.
* resources
* Files used at run time. Need to be included somehow when distributing binary builds.
* support
* android
* Libraries that require special handling for building for Android platforms
* rust-task_info
* Library for obtaining information about memory usage for a process
* target
* debug
* Build artifacts generated by `./mach build --debug`.
* doc
* Documentation is generated here by the `rustdoc` tool when running `./mach doc`
* release
* Build artifacts generated by `./mach build --release`.
* tests
* dromaeo
* Harness for automatically running the Dromaeo testsuite.
* html
* Manual tests and experiments.
* jquery
* Harness for automatically running the jQuery testsuite.
* power
* Tools for measurement of power consumption.
* unit
* Unit tests using rustcs built-in test harness.
* wpt
* W3C web-platform-tests and csswg-tests along with tools to run them and expected failures.
# Servos directory structure
# Major dependencies
* <https://github.com/servo/rust-mozjs>, <https://github.com/servo/mozjs>: bindings to SpiderMonkey
* <https://github.com/hyperium/hyper>: an HTTP implementation
* <https://github.com/servo/html5ever>: an HTML5 parser
* <https://github.com/servo/ipc-channel>: an IPC implementation
* <https://github.com/image-rs/image>: image decoders
* <https://github.com/rust-windowing/winit>: cross-platform windowing and input
* <https://github.com/jrmuizel/raqote>: a pure Rust 2D graphics library
* <https://github.com/servo/rust-cssparser>: a CSS parser
* <https://github.com/housleyjk/ws-rs>: a WebSocket protocol implementation
* <https://github.com/servo/rust-url>: an implementation of the URL specification
* <https://github.com/servo/webrender>: a GPU renderer
Moved to the Servo book:
- Servos architecture
- [Directory structure](https://book.servo.org/architecture/directory-structure.html)

View file

@ -1,29 +1,6 @@
# Style Guide
The majority of our style recommendations are automatically enforced via our
automated linters. This document has guidelines that are less easy to lint for.
Moved to the Servo book:
## Shell scripts
Shell scripts are suitable for small tasks or wrappers, but it's preferable to use Python for
anything with a hint of complexity or in general.
Shell scripts should be written using bash, starting with this shebang:
```
#!/usr/bin/env bash
```
Note that the version of bash available on macOS by default is quite old, so be
careful when using new features.
Scripts should enable a few options at the top for robustness:
```
set -o errexit
set -o nounset
set -o pipefail
```
Rememeber to quote all variables, using the full form: `"${SOME_VARIABLE}"`.
Use `"$(some-command)"` instead of backticks for command substitution. Note
that these should be quoted as well.
- Pre-book docs
- [docs/STYLE_GUIDE.md](https://book.servo.org/old/STYLE_GUIDE.html)

View file

@ -1,147 +1,6 @@
# Servo's style system overview
This document provides an overview of Servo's style system. For more extensive details,
refer to the [style doc comments][style-doc], or the [Styling
Overview][wiki-styling-overview] in the wiki, which includes a conversation between
Boris Zbarsky and Patrick Walton about how style sharing works.
Moved to the Servo book:
<a name="selector-impl"></a>
## Selector Implementation
To ensure compatibility with Stylo (a project integrating Servo's style system into Gecko),
selectors must be consistent.
The consistency is implemented in [selectors' SelectorImpl][selector-impl],
containing the logic related to parsing pseudo-elements and other pseudo-classes
apart from [tree-structural ones][tree-structural-pseudo-classes].
Servo extends the selector implementation trait in order to allow a few more
things to be shared between Stylo and Servo.
The main Servo implementation (the one that is used in regular builds) is
[SelectorImpl][servo-selector-impl].
<a name="dom-glue"></a>
## DOM glue
In order to keep DOM, layout and style in different modules, there are a few
traits involved.
Style's [`dom` traits][style-dom-traits] (`TDocument`, `TElement`, `TNode`,
`TRestyleDamage`) are the main "wall" between layout and style.
Layout's [`wrapper`][layout-wrapper] module makes sure that
layout traits have the required traits implemented.
<a name="stylist"></a>
## The Stylist
The [`stylist`][stylist] structure holds all the selectors and
device characteristics for a given document.
The stylesheets' CSS rules are converted into [`Rule`][selectors-rule]s.
They are then introduced in a [`SelectorMap`][selectors-selectormap] depending
on the pseudo-element (see [`PerPseudoElementSelectorMap`][per-pseudo-selectormap]),
stylesheet origin (see [`PerOriginSelectorMap`][per-origin-selectormap]), and
priority (see the `normal` and `important` fields in
[`PerOriginSelectorMap`][per-origin-selectormap]).
This structure is effectively created once per [pipeline][docs-pipeline], in the
corresponding LayoutThread.
<a name="properties"></a>
## The `properties` module
The [properties module][properties-module] is a mako template. Its complexity is derived
from the code that stores properties, [`cascade` function][properties-cascade-fn] and computation logic of the returned value which is exposed in the main function.
<a name="pseudo-elements"></a>
## Pseudo-Element resolution
Pseudo-elements are a tricky section of the style system. Not all
pseudo-elements are very common, and so some of them might want to skip the
cascade.
Servo has, as of right now, five [pseudo-elements][servo-pseudo-elements]:
* [`::before`][mdn-pseudo-before] and [`::after`][mdn-pseudo-after].
* [`::selection`][mdn-pseudo-selection]: This one is only partially
implemented, and only works for text inputs and textareas as of right now.
* `::-servo-details-summary`: This pseudo-element represents the `<summary>` of
a `<details>` element.
* `::-servo-details-content`: This pseudo-element represents the contents of
a `<details>` element.
Both `::-servo-details-*` pseudo-elements are private (i.e. they are only parsed
from User-Agent stylesheets).
Servo has three different ways of cascading a pseudo-element, which are defined
in [`PseudoElementCascadeType`][pseudo-cascade-type]:
<a name="pe-cascading-eager"></a>
### "Eager" cascading
This mode computes the computed values of a given node's pseudo-element over the
first pass of the style system.
This is used for all public pseudo-elements, and is, as of right now, **the only
way a public pseudo-element should be cascaded** (the explanation for this is
below).
<a name="pe-cascading-precomputed"></a>
### "Precomputed" cascading
Or, better said, no cascading at all. A pseudo-element marked as such is not
cascaded.
The only rules that apply to the styles of that pseudo-element are universal
rules (rules with a `*|*` selector), and they are applied directly over the
element's style if present.
`::-servo-details-content` is an example of this kind of pseudo-element, all the
rules in the UA stylesheet with the selector `*|*::-servo-details-content` (and
only those) are evaluated over the element's style (except the `display` value,
that is overwritten by layout).
This should be the **preferred type for private pseudo-elements** (although some
of them might need selectors, see below).
<a name="pe-cascading-lazy"></a>
### "Lazy" cascading
Lazy cascading allows to compute pseudo-element styles lazily, that is, just
when needed.
Currently (for Servo, not that much for stylo), **selectors supported for this
kind of pseudo-elements are only a subset of selectors that can be matched on
the layout tree, which does not hold all data from the DOM tree**.
This subset includes tags and attribute selectors, enough for making
`::-servo-details-summary` a lazy pseudo-element (that only needs to know
if it is in an `open` details element or not).
Since no other selectors would apply to it, **this is (at least for now) not an
acceptable type for public pseudo-elements, but should be considered for private
pseudo-elements**.
[style-doc]: https://doc.servo.org/style/index.html
[wiki-styling-overview]: https://github.com/servo/servo/wiki/Styling-overview
[selector-impl]: https://doc.servo.org/selectors/parser/trait.SelectorImpl.html
[selector-impl-ext]: https://doc.servo.org/style/selector_parser/trait.SelectorImplExt.html
[servo-selector-impl]: https://doc.servo.org/style/servo/selector_parser/struct.SelectorImpl.html
[tree-structural-pseudo-classes]: https://www.w3.org/TR/selectors4/#structural-pseudos
[style-dom-traits]: https://doc.servo.org/style/dom/index.html
[layout-wrapper]: https://doc.servo.org/layout/wrapper/index.html
[pseudo-cascade-type]: https://doc.servo.org/style/selector_parser/enum.PseudoElementCascadeType.html
[servo-pseudo-elements]: https://doc.servo.org/style/selector_parser/enum.PseudoElement.html
[mdn-pseudo-before]: https://developer.mozilla.org/en/docs/Web/CSS/::before
[mdn-pseudo-after]: https://developer.mozilla.org/en/docs/Web/CSS/::after
[mdn-pseudo-selection]: https://developer.mozilla.org/en/docs/Web/CSS/::selection
[stylist]: https://doc.servo.org/style/stylist/struct.Stylist.html
[selectors-selectormap]: https://doc.servo.org/style/selector_map/struct.SelectorMap.html
[selectors-rule]: https://doc.servo.org/style/stylist/struct.Rule.html
[per-pseudo-selectormap]: https://doc.servo.org/style/selector_parser/struct.PerPseudoElementMap.html
[per-origin-selectormap]: https://doc.servo.org/style/stylist/struct.PerOriginSelectorMap.html
[docs-pipeline]: https://github.com/servo/servo/blob/main/docs/glossary.md#pipeline
[properties-module]: https://doc.servo.org/style/properties/index.html
[properties-cascade-fn]: https://doc.servo.org/style/properties/fn.cascade.html
- Servos architecture
- [Style](https://book.servo.org/architecture/style.html)

View file

@ -1,78 +1,6 @@
# How WebXR works in Servo
## Terminology
Moved to the Servo book:
Servo's WebXR implementation involves three main components:
1. The script thread (runs all JS for a page)
2. The WebGL thread (maintains WebGL canvas data and invokes GL operations corresponding to [WebGL APIs](https://registry.khronos.org/webgl/specs/latest/1.0/))
3. The compositor (AKA the main thread)
Additionally, there are a number of WebXR-specific concepts:
* The [discovery object](https://doc.servo.org/webxr_api/trait.DiscoveryAPI.html) (ie. how Servo discovers if a device can provide a WebXR session)
* The [WebXR registry](https://doc.servo.org/webxr_api/struct.MainThreadRegistry.html) (the compositor's interface to WebXR)
* The [layer manager](https://doc.servo.org/webxr_api/layer/trait.LayerManagerAPI.html) (manages WebXR layers for a given session and frame operations on those layers)
* The [layer grand manager](https://doc.servo.org/webxr_api/layer/trait.LayerGrandManagerAPI.html) (manages all layer managers for WebXR sessions)
Finally, there are graphics-specific concepts that are important for the low-level details of rendering with WebXR:
* [surfman](https://github.com/servo/webxr/blob/main/webxr/glwindow/mod.rs#L448-L452) is a crate that abstracts away platform-specific details of OpenGL hardware-accelerated rendering
* [surface](https://doc.servo.org/surfman/platform/unix/default/surface/type.Surface.html) is a hardware buffer that are tied to a specific OpenGL context
* [surface texture](https://doc.servo.org/surfman/platform/unix/default/surface/type.SurfaceTexture.html) is an OpenGL texture that wraps a surface. Surface textures can be shared between OpenGL contexts.
* [surfman context](https://doc.servo.org/surfman/platform/unix/default/context/type.Context.html) represents a particular OpenGL context, and is backed by platform-specific implementations (such as EGL on Unix-based platforms)
* [ANGLE](https://github.com/servo/mozangle/) is an OpenGL implementation on top of Direct3D which is used in Servo to provide a consistent OpenGL backend on Windows-based platforms
## How Servo's compositor starts
The embedder is responsible for creating a window and [triggering the rendering context creation](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/ports/servoshell/headed_window.rs#L134) appropriately.
Servo creates the rendering context by [creating a surfman context](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/gfx/rendering_context.rs#L48-L58) which will
be [used by the compositor](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/servo/lib.rs#L467) for all [web content rendering operations](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/servo/lib.rs#L269-L281).
## How a session starts
When a webpage invokes `navigator.xr.requestSession(..)` through JS, this corresponds to the [XrSystem::RequestSession](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/script/dom/xrsystem.rs#L158) method in Servo.
This method [sends a message](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr-api/registry.rs#L103-L108) to the [WebXR message handler](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr-api/registry.rs#L193-L195)
that lives on the main thread, under the [control of the compositor](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/compositing/compositor.rs#L2049).
The WebXR message handler iterates over all known discovery objects and attempts to [request a session](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr-api/registry.rs#L217-L231)
from each of them. The discovery objects encapsulate creating a session for each supported backend.
As of Feb 3, 2024, there are five WebXR backends:
* [magicleap](https://github.com/servo/webxr/tree/main/webxr/magicleap) - supports Magic Leap 1.0 devices
* [googlevr](https://github.com/servo/webxr/tree/main/webxr/googlevr) - supports Google VR
* [headless](https://github.com/servo/webxr/tree/main/webxr/headless) - supports a window-less, device-less device for automated tests
* [glwindow](https://github.com/servo/webxr/tree/main/webxr/glwindow) - supports a GL-based window for manual testing in desktop environments without real devices
* [openxr](https://github.com/servo/webxr/tree/main/webxr/openxr) - supports devices that implement the OpenXR standard
WebXR sessions need to [create a layer manager](https://github.com/servo/webxr/blob/main/webxr/glwindow/mod.rs#L448-L452)
at some point in order to be able to create and render to WebXR layers. This happens in several steps:
1. some initialization happens on the main thread
2. the main thread [sends a synchronous message](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/canvas/webgl_thread.rs#L3182-L3187) to the WebGL thread
3. the WebGL thread [receives the message](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/canvas/webgl_thread.rs#L392-L396)
4. some backend-specific, graphics-specific initialization happens on the WebGL thread, hidden behind the [layer manager factory](https://doc.servo.org/webxr_api/struct.LayerManagerFactory.html) abstraction
5. the new layer manager is [stored in the WebGL thread](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/canvas/webgl_thread.rs#L3058-L3061)
6. the main thread [receives a unique identifier](https://github.com/servo/servo/blob/d7d0451424faf1bf9c705068bea1aa8cf582d6ad/components/canvas/webgl_thread.rs#L3189-L3196) representing the new layer manager
This cross-thread dance is important because the device performing the rendering often has strict requirements for the compatibility of any
WebGL context that is used for rendering, and most GL state is only observable on the thread that created it.
## How an OpenXR session is created
The OpenXR discovery process starts at [OpenXrDiscovery::request_session](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L309).
The discovery object only has access to whatever state was passed in its constructor, as well as a [SessionBuilder](https://doc.servo.org/webxr_api/struct.SessionBuilder.html)
object that contains values required to create a new session.
Creating an OpenXR session first [creates an OpenXR instance](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L192),
which allows coniguring which extensions are in use. There are different extensions used to initialize OpenXR on different platforms; for Window
the [D3D extension](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L213) can be used
since Servo relies on ANGLE for its OpenGL implementation.
Once an OpenXR instance exists, the session builder is used to create a new WebXR session that [runs in its own thread](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L331).
All WebXR sessions can either [run in a thread](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr-api/session.rs#L513-L538)
or have Servo [run them on the main thread](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr-api/session.rs#L540-L552).
This choice has implications for how the graphics for the WebXR session can be set up, based on what GL state must be available for sharing.
OpenXR's new session thread [initializes an OpenXR device](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L332-L337),
which is responsible for creating the actual OpenXR session. This session object is [created on the WebGL thread](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L864-L878)
as part of creating the OpenXR layer manager, since it relies on [sharing the underlying GPU device](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L443-L460) that the WebGL thread uses.
Once the session object has been created, the main thread can [obtain a copy](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L878)
and resume initializing the [remaining properties](https://github.com/servo/webxr/blob/614420b9830615376563fc6e1d98c52119f97123/webxr/openxr/mod.rs#L882-L1026) of the new device.
- Servos architecture
- [WebXR](https://book.servo.org/architecture/webxr.html)

View file

@ -1,62 +1,6 @@
# Servo debugging guide
There are a few ways to debug Servo. `mach` supports a `--debug` flag that
searches a suitable debugger for you and runs Servo with the appropriate
arguments under it:
Moved to the Servo book:
```
./mach run --debug test.html
```
You can also specify an alternative debugger using the `--debugger` flag:
```
./mach run --debugger=my-debugger test.html
```
You can also, of course, run directly your debugger on the Servo binary:
```
$ gdb --args ./target/debug/servo test.html
```
## Debugging SpiderMonkey.
You can build Servo with a debug version of SpiderMonkey passing the
`--debug-mozjs` flag to `./mach build`.
Note that this sometimes can cause problems when an existing build exists, so
you might have to delete the `mozjs` build directory, or run `./mach clean`
before your first `--debug-mozjs` build.
## Debugging Servo with [rr][rr].
To record a trace under rr you can either use:
```
$ ./mach run --debugger=rr testcase.html
```
Or:
```
$ rr record ./target/debug/servo testcase.html
```
### Running WPT tests under rr's chaos mode.
Matt added a mode to Servo's testing commands to record traces of Servo running
a test or set of tests until the result is unexpected.
To use this, you can pass the `--chaos` argument to `mach test-wpt`:
```
$ ./mach test-wpt --chaos path/to/test
```
Note that for this to work you need to have `rr` in your `PATH`.
Also, note that this might generate a lot of traces, so you might want to delete
them when you're done. They're under `$HOME/.local/share/rr`.
[rr]: http://rr-project.org/
- Hacking on Servo
- [Debugging](https://book.servo.org/hacking/debugging.html)

View file

@ -1,35 +1,6 @@
# How to use this glossary
This is a collection of common terms that have a specific meaning in the context of the Servo project. The goal is to provide high-level definitions and useful links for further reading, rather than complete documentation about particular parts of the code.
If there is a word or phrase used in Servo's code, issue tracker, mailing list, etc. that is confusing, please make a pull request that adds it to this file with a body of `TODO`. This will signal more knowledgeable people to add a more meaningful definition.
# Glossary
### Compositor ###
Moved to the Servo book:
The thread that receives input events from the operating system and forwards them to the constellation. It is also in charge of compositing complete renders of web content and displaying them on the screen as fast as possible.
### Constellation ###
The thread that controls a collection of related web content. This could be thought of as an owner of a single tab in a tabbed web browser; it encapsulates session history, knows about all frames in a frame tree, and is the owner of the pipeline for each contained frame.
### Display list ###
A list of concrete rendering instructions. The display list is post-layout, so all items have stacking-context-relative pixel positions, and z-index has already been applied, so items later in the display list will always be on top of items earlier in it.
### Layout thread ###
A thread that is responsible for laying out a DOM tree into layers of boxes for a particular document. Receives commands from the script thread to lay out a page and either generate a new display list for use by the renderer thread, or return the results of querying the layout of the page for use by script.
### Pipeline ###
A unit encapsulating a means of communication with the script, layout, and renderer threads for a particular document. Each pipeline has a globally-unique id which can be used to access it from the constellation.
### Renderer thread (alt. paint thread) ###
A thread which translates a display list into a series of drawing commands that render the contents of the associated document into a buffer, which is then sent to the compositor.
### Script thread (alt. script task) ###
A thread that executes JavaScript and stores the DOM representation of all documents that share a common [origin](https://tools.ietf.org/html/rfc6454). This thread translates input events received from the constellation into DOM events [per the specification](https://w3c.github.io/uievents/), invokes the HTML parser when new page content is received, and evaluates JS for events like timers and `<script>` elements.
- Pre-book docs
- [docs/glossary.md](https://book.servo.org/old/glossary.html)

View file

@ -1,6 +1,6 @@
<!doctype html>
<title>Servo, the parallel browser engine</title>
<meta http-equiv=refresh content="0;url=servo/index.html">
<meta http-equiv=refresh content="0;url=https://book.servo.org/">
Documentation for Servo, the parallel browser engine.
Start with <a href="servo/index.html">the <code>servo</code> crate</a>
Start with <a href="https://book.servo.org/">The Servo Book</a>.

248
tests/wpt/README.md vendored
View file

@ -1,246 +1,6 @@
This folder contains the web platform tests and the
code required to integrate them with Servo.
To learn how to write tests, go [here](http://web-platform-tests.org/writing-tests/index.html).
# Web tests (including [Web Platform Tests](https://web-platform-tests.org))
Contents
========
Moved to the Servo book:
In particular, this folder contains:
* `config.ini`: some configuration for the web-platform-tests.
* `include.ini`: the subset of web-platform-tests we currently run.
* `tests`: copy of the web-platform-tests.
* `meta`: expected failures for the web-platform-tests we run.
* `mozilla`: web-platform-tests that cannot be upstreamed.
Running the tests
=================
The simplest way to run the web-platform-tests in Servo is `./mach
test-wpt` in the root directory. This will run the subset of
JavaScript tests defined in `include.ini` and log the output to
stdout.
A subset of tests may be run by providing positional arguments to the
mach command, either as filesystem paths or as test urls e.g.
./mach test-wpt tests/wpt/tests/dom/historical.html
to run the dom/historical.html test, or
./mach test-wpt dom
to run all the DOM tests.
There are also a large number of command line options accepted by the
test harness; these are documented by running with `--help`.
Running all tests
------------------------------
Running all the WPT tests with debug mode results in a lot of timeout.
If one wants to run all the tests,
build with `mach build -r`
and
test with `mach test-wpt --release`
Running the tests with an external WPT server
---------------------------------------------
Normally wptrunner starts its own WPT server, but occasionally you
might want to run multiple instances of `mach test-wpt`, such as when
debugging one test while running the full suite in the background, or
when running a single test many times in parallel (--processes only
works across different tests).
This would lead to a “Failed to start HTTP server” errors, because you
can only run one WPT server at a time. To fix this:
1. Follow the steps in [**Running the tests manually**](#running-the-tests-manually)
2. Add a `break` to [start_servers in serve.py](https://github.com/servo/servo/blob/ce92b7bfbd5855aac18cb4f8a8ec59048041712e/tests/wpt/web-platform-tests/tools/serve/serve.py#L745-L783) as follows:
```
--- a/tests/wpt/tests/tools/serve/serve.py
+++ b/tests/wpt/tests/tools/serve/serve.py
@@ -746,6 +746,7 @@ def start_servers(logger, host, ports, paths, routes, bind_address, config,
mp_context, log_handlers, **kwargs):
servers = defaultdict(list)
for scheme, ports in ports.items():
+ break
assert len(ports) == {"http": 2, "https": 2}.get(scheme, 1)
# If trying to start HTTP/2.0 server, check compatibility
```
3. Run `mach test-wpt` as many times as needed
If you get unexpected TIMEOUT in testharness tests, then the custom
testharnessreport.js may have been installed incorrectly (see
[**Running the tests manually**](#running-the-tests-manually)
for more details).
Running the tests manually
--------------------------
(See also [the relevant section of the upstream README][upstream-running].)
It can be useful to run a test without the interference of the test runner, for
example when using a debugger such as `gdb`. To do this, we need to start the
WPT server manually, which requires some extra configuration.
To do this, first add the following to the system's hosts file:
127.0.0.1 www.web-platform.test
127.0.0.1 www1.web-platform.test
127.0.0.1 www2.web-platform.test
127.0.0.1 web-platform.test
127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test
127.0.0.1 xn--lve-6lad.web-platform.test
Navigate to `tests/wpt/web-platform-tests` for the remainder of this section.
Normally wptrunner [installs Servos version of testharnessreport.js][environment],
but when starting the WPT server manually, we get the default version, which
wont report test results correctly. To fix this:
1. Create a directory `local-resources`
2. Copy `tools/wptrunner/wptrunner/testharnessreport-servo.js` to `local-resources/testharnessreport.js`
3. Edit `local-resources/testharnessreport.js` to substitute the variables as follows:
* `%(output)d`
* → `1` if you want to play with the test interactively (≈ pause-after-test)
* → `0` if you dont care about that (though its also ok to use `1` always)
* `%(debug)s``true`
4. Create a `./config.json` as follows (see `tools/wave/config.default.json` for defaults):
```
{"aliases": [{
"url-path": "/resources/testharnessreport.js",
"local-dir": "local-resources"
}]}
```
[environment]: https://github.com/servo/servo/blob/ce92b7bfbd5855aac18cb4f8a8ec59048041712e/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/environment.py#L231-L237
Then start the server with `./wpt serve`. To check if `testharnessreport.js` was installed correctly:
* The standard output of `curl http://web-platform.test:8000/resources/testharnessreport.js`
should look like [testharnessreport-servo.js], not like [the default testharnessreport.js]
* The standard output of `target/release/servo http://web-platform.test:8000/css/css-pseudo/highlight-pseudos-computed.html`
(or any [testharness test]) should contain lines starting with:
* `TEST START`
* `TEST STEP`
* `TEST DONE`
* `ALERT: RESULT:`
[testharnessreport-servo.js]: https://github.com/servo/servo/blob/ce92b7bfbd5855aac18cb4f8a8ec59048041712e/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testharnessreport-servo.js
[the default testharnessreport.js]: https://github.com/servo/servo/blob/ce92b7bfbd5855aac18cb4f8a8ec59048041712e/tests/wpt/web-platform-tests/resources/testharnessreport.js
[testharness test]: http://web-platform-tests.org/writing-tests/testharness.html
To prevent browser SSL warnings when running HTTPS tests locally,
you will need to run Servo with `--certificate-path resources/cert-wpt-only`.
[upstream-running]: https://github.com/w3c/web-platform-tests#running-the-tests
Running the tests in Firefox
----------------------------
When working with tests, you may want to compare Servo's result with Firefox.
You can supply `--product firefox` along with the path to a Firefox binary (as
well as few more odds and ends) to run tests in Firefox from your Servo
checkout:
GECKO="$HOME/projects/mozilla/gecko"
GECKO_BINS="$GECKO/obj-firefox-release-artifact/dist/Nightly.app/Contents/MacOS"
./mach test-wpt dom --product firefox --binary $GECKO_BINS/firefox --certutil-binary $GECKO_BINS/certutil --prefs-root $GECKO/testing/profiles
Updating test expectations
==========================
When fixing a bug that causes the result of a test to change, the expected
results for that test need to be changed. This can be done manually, by editing
the `.ini` file under the `meta` folder that corresponds to the test. In
this case, remove the references to tests whose expectation is now `PASS`, and
remove `.ini` files that no longer contain any expectations.
When a larger number of changes is required, this process can be automated.
This first requires saving the raw, unformatted log from a test run, for
example by running:
./mach test-wpt --log-raw /tmp/servo.log
Once the log is saved, run from the root directory:
./mach update-wpt /tmp/servo.log
The same process can be done for the legacy layout engine:
./mach test-wpt --legacy-layout --log-raw /tmp/servo-legacy.log
./mach update-wpt --legacy-layout /tmp/servo-legacy.log
The updated expectations will be in `tests/wpt/meta/` and
`tests/wpt/meta-legacy-layout/` respectively.
Writing new tests
=================
The simplest way to create a new test is to use the following command:
./mach create-wpt tests/wpt/path/to/new/test.html
This will create test.html in the appropriate directory using the WPT
template for JavaScript tests. Tests are written using [testharness.js](https://github.com/w3c/testharness.js/). Documentation can be found [here](http://testthewebforward.org/docs/testharness-library.html).
To create a new reference test instead, use the following:
./mach create-wpt --reftest tests/wpt/path/to/new/reftest.html --reference tests/wpt/path/to/reference.html
`reference.html` will be created if it does not exist, and `reftest.html`
will be created using the WPT reftest template. To know more about reftests, check [this](http://web-platform-tests.org/writing-tests/reftests.html).
These new tests can then be run in the following manner like any other WPT test:
./mach test-wpt tests/wpt/path/to/new/test.html
./mach test-wpt tests/wpt/path/to/new/reftest.html
Editing tests
=============
web-platform-tests may be edited in-place and the changes committed to
the servo tree. These changes will be upstreamed when the tests are
next synced.
Servo-specific tests
====================
The `mozilla` directory contains tests that cannot be upstreamed for some
reason (e.g. because they depend on Servo-specific APIs), as well as some
legacy tests that should be upstreamed at some point. When run they are
mounted on the server under `/_mozilla/`.
Analyzing reftest results
=========================
Reftest results can be analyzed from a raw log file. To generate this run
with the `--log-raw` option e.g.
./mach test-wpt --log-raw wpt.log
This file can then be fed into the
[reftest analyzer](https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer-structured.xhtml)
which will show all failing tests (not just those with unexpected results).
Note that this ingests logs in a different format to [original version of the
tool](https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer.xhtml)
written for gecko reftests.
The reftest analyzer allows pixel-level comparison of the test and reference
screenshots. Tests that both fail and have an unexpected result are marked
with a `!`.
Updating the WPT manifest
=========================
MANIFEST.json can be regenerated automatically with the mach command `update-manifest` e.g.
./mach update-manifest
This is equivalent to running
./mach test-wpt --manifest-update SKIP_TESTS
- Hacking on Servo
- [Automated testing](https://book.servo.org/hacking/testing.html)