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 77A good way to test out the capture is to use environment variables in conjunction with the sample 78template. For example: 79 80``` 81$ ANGLE_CAPTURE_FRAME_END=4 ANGLE_CAPTURE_OUT_DIR=samples/capture_replay out/Debug/simple_texture_2d 82``` 83 84## Running a CPP replay 85 86To run a CPP replay you can use a template located in 87[samples/capture_replay](../samples/capture_replay). First run your capture and ensure all capture 88files are written to `samples/capture_replay`. You can conveniently use `ANGLE_CAPTURE_OUT_DIR`. 89Then enable the `capture_replay_sample` via `gn args`: 90 91``` 92angle_build_capture_replay_sample = true 93``` 94 95See [samples/BUILD.gn](../samples/BUILD.gn) for details. Then build and run your replay sample: 96 97``` 98$ autoninja -C out/Debug capture_replay_sample 99$ ANGLE_CAPTURE_ENABLED=0 out/Debug/capture_replay_sample 100``` 101 102Note that we specify `ANGLE_CAPTURE_ENABLED=0` to prevent re-capturing when running the replay. 103 104## Capturing an Android application 105 106In order to capture on Android, the following additional steps must be taken. These steps 107presume you've built and installed the ANGLE APK with capture enabled, and selected ANGLE 108as the GLES driver for your application. 109 1101. Create the output directory 111 112 Determine your package name: 113 ``` 114 export PACKAGE_NAME com.android.gl2jni 115 ``` 116 Then create an output directory that it can write to: 117 ``` 118 $ adb shell mkdir -p /sdcard/Android/data/$PACKAGE_NAME/angle_capture 119 ``` 120 1212. Set properties to use for environment variable 122 123 On Android, it is difficult to set an environment variable before starting native code. 124 To work around this, ANGLE will read debug system properties before starting the capture 125 and use them to prime environment variables used by the capture code. 126 127 Note: Mid-execution capture doesn't work for Android just yet, so frame_start must be 128 zero, which is the default. This it is sufficient to only set the end frame. 129 ``` 130 $ adb shell setprop debug.angle.capture.frame_end 200 131 ``` 132 133 There are other properties that can be set that match 1:1 with the env vars, but 134 they are not required for capture: 135 ``` 136 # Optional 137 $ adb shell setprop debug.angle.capture.enabled 0 138 $ adb shell setprop debug.angle.capture.out_dir foo 139 $ adb shell setprop debug.angle.capture.frame_start 0 140 $ adb shell setprop debug.angle.capture.label bar 141 ``` 142 1433. Run the application, then pull the files to the capture_replay directory 144 ``` 145 $ cd samples/capture_replay 146 $ adb pull /sdcard/Android/data/$PACKAGE_NAME/angle_capture replay_files 147 $ cp replay_files/* . 148 ``` 149 1504. Update your GN args to specifiy which context will be replayed. 151 152 By default Context ID 1 will be replayed. On Android, Context ID 2 is more typical, some apps 153 we've run go as high as ID 6. 154 Note: this solution is temporary until EGL capture is in place. 155 ``` 156 angle_capture_replay_sample_context_id = 2 157 ``` 158 1595. Replay the capture on desktop 160 161 Until we have samples building for Android, the replay sample must be run on desktop. 162 We will also be plumbing replay files into perf and correctness tests which will run on Android. 163 ``` 164 $ autoninja -C out/Release capture_replay_sample 165 $ out/Release/capture_replay_sample 166 ```