• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ANGLE OpenGL Frame Capture and Replay
2
3ANGLE currently supports a limited OpenGL capture and replay framework.
4
5Limitations:
6
7 * GLES capture has many unimplemented functions.
8 * EGL capture and replay is not yet supported.
9 * Mid-execution capture is supported with the Vulkan back-end.
10 * Mid-execution capture has many unimplemented features.
11 * Capture and replay is currently only tested on desktop platforms.
12 * Binary replay is unimplemented. CPP replay is supported.
13
14## Capturing and replaying an application
15
16To build ANGLE with capture and replay enabled update your GN args:
17
18```
19angle_with_capture_by_default = true
20```
21
22Once built ANGLE will capture the OpenGL ES calls to CPP replay files. By default the replay will be
23stored in the current working directory. The capture files will be named according to the pattern
24`angle_capture_context{id}_frame{n}.cpp`. Each GL Context currently has its own replay sources.
25ANGLE will write out data binary blobs for large Texture or Buffer contents to
26`angle_capture_context{id}_frame{n}.angledata`. Replay programs must be able to load data from the
27corresponding `angledata` files.
28
29## Controlling Frame Capture
30
31Some simple environment variables control frame capture:
32
33 * `ANGLE_CAPTURE_ENABLED`:
34   * Set to `0` to disable capture entirely. Default is `1`.
35 * `ANGLE_CAPTURE_COMPRESSION`:
36   * Set to `0` to disable capture compression. Default is `1`.
37 * `ANGLE_CAPTURE_OUT_DIR=<path>`:
38   * Can specify an alternate replay output directory.
39   * Example: `ANGLE_CAPTURE_OUT_DIR=samples/capture_replay`. Default is the CWD.
40 * `ANGLE_CAPTURE_FRAME_START=<n>`:
41   * Uses mid-execution capture to write "Setup" functions that starts a Context at frame `n`.
42   * Example: `ANGLE_CAPTURE_FRAME_START=2`. Default is `0`.
43 * `ANGLE_CAPTURE_FRAME_END=<n>`:
44   * By default ANGLE will capture the first ten frames. This variable can override the default.
45   * Example: `ANGLE_CAPTURE_FRAME_END=4`. Default is `10`.
46 * `ANGLE_CAPTURE_LABEL=<label>`:
47   * When specified, files and functions will be labeled uniquely.
48   * Example: `ANGLE_CAPTURE_LABEL=foo`
49     * Results in filenames like this:
50       ```
51       foo_capture_context1.cpp
52       foo_capture_context1.h
53       foo_capture_context1_files.txt
54       foo_capture_context1_frame000.angledata
55       foo_capture_context1_frame000.cpp
56       foo_capture_context1_frame001.angledata
57       foo_capture_context1_frame001.cpp
58       ...
59       ```
60     * Functions wrapped in namespaces like this:
61       ```
62       namespace foo
63       {
64           void ReplayContext1Frame0();
65           void ReplayContext1Frame1();
66       }
67       ```
68     * For use like this:
69       ```
70       foo::SetupContext1Replay();
71       for (...)
72       {
73           foo::ReplayContext1Frame(i);
74       }
75       ```
76 * `ANGLE_CAPTURE_SERIALIZE_STATE`:
77   * Set to `1` to enable GL state serialization. Default is `0`.
78
79A good way to test out the capture is to use environment variables in conjunction with the sample
80template. For example:
81
82```
83$ ANGLE_CAPTURE_FRAME_END=4 ANGLE_CAPTURE_OUT_DIR=samples/capture_replay out/Debug/simple_texture_2d
84```
85
86## Running a CPP replay
87
88To run a CPP replay you can use a template located in
89[samples/capture_replay](../samples/capture_replay). First run your capture and ensure all capture
90files are written to `samples/capture_replay`. You can conveniently use `ANGLE_CAPTURE_OUT_DIR`.
91Then enable the `capture_replay_sample` via `gn args`:
92
93```
94angle_build_capture_replay_sample = true
95```
96
97See [samples/BUILD.gn](../samples/BUILD.gn) for details. Then build and run your replay sample:
98
99```
100$ autoninja -C out/Debug capture_replay_sample
101$ ANGLE_CAPTURE_ENABLED=0 out/Debug/capture_replay_sample
102```
103
104Note that we specify `ANGLE_CAPTURE_ENABLED=0` to prevent re-capturing when running the replay.
105
106## Capturing an Android application
107
108In order to capture on Android, the following additional steps must be taken. These steps
109presume you've built and installed the ANGLE APK with capture enabled, and selected ANGLE
110as the GLES driver for your application.
111
1121. Create the output directory
113
114    Determine your package name:
115    ```
116    export PACKAGE_NAME com.android.gl2jni
117    ```
118    Then create an output directory that it can write to:
119    ```
120    $ adb shell mkdir -p /sdcard/Android/data/$PACKAGE_NAME/angle_capture
121    ```
122
1232. Set properties to use for environment variable
124
125    On Android, it is difficult to set an environment variable before starting native code.
126    To work around this, ANGLE will read debug system properties before starting the capture
127    and use them to prime environment variables used by the capture code.
128
129    Note: Mid-execution capture doesn't work for Android just yet, so frame_start must be
130    zero, which is the default. This it is sufficient to only set the end frame.
131    ```
132    $ adb shell setprop debug.angle.capture.frame_end 200
133    ```
134
135    There are other properties that can be set that match 1:1 with the env vars, but
136    they are not required for capture:
137    ```
138    # Optional
139    $ adb shell setprop debug.angle.capture.enabled 0
140    $ adb shell setprop debug.angle.capture.out_dir foo
141    $ adb shell setprop debug.angle.capture.frame_start 0
142    $ adb shell setprop debug.angle.capture.label bar
143    ```
144
1453.  Run the application, then pull the files to the capture_replay directory
146    ```
147    $ cd samples/capture_replay
148    $ adb pull /sdcard/Android/data/$PACKAGE_NAME/angle_capture replay_files
149    $ cp replay_files/* .
150    ```
151
1524. Update your GN args to specifiy which context will be replayed.
153
154    By default Context ID 1 will be replayed. On Android, Context ID 2 is more typical, some apps
155    we've run go as high as ID 6.
156    Note: this solution is temporary until EGL capture is in place.
157    ```
158    angle_capture_replay_sample_context_id = 2
159    ```
160
1615. Replay the capture on desktop
162
163    Until we have samples building for Android, the replay sample must be run on desktop.
164    We will also be plumbing replay files into perf and correctness tests which will run on Android.
165    ```
166    $ autoninja -C out/Release capture_replay_sample
167    $ out/Release/capture_replay_sample
168    ```
169
170### Starting capture at an arbitrary frame
171In some scenarios, you don't know which frame you want to start on. You'll only know when target
172content is being rendered.  For that we've added a trigger that can allow starting the capture at
173any time.
174
175To use it, set the following environment variable, in addition to all the setup steps above. Set
176the trigger value equal to the number of frames you'd like to capture.
177```
178adb shell setprop debug.angle.capture.trigger 20
179```
180When this value is set, `ANGLE_CAPTURE_FRAME_START` and `ANGLE_CAPTURE_FRAME_END` will be ignored.
181
182While your content is rendering, wait until you arrive at the scene you'd like to capture. Then
183set the value back to zero:
184```
185adb shell setprop debug.angle.capture.trigger 0
186```
187ANGLE will detect this change and start recording the requested number of frames.
188
189## Testing
190
191### Regression Testing Architecture
192The [python script][link_to_python_script] uses the job queue pattern. We spawn n-1 independent
193worker processes, where n is the value returned by multiprocessing.cpu_count(). Whenever a worker
194process finishes a job and becomes available, it grabs the next job from a shared job queue and
195runs that job on its CPU core. When there are no more jobs in the queue, the worker processes
196terminate and the main process reports results.
197
198![Point-in-time snapshot of the job queue](img/RegressionTestingArchitecture.png)
199
200### Job unit
201A job unit is a test batch. Each test has to go through 3 stages: capture run, replay build, and
202replay run. The test batch batches the replay build stage of multiple tests together, and the
203replay run stage of multiple tests together.
204
205![A test batch as a job unit](img/JobUnit.png)
206
207### Running tests
208From the command line, navigate to the ANGLE root folder [angle][angle_folder] then run the
209command below:
210```
211python3 src/tests/capture_replay_tests.py --use-goma --gtest_filter=*/ES2_Vulkan --keep-temp-files --output-to-file --batch-count=8
212```
213
214* `--use-goma` to turn on/off building with goma
215* `--gtest_filter` to run only specific tests
216* `--keep-temp-files` to keep the trace files
217* `--output-to-file` to write the log to results.txt at
218 [src/tests/capture_replay_tests][capture_replay_test_folder] folder.
219* `--batch-count` to set the number of tests in a batch. More tests in a batch means that
220the tests will finish faster, but also means a lower level of granularity.
221All command line arguments can be found at the top of the [python script][link_to_python_script].
222
223[angle_folder]: ../
224[capture_replay_test_folder]: ../src/tests/capture_replay_tests/
225[link_to_python_script]: ../src/tests/capture_replay_tests.py
226
227
228