ANGLE OpenGL Frame Capture and Replay
ANGLE currently supports a limited OpenGL capture and replay framework.
Limitations:
GLES capture has many unimplemented functions.
EGL capture and replay is not yet supported.
Mid-execution capture is supported with the Vulkan back-end.
Mid-execution capture has many unimplemented features.
Capture and replay is currently only tested on desktop platforms.
Binary replay is unimplemented. CPP replay is supported.
Capturing and replaying an application
To build ANGLE with capture and replay enabled update your GN args:
Once built ANGLE will capture the OpenGL ES calls to CPP replay files. By default the replay will be stored in the current working directory. The capture files will be named according to the pattern angle_capture_context{id}_frame{n}.cpp
. Each GL Context currently has its own replay sources. ANGLE will write out data binary blobs for large Texture or Buffer contents to angle_capture_context{id}_frame{n}.angledata
. Replay programs must be able to load data from the corresponding angledata
files.
Controlling Frame Capture
Some simple environment variables control frame capture:
ANGLE_CAPTURE_ENABLED
:Set to
0
to disable capture entirely. Default is1
.
ANGLE_CAPTURE_COMPRESSION
:Set to
0
to disable capture compression. Default is1
.
ANGLE_CAPTURE_OUT_DIR=<path>
:Can specify an alternate replay output directory.
Example:
ANGLE_CAPTURE_OUT_DIR=samples/capture_replay
. Default is the CWD.
ANGLE_CAPTURE_FRAME_START=<n>
:Uses mid-execution capture to write "Setup" functions that starts a Context at frame
n
.Example:
ANGLE_CAPTURE_FRAME_START=2
. Default is0
.
ANGLE_CAPTURE_FRAME_END=<n>
:By default ANGLE will capture the first ten frames. This variable can override the default.
Example:
ANGLE_CAPTURE_FRAME_END=4
. Default is10
.
ANGLE_CAPTURE_LABEL=<label>
:When specified, files and functions will be labeled uniquely.
Example:
ANGLE_CAPTURE_LABEL=foo
Results in filenames like this:
Functions wrapped in namespaces like this:
For use like this:
ANGLE_CAPTURE_SERIALIZE_STATE
:Set to
1
to enable GL state serialization. Default is0
.
A good way to test out the capture is to use environment variables in conjunction with the sample template. For example:
Running a CPP replay
To run a CPP replay you can use a template located in samples/capture_replay. First run your capture and ensure all capture files are written to samples/capture_replay
. You can conveniently use ANGLE_CAPTURE_OUT_DIR
. Then enable the capture_replay_sample
via gn args
:
See samples/BUILD.gn for details. Then build and run your replay sample:
Note that we specify ANGLE_CAPTURE_ENABLED=0
to prevent re-capturing when running the replay.
Capturing an Android application
In order to capture on Android, the following additional steps must be taken. These steps presume you've built and installed the ANGLE APK with capture enabled, and selected ANGLE as the GLES driver for your application.
Create the output directory
Determine your package name:
Then create an output directory that it can write to:
Set properties to use for environment variable
On Android, it is difficult to set an environment variable before starting native code. To work around this, ANGLE will read debug system properties before starting the capture and use them to prime environment variables used by the capture code.
Note: Mid-execution capture doesn't work for Android just yet, so frame_start must be zero, which is the default. This it is sufficient to only set the end frame.
There are other properties that can be set that match 1:1 with the env vars, but they are not required for capture:
Run the application, then pull the files to the capture_replay directory
Update your GN args to specifiy which context will be replayed.
By default Context ID 1 will be replayed. On Android, Context ID 2 is more typical, some apps we've run go as high as ID 6. Note: this solution is temporary until EGL capture is in place.
Replay the capture on desktop
Until we have samples building for Android, the replay sample must be run on desktop. We will also be plumbing replay files into perf and correctness tests which will run on Android.
Starting capture at an arbitrary frame
In some scenarios, you don't know which frame you want to start on. You'll only know when target content is being rendered. For that we've added a trigger that can allow starting the capture at any time.
To use it, set the following environment variable, in addition to all the setup steps above. Set the trigger value equal to the number of frames you'd like to capture.
When this value is set, ANGLE_CAPTURE_FRAME_START
and ANGLE_CAPTURE_FRAME_END
will be ignored.
While your content is rendering, wait until you arrive at the scene you'd like to capture. Then set the value back to zero:
ANGLE will detect this change and start recording the requested number of frames.
Testing
Regression Testing Architecture
The python script uses the job queue pattern. We spawn n-1 independent worker processes, where n is the value returned by multiprocessing.cpu_count(). Whenever a worker process finishes a job and becomes available, it grabs the next job from a shared job queue and runs that job on its CPU core. When there are no more jobs in the queue, the worker processes terminate and the main process reports results.
Job unit
A job unit is a test batch. Each test has to go through 3 stages: capture run, replay build, and replay run. The test batch batches the replay build stage of multiple tests together, and the replay run stage of multiple tests together.
Running tests
From the command line, navigate to the ANGLE root folder angle then run the command below:
--use-goma
to turn on/off building with goma--gtest_filter
to run only specific tests--keep-temp-files
to keep the trace files--output-to-file
to write the log to results.txt at src/tests/capture_replay_tests folder.--batch-count
to set the number of tests in a batch. More tests in a batch means that the tests will finish faster, but also means a lower level of granularity. All command line arguments can be found at the top of the python script.