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