# 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/