---
# System prepended metadata

title: Updating ANGLE
tags: [webgl]

---

# Updating ANGLE

We aim to update ANGLE every two Firefox cycles.
Examples will be given based on 2019aug16's ANGLE update for Firefox 70. (our last ANGLE update was in 68, though we took some cherry-picks in 69)

## 0. Ingredients

- Windows system
- depot_tools checkout: https://chromium.googlesource.com/chromium/tools/depot_tools.git
- CMD shell with depot_tools in PATH (consider depot_tools.bat below)
    - I use depot_tools.bat (see below) instead of putting depot_tools in my permanent PATH, because depot_tools has its own git and friends that I don't want polluting my system.
    - You can also just put it in PATH temporarily, though I find this annoying.
- ANGLE checkout with remotes:
    - `origin`:  https://chromium.googlesource.com/angle/angle
    - `moz`: git@github.com:mozilla/angle.git

### `depot_tools.bat`:
```
@title depot_tools cmd
set PATH=C:\dev\depot_tools;%PATH%;
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
set GYP_MSVS_VERSION=2019
@cmd
```

## 1. Choose a merge-base

For our merge-base we want to choose an upstream branch that matches what Chromium is targetting, generally for their Beta channel.

OmahaProxy is their tool for seeing what's shipping: https://omahaproxy.appspot.com/

We're looking for `win`+`beta` row, `true_branch` column. (Today that's `3865`)

## 2. Rebase our top-of-tree ANGLE on the merge-base

Checkout our previous top-of-tree ANGLE branch from the `moz` remote.
`git fetch origin` will grab all the new numbered branches.
Rebase onto the new merge-base: `git rebase -i origin/chromium/3865`
Check that the rebase looks sane! (gfx/angle/cherry_picks.txt will give you an idea of what to expect)
Rebasing might turn up conflicts that either:

- Are for csets that are redundant or no longer necessary, or
- Are from bitrot, and need to be repaired.

Good luck! We try upstream our changes into ANGLE aggressively, so ideally all our cherry_picks disappear in subsequent ANGLE updates.

## 3. `scripts/bootstrap.py` and `gclient sync`

Checking out the ANGLE git repo is only part of the equation. We'll also need to download/update its dependencies, which is done with `gclient sync`.

In your depot_tools shell:
```
py scripts\bootstrap.py
gclient sync
```

### I got "Exception: Visual Studio Version 2017 (from GYP_MSVS_VERSION) not found."
Make sure VS 2019 is installed, set GYP_MSVS_VERSION, and re-run:
```
set GYP_MSVS_VERSION=2019
gclient sync
```

## 4. Vendor into Gecko

In your gecko checkout, checkout something recent, like Central's tip. (both git and hg should work for this, but I use git)

Update the merge-base file at `gfx/angle/MERGE_BASE` with `chromium/3865`.

In your depot_tools shell:
```
cd path\to\angle-repo
py ..\path\to\gecko-repo\gfx\angle\update_angle.py origin
```

You should see output like:
```
C:\dev\angle>py ..\mozilla\gecko4\gfx\angle\update-angle.py origin
Importing graph
  ('gn', 'gen', 'out')
Done. Made 172 targets from 70 files in 3270ms
  ('gn', 'desc', '--format=json', 'out', '*')

Processing graph
  static_library //:translator
  static_library //:angle_common
  source_set //:angle_system_utils
  source_set //:angle_version
  action //:commit_id
  source_set //:includes
  source_set //:xxhash
  static_library //:preprocessor
  shared_library //:libEGL
  source_set //:libEGL_egl_loader
  shared_library //:libGLESv2
  source_set //:libANGLE
  static_library //:angle_gpu_info_util
  static_library //:angle_image_util
  copy //:copy_compiler_dll
  group //build/config:shared_library_deps
  group //build/config:common_deps

7 libraries:
  //:angle_common
  //:libEGL
  //:angle_image_util
  //:libGLESv2
  //:angle_gpu_info_util
  //:translator
  //:preprocessor

Logging cherry picks to ..\mozilla\gecko4\gfx\angle\cherry_picks.txt.
  ('git', 'merge-base', 'HEAD', 'origin/chromium/3865')
  ('git', 'log', '08b97da894b278c10e70b6888ac65e3972a13b31~1..08b97da894b278c10e70b6888ac65e3972a13b31')
  ('git', 'log', '08b97da894b278c10e70b6888ac65e3972a13b31..')

Run actions
  ('ninja', '-C', 'out', ':commit_id')
ninja: Entering directory `out'
ninja: no work to do.

Export targets
    Writing ..\mozilla\gecko4\gfx\angle\targets\angle_common\moz.build
    Writing ..\mozilla\gecko4\gfx\angle\targets\libEGL\moz.build
    Writing ..\mozilla\gecko4\gfx\angle\targets\angle_image_util\moz.build
[libGLESv2] Unrecognized define: ANGLE_CAPTURE_ENABLED
    Writing ..\mozilla\gecko4\gfx\angle\targets\libGLESv2\moz.build
    Writing ..\mozilla\gecko4\gfx\angle\targets\angle_gpu_info_util\moz.build
    Writing ..\mozilla\gecko4\gfx\angle\targets\translator\moz.build
    Writing ..\mozilla\gecko4\gfx\angle\targets\preprocessor\moz.build

Migrate required files
  Copying 1035/1035

Done
```

### Standalone builds

At this point, you can also build ANGLE standalone:
```
ninja -C out
```

update_angle.py configures some `gn args` to match what we build, including making it possible to build at all with is_clang = true.

If it doesn't build, message jgilbert!

### Handling `Unrecognized define`

In this case, we see a warning: `Unrecognized define: ANGLE_CAPTURE_ENABLED` from the `libGLESv2` target.
Open up `gfx/angle/update_angle.py` and locate `REGISTERED_DEFINES`.
Add `ANGLE_CAPTURE_ENABLED` with a `True` (meaning "use ANGLE's value for this define"). `False` would mean "ignore ANGLE's value, we'll define it ourselves if we want".

### Handling `Invalid include`

This particular update doesn't have this problem, but ANGLE upstream will sometimes forget to add new header files to their .gni build files. Since we try to copy only the files we know we need, we'll be missing any files not mentioned in the build files.

If you were to go to `angle-repo/src/libGLESv2.gni`, and comment out the line containing `passthroughdepth2d11ps.h`, `update_angle.py` will output the following:

```
C:\dev\angle>py ..\mozilla\gecko4\gfx\angle\update-angle.py origin
Importing graph
  ('gn', 'gen', 'out')
Done. Made 172 targets from 70 files in 3283ms
  ('gn', 'desc', '--format=json', 'out', '*')

Processing graph
  static_library //:translator
  static_library //:angle_common
  source_set //:angle_system_utils
  source_set //:angle_version
  action //:commit_id
  source_set //:includes
  source_set //:xxhash
  static_library //:preprocessor
  shared_library //:libEGL
  source_set //:libEGL_egl_loader
  shared_library //:libGLESv2
  source_set //:libANGLE
Warning in //:libANGLE: src\libANGLE\renderer\d3d\d3d11\Blit11.cpp: Invalid include: b'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h'
Traceback (most recent call last):
  File "..\mozilla\gecko4\gfx\angle\update-angle.py", line 308, in <module>
    libraries = gather_libraries(ROOTS, descs)
  File "..\mozilla\gecko4\gfx\angle\update-angle.py", line 303, in gather_libraries
    dag_traverse(roots, fn)
  File "..\mozilla\gecko4\gfx\angle\update-angle.py", line 134, in dag_traverse
    recurse(x)
  File "..\mozilla\gecko4\gfx\angle\update-angle.py", line 127, in recurse
    recurse(x)
  File "..\mozilla\gecko4\gfx\angle\update-angle.py", line 127, in recurse
    recurse(x)
  File "..\mozilla\gecko4\gfx\angle\update-angle.py", line 119, in recurse
    t = pre_recurse_func(key)
  File "..\mozilla\gecko4\gfx\angle\update-angle.py", line 297, in fn
    assert has_all_includes(target_name, descs), target_name
AssertionError: //:libANGLE
```

Don't panic, this is only fatal because if we don't fix it, our *Gecko* build will fail very eventually, and we'd rather fail-fast.
All we need to do is add the file to the proper .gni file, try `update_angle.py` again.

After we add all the missing includes, commit it and *upstream it immediately!*. (see "Upstreaming changes" below)

Here's an example: https://github.com/mozilla/angle/commit/ad5a21320c011cacda9ca4b0f48e1c779427e511

## 5. Record it into the mozilla/angle GitHub repo

To keep things easy for ourselves, push the firefox-N (here firefox-70) branch up to the `moz` remote, so we have easy access to it for next time.

## 6. Make the Gecko commits

Here's the bug for the Firefox 68 ANGLE update:
https://bugzilla.mozilla.org/show_bug.cgi?id=angle-68

ANGLE updates usually have 2 or 3 commits:

1. Update our updater (gfx/angle/* except for gfx/angle/checkout and gfx/angle/targets)
2. Vendored ANGLE update (from update_angle.py) (gfx/angle/[checkout,targets])
3. Mark new unexpected-fails and unexpected-passes (sometimes not needed)

Get review from jgilbert for all of these, though the review on the (huge) commit#2 will just be a sanity check. (We're not going to re-review all the upstream changes!)

You'll want to do a Try run to figure out if you need anything for commit#3, or if there's anything else wrong. While we don't use ANGLE's GLES driver for any platform but Windows, all platforms use the ANGLE shader translater for WebGL, so new and exciting build failures can happen on any platform.

"That's all!" :)

## Appendix: Upstreaming changes

ANGLE has an explainer, though it's a little out-of-date:
https://chromium.googlesource.com/angle/angle/+/master/doc/ContributingCode.md#getting-started-with-gerrit-for-angle
Use the depot_tools shell (thus depot_tools's git hooks) so that you can ignore the `Install the Gerrit commit_msg hook` section.

1. File a bug on Chromium's angleproject sub-tracker:
    - https://bugs.chromium.org/p/angleproject/issues/entry
2. Write the fix. Ideally add a test.
3. `git cl format`
4. Use the bug number from #1 in the commit body next to the `Change-Id` line: `Bug: angleproject:3330`
    - Example: https://github.com/mozilla/angle/commit/41ec3fab29e097be566490530590bc97ce235ab6
5. Setup Chromium commit access
6. `git cl upload`
7. Ask for review, generally from jmadill@chromium.org and geofflang@chromium.org.
8. Pass review and have them land the change! \o/
