[PATCH] cli: Add a simple "apitrace replay" sub-command.

José Fonseca jose.r.fonseca at gmail.com
Thu Sep 6 07:25:18 PDT 2012


Hi Carl,

Thanks for doing this. It's always been one of my pet annoyances too.

I think it is misleading to add a replay sub-command without handling
eglretrace/d3dretrace too -- it will confuse users. Supporting
eglretrace/d3dretrace is actually not hard: it simply requires opening
the trace with the parser, and take a look at the trace::Parser::api
member.

I don't think that "apitrace replay" should do any command parsing at
all. We should simply assume the last argument is a trace, probe its
type, and spew the appropriate retrace process.

Jose

On Mon, Aug 20, 2012 at 6:00 PM, Carl Worth <cworth at cworth.org> wrote:
> This calls out to glretrace in order to replay a trace. Currently it
> only supports the -w,--wait option, (and not yet any of the profiling
> support).
>
> With this command and the existing "apitrace dump-images", we're quite
> close to being able to relegate glretrace to an implementation detail
> used by the apitrace program, (such that soon, it won't be necessary
> to provide glretrace on the user's PATH).
> ---
>
> I think this is useful as-is. It will be better when it also provides
> support for all of the profiling modes of glretrace. I didn't do that
> here yet specifically because I would like some suggestions on what
> the long-format command-line options for selecting profiling should
> look like.
>
> Historically, glretrace had only ad-hoc command-line options. I
> recently converted it to using getopt, but just made long options
> matching the old names. It could use some actual long names and
> probably merged together somehow (--profile=cpu,cpu ?).
>
> Finally, I have imagined pulling trace replaying into process rather
> than invoking glretrace. But we're already invoking glretrace for
> "apitrace dump-images" so this is no worse. And this avoids incurring
> new link-time dependencies for the aptirace binary. I don't know where
> things stand as far as shared code for multi-target replaying, but I
> believe that work is currently taking place under glretrace.
>
>  cli/CMakeLists.txt |    1 +
>  cli/cli.hpp        |    1 +
>  cli/cli_main.cpp   |    1 +
>  cli/cli_replay.cpp |  125 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 128 insertions(+)
>  create mode 100644 cli/cli_replay.cpp
>
> diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
> index a03dd27..1a3e7ec 100644
> --- a/cli/CMakeLists.txt
> +++ b/cli/CMakeLists.txt
> @@ -8,6 +8,7 @@ add_executable (apitrace
>      cli_pager.cpp
>      cli_pickle.cpp
>      cli_repack.cpp
> +    cli_replay.cpp
>      cli_trace.cpp
>      cli_trim.cpp
>      trace_analyzer.cpp
> diff --git a/cli/cli.hpp b/cli/cli.hpp
> index 4f3e2b9..c701f52 100644
> --- a/cli/cli.hpp
> +++ b/cli/cli.hpp
> @@ -47,6 +47,7 @@ extern const Command dump_command;
>  extern const Command dump_images_command;
>  extern const Command pickle_command;
>  extern const Command repack_command;
> +extern const Command replay_command;
>  extern const Command trace_command;
>  extern const Command trim_command;
>
> diff --git a/cli/cli_main.cpp b/cli/cli_main.cpp
> index 8c619ba..6682717 100644
> --- a/cli/cli_main.cpp
> +++ b/cli/cli_main.cpp
> @@ -73,6 +73,7 @@ static const Command * commands[] = {
>      &dump_images_command,
>      &pickle_command,
>      &repack_command,
> +    &replay_command,
>      &trace_command,
>      &trim_command,
>      &help_command
> diff --git a/cli/cli_replay.cpp b/cli/cli_replay.cpp
> new file mode 100644
> index 0000000..aaa68e2
> --- /dev/null
> +++ b/cli/cli_replay.cpp
> @@ -0,0 +1,125 @@
> +/*********************************************************************
> + *
> + * Copyright 2011 Jose Fonseca
> + * Copyright 2012 Intel Corporation
> + * All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person
> + * obtaining a copy of this software and associated documentation
> + * files (the "Software"), to deal in the Software without
> + * restriction, including without limitation the rights to use, copy,
> + * modify, merge, publish, distribute, sublicense, and/or sell copies
> + * of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be
> + * included in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + *
> + *********************************************************************/
> +
> +#include <string.h>
> +#include <limits.h> // for CHAR_MAX
> +#include <getopt.h>
> +#include <iostream>
> +
> +#include "cli.hpp"
> +
> +#include "os_string.hpp"
> +#include "os_process.hpp"
> +
> +#include "trace_resource.hpp"
> +
> +static const char *synopsis = "Replay a trace.";
> +
> +static void
> +usage(void)
> +{
> +    std::cout << "usage apitrace replay [OPTIONS] TRACE_FILE\n"
> +              << synopsis << "\n"
> +           "\n"
> +           "    -h, --help             Show this help message and exit\n"
> +           "    -w, --wait             Wait for user termination after the last frame\n"
> +           "\n";
> +}
> +
> +const static char *
> +shortOptions = "hw";
> +
> +const static struct option
> +longOptions[] = {
> +    {"help", no_argument, 0, 'h'},
> +    {"wait", required_argument, 0, 'w'},
> +    {0, 0, 0, 0}
> +};
> +
> +static int
> +command(int argc, char *argv[])
> +{
> +    bool wait = false;
> +    const char *filename;
> +
> +    int opt;
> +    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
> +        switch (opt) {
> +        case 'h':
> +            usage();
> +            return 0;
> +        case 'w':
> +            wait = true;
> +            break;
> +        default:
> +            std::cerr << "error: unexpected option `" << opt << "`\n";
> +            usage();
> +            return 1;
> +        }
> +    }
> +
> +    if (optind >= argc) {
> +        std::cerr << "error: apitrace replay requires a trace file as an argument.\n";
> +        usage();
> +        return 1;
> +    }
> +
> +    if (optind < argc - 1) {
> +        std::cerr << "error: apitrace replay can accept only a single trace file argument.\n";
> +        usage();
> +        return 1;
> +    }
> +
> +    filename = argv[optind];
> +
> +    /* FIXME: It would be cleaner to pull the replaying of the trace
> +     * in-process here and generate the images directly. But that
> +     * pulls in a non-trivial amount of the existing 'retrace' code,
> +     * along with dependencies on GL, etc.
> +     */
> +    std::vector<const char *> command;
> +
> +    os::String glretracePath = trace::findProgram("glretrace");
> +    command.push_back(glretracePath);
> +
> +    if (wait) {
> +        command.push_back("--wait");
> +    }
> +
> +    command.push_back(filename);
> +    command.push_back(NULL);
> +
> +    return os::execute((char * const *)&command[0]);
> +}
> +
> +const Command replay_command = {
> +    "replay",
> +    synopsis,
> +    usage,
> +    command
> +};
> --
> 1.7.10
>
> _______________________________________________
> apitrace mailing list
> apitrace at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/apitrace


More information about the apitrace mailing list