Edit

kc3-lang/angle/doc/CaptureAndReplay.md

Branch :

  • Show log

    Commit

  • Author : Cody Northrop
    Date : 2020-08-10 09:53:54
    Hash : a7cbb3f0
    Message : Capture/Replay: Allow starting capture at an unknown frame This CL adds a new way to set the start frame of a capture. It adds a new environment variable called ANGLE_CAPTURE_TRIGGER that, when set, will be used instead of frame start and end. By setting ANGLE_CAPTURE_TRIGGER to a non-zero value, ANGLE will capture that many frames when the value changes. For example, on Android, we can set it with: adb shell setprop debug.angle.capture.trigger 20 When we reach the target content, set the value back to zero: adb shell setprop debug.angle.capture.trigger 0 and ANGLE will start capturing 20 frames. Currently only hooked up for Android, but should be possible to support on other platforms. Test: Capture application frames using trigger Bug: angleproject:4949 Change-Id: I469ef5c48feb78c85b8cda2fefd5df59e495bbe2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2347858 Commit-Queue: Cody Northrop <cnorthrop@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Manh Nguyen <nguyenmh@google.com>

  • doc/CaptureAndReplay.md
  • # 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:
    
    ```
    angle_with_capture_by_default = true
    ```
    
    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 is `1`.
     * `ANGLE_CAPTURE_COMPRESSION`:
       * Set to `0` to disable capture compression. Default is `1`.
     * `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 is `0`.
     * `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 is `10`.
     * `ANGLE_CAPTURE_LABEL=<label>`:
       * When specified, files and functions will be labeled uniquely.
       * Example: `ANGLE_CAPTURE_LABEL=foo`
         * Results in filenames like this:
           ```
           foo_capture_context1.cpp
           foo_capture_context1.h
           foo_capture_context1_files.txt
           foo_capture_context1_frame000.angledata
           foo_capture_context1_frame000.cpp
           foo_capture_context1_frame001.angledata
           foo_capture_context1_frame001.cpp
           ...
           ```
         * Functions wrapped in namespaces like this:
           ```
           namespace foo
           {
               void ReplayContext1Frame0();
               void ReplayContext1Frame1();
           }
           ```
         * For use like this:
           ```
           foo::SetupContext1Replay();
           for (...)
           {
               foo::ReplayContext1Frame(i);
           }
           ```
     * `ANGLE_CAPTURE_SERIALIZE_STATE`:
       * Set to `1` to enable GL state serialization. Default is `0`.
    
    A good way to test out the capture is to use environment variables in conjunction with the sample
    template. For example:
    
    ```
    $ ANGLE_CAPTURE_FRAME_END=4 ANGLE_CAPTURE_OUT_DIR=samples/capture_replay out/Debug/simple_texture_2d
    ```
    
    ## Running a CPP replay
    
    To run a CPP replay you can use a template located in
    [samples/capture_replay](../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`:
    
    ```
    angle_build_capture_replay_sample = true
    ```
    
    See [samples/BUILD.gn](../samples/BUILD.gn) for details. Then build and run your replay sample:
    
    ```
    $ autoninja -C out/Debug capture_replay_sample
    $ ANGLE_CAPTURE_ENABLED=0 out/Debug/capture_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.
    
    1. Create the output directory
    
        Determine your package name:
        ```
        export PACKAGE_NAME com.android.gl2jni
        ```
        Then create an output directory that it can write to:
        ```
        $ adb shell mkdir -p /sdcard/Android/data/$PACKAGE_NAME/angle_capture
        ```
    
    2. 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.
        ```
        $ adb shell setprop debug.angle.capture.frame_end 200
        ```
    
        There are other properties that can be set that match 1:1 with the env vars, but
        they are not required for capture:
        ```
        # Optional
        $ adb shell setprop debug.angle.capture.enabled 0
        $ adb shell setprop debug.angle.capture.out_dir foo
        $ adb shell setprop debug.angle.capture.frame_start 0
        $ adb shell setprop debug.angle.capture.label bar
        ```
    
    3.  Run the application, then pull the files to the capture_replay directory
        ```
        $ cd samples/capture_replay
        $ adb pull /sdcard/Android/data/$PACKAGE_NAME/angle_capture replay_files
        $ cp replay_files/* .
        ```
    
    4. 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.
        ```
        angle_capture_replay_sample_context_id = 2
        ```
    
    5. 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.
        ```
        $ autoninja -C out/Release capture_replay_sample
        $ out/Release/capture_replay_sample
        ```
    
    ### 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.
    ```
    adb shell setprop debug.angle.capture.trigger 20
    ```
    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:
    ```
    adb shell setprop debug.angle.capture.trigger 0
    ```
    ANGLE will detect this change and start recording the requested number of frames.
    
    ## Testing
    
    ### Regression Testing Architecture
    The [python script][link_to_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.
    
    ![Point-in-time snapshot of the job queue](img/RegressionTestingArchitecture.png)
    
    ### 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.
    
    ![A test batch as a job unit](img/JobUnit.png)
    
    ### Running tests
    From the command line, navigate to the ANGLE root folder [angle][angle_folder] then run the
    command below:
    ```
    python3 src/tests/capture_replay_tests.py --use-goma --gtest_filter=*/ES2_Vulkan --keep-temp-files --output-to-file --batch-count=8
    ```
    
    * `--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][capture_replay_test_folder] 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][link_to_python_script].
    
    [angle_folder]: ../
    [capture_replay_test_folder]: ../src/tests/capture_replay_tests/
    [link_to_python_script]: ../src/tests/capture_replay_tests.py