How to Run a Perfetto Trace on Oculus Quest or Quest 2

Oculus Developer Blog
|
Posted by James Leitch, Software Engineer, Facebook
|
April 21, 2021
|
Share
Quest
Perfetto

Perfetto is an Android system-wide profiling tool (as of Android 10) that provides information on system events such as scheduling activity, in addition to app-level instrumentation for apps that integrate with Perfetto or ATrace. It is a replacement for systrace that supports a larger selection of events, longer traces, and offers better performance, in addition to adding support for counters. For more information on Perfetto, check out https://perfetto.dev/.

With our v27 OS update, we’ve enabled Perfetto by default on both Oculus Quest and Quest 2 when Developer Mode is turned on. The v27 OS update also shipped with both VrApi and GPU emitting metrics to Perfetto which can be enabled on your traces.

Quest developers can use Perfetto to profile their apps with additional context of the overall system it is executing on. Over time, we plan to expose more Oculus-specific data that will be available via Perfetto.

Emitting Data from your App

In order for events from your app to show up in a Perfetto trace, your app must be annotated either with Perfetto TrackEvents or with ATrace. If you need to annotate your app, we recommend choosing Perfetto TrackEvents as the more performant option. Make sure your Perfetto config (covered below) has the appropriate TrackEvent or ATrace data source.

For instructions on adding Perfetto TrackEvents, start here.

Perfetto Setup

To record a new trace, you'll first need to set up a few files. You will need to create a working directory. This is where you'll create a Perfetto config and where the trace will be written to. (We show a setup with a Python script below, but you can also use the Git Bash / WSL / Cygwin script provided at the end of this post.)

  1. Create a working directory that will contain the Perfetto configuration, scripts, and trace output

    • For the purposes of this post, we'll call the directory perfetto_traces, but you can name it whatever you want.

  2. Create your Perfetto configuration (config.txt)

    • Create a text file at perfetto_traces/config.txt.

    • Populate the file with your trace configuration. The best starting place is to use the Web UI (https://ui.perfetto.dev/) to generate a Perfetto configuration, and then tweak it from there.

      • In the Web UI, click Record new trace.

      • Select the various data sources you'd like to record.

      • Copy the config presented in the Trace command section. Make sure to only copy the configuration, not the entire command (see selected text).

    NOTE: Both Perfetto app instrumentation and VrApi/GPU metrics are part of Perfetto TrackEvents, which is a data source the Web UI does not support generating configurations for. In order to record these, add the following to your config:

    data_sources: {
        config {
            name: "track_event"
        }
    }

    NOTE: GPU metrics require that adb shell ovrgpuprofiler -r is running in the background for the duration of the trace.

    Example Config File

    Below is an example config file that will record VrApi and GPU metrics, as well as any other Perfetto TrackEvents being emitted on the device.

    buffers: {
        size_kb: 63488
        fill_policy: DISCARD
    }
    buffers: {
        size_kb: 2048
        fill_policy: DISCARD
    }
    data_sources: {
        config {
            name: "linux.process_stats"
            target_buffer: 1
            process_stats_config {
                 scan_all_processes_on_start: true
             }
         }
    }
    data_sources: {
        config: {
           name: "track_event"
         }
    }
    duration_ms: 10000

  3. Create the Python script to record the trace (perfetto.py).

    • Create a text file at perfetto_traces/perfetto.py.

    • Paste the following into the file:

    #!/usr/bin/env python3

    import os
    import subprocess
    import sys

    dir = os.path.dirname(os.path.realpath(__file__))
    config_file = os.path.join(dir, "config.txt")
    output_file = os.path.join(dir, "trace.pftrace")

    if not os.path.isfile(config_file):
        print("Config file does not exist: " + config_file)
        sys.exit(1)
    config = open(config_file, 'r')

    subprocess.run(["adb", "shell", "rm", "-f", "/data/misc/perfetto-traces/trace"], check=False)
    subprocess.run(["adb", "shell", "perfetto", "-c", "-", "--txt", "-o",
    "/data/misc/perfetto-traces/trace"], stdin=config, check=True)
    if os.path.isfile(output_file):
        os.remove(output_file)
    subprocess.run(["adb", "pull", "/data/misc/perfetto-traces/trace", output_file], check=True)

  4. (Optional) Create a Custom Command in Oculus Developer Hub (ODH) to run the script.

    • Make sure your Quest is connected to ODH.

    • Under the My Device tab, click + Create Command.

      • Name: Perfetto

      • Command: python3 <absolute path>/perfetto_traces/perfetto.py

      • Display command output in a new window: Checked

    • For more information on ODH Customer Commands, click here.

Recording and Viewing Traces

To Record a Trace

  • Make sure your Quest is connected to your PC.

  • Check that your Quest is listed when you run the command adb devices.

  • Open your app and get into the scenario you want to profile.

  • Run perfetto.py using Python3 - This will copy your config to the device, run Perfetto, and copy the recorded trace back to the directory.

    • Alternatively, if using ODH, run the Perfetto Custom Command in ODH

  • Your recorded trace will be saved to perfetto_traces/trace.pftrace.

To View a Trace

  • Open the Web UI: https://ui.perfetto.dev/

  • Click `Open trace file` and select the trace you just recorded, located at perfetto_traces/trace.pftrace.

TIP: You can pin counters to the top of the Timeline view by clicking the star next to the counter name.

Git Bash / WSL / Cygwin Script

If you prefer Git Bash / WSL / Cygwin in your development, use the script below rather than the python script provided above.

  • Create a text file at perfetto_traces/perfetto.sh.

  • Paste the following into the file:

#!/bin/bash
set -euo pipefail
export MSYS_NO_PATHCONV=1
export MSYS2_ARG_CONV_EXCL="*"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

CONFIG_FILE="${DIR}/config.txt"
OUTPUT_FILE="${DIR}/trace.pftrace"
if [ ! -f "${CONFIG_FILE}" ]; then
    echo "Config file does not exist: ${CONFIG_FILE}"
    exit 1
fi
if [ -x "$(command -v cygpath)" ]; then
    OUTPUT_FILE=$(cygpath -w "${OUTPUT_FILE}")
fi
if [ -x "$(command -v wslpath)" ]; then
    OUTPUT_FILE=$(wslpath -w "${OUTPUT_FILE}")
fi
adb.exe shell rm -f /data/misc/perfetto-traces/trace || true
adb.exe shell perfetto -c - --txt -o /data/misc/perfetto-traces/trace
<"${CONFIG_FILE}"
rm -f "${OUTPUT_FILE}" || true
adb.exe pull /data/misc/perfetto-traces/trace "${OUTPUT_FILE}"

If you have questions, comments or feedback, let us know in the comments below or in the Developer Forums.