diff options
author | Mark Janes <mark.a.janes@intel.com> | 2016-11-11 13:17:18 -0800 |
---|---|---|
committer | Mark Janes <mark.a.janes@intel.com> | 2017-06-19 14:04:49 -0700 |
commit | 63a3dbaf180a6fc6917df499fccf3f05c0babd31 (patch) | |
tree | 98eb3096c5e3dc7412547861243ffe0048ff549c | |
parent | 3c48faa1df3d7dd29341986cbff588e550c78772 (diff) |
Implement framestat
Framestat loops over specified frames, providing frame time in
milliseconds.
-rw-r--r-- | retrace/daemon/CMakeLists.txt | 1 | ||||
-rw-r--r-- | retrace/daemon/framestat/CMakeLists.txt | 41 | ||||
-rw-r--r-- | retrace/daemon/framestat/glframe_loop.cpp | 154 | ||||
-rw-r--r-- | retrace/daemon/framestat/glframe_loop.hpp | 63 | ||||
-rw-r--r-- | retrace/daemon/framestat/main.cpp | 89 |
5 files changed, 348 insertions, 0 deletions
diff --git a/retrace/daemon/CMakeLists.txt b/retrace/daemon/CMakeLists.txt index 6a58ea27..82ebae4a 100644 --- a/retrace/daemon/CMakeLists.txt +++ b/retrace/daemon/CMakeLists.txt @@ -86,6 +86,7 @@ if (NOT WIN32) Lint( RETRACE_SOURCES ) endif() +add_subdirectory (framestat) add_subdirectory (test) add_subdirectory (ui) add_subdirectory (server) diff --git a/retrace/daemon/framestat/CMakeLists.txt b/retrace/daemon/framestat/CMakeLists.txt new file mode 100644 index 00000000..1cc295fc --- /dev/null +++ b/retrace/daemon/framestat/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 2.8) + +include_directories ( + ) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + + +set (FRAMESTAT_SRC + glframe_loop.cpp + glframe_loop.hpp + ../glretrace_globals.cpp + main.cpp + ) + +add_executable(framestat + ${FRAMESTAT_SRC} +) + +if (WIN32) + set (GL_LIB opengl32) + set (THREAD_LIB Ws2_32) +else() + set (GL_LIB GL) + set (THREAD_LIB pthread dl) +endif() + +target_link_libraries(framestat + glretrace_common + glhelpers + glproc_gl + ${GL_LIB} + ${X11_X11_LIB} + ${THREAD_LIB} +) + +install (TARGETS framestat RUNTIME DESTINATION bin) + +if (NOT WIN32) + Lint(FRAMESTAT_SRC) +endif() diff --git a/retrace/daemon/framestat/glframe_loop.cpp b/retrace/daemon/framestat/glframe_loop.cpp new file mode 100644 index 00000000..6fa0f126 --- /dev/null +++ b/retrace/daemon/framestat/glframe_loop.cpp @@ -0,0 +1,154 @@ +/************************************************************************** + * + * Copyright 2016 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. + * + * Authors: + * Mark Janes <mark.a.janes@intel.com> + **************************************************************************/ + +#include "glframe_loop.hpp" + +#include <GLES2/gl2.h> + +#include <sstream> +#include <string> +#include <vector> + +#include "glretrace.hpp" +#include "retrace.hpp" + +using glretrace::FrameLoop; + +using retrace::parser; +using trace::Call; + +extern retrace::Retracer retracer; + +FrameLoop::FrameLoop(const std::string filepath, + const std::string out_path) + : m_of(), m_o(NULL), + m_current_frame(1) { + if (out_path.size()) { + m_of.open(out_path); + m_o = new JSONWriter(m_of); + } else { + m_o = new JSONWriter(std::cout); + } + m_o->beginMember("file"); + m_o->writeString(filepath); + m_o->endMember(); + + retrace::debug = 0; + retracer.addCallbacks(glretrace::gl_callbacks); + retracer.addCallbacks(glretrace::glx_callbacks); + retracer.addCallbacks(glretrace::wgl_callbacks); + retracer.addCallbacks(glretrace::cgl_callbacks); + retracer.addCallbacks(glretrace::egl_callbacks); + retrace::setUp(); + parser->open(filepath.c_str()); +} + +FrameLoop::~FrameLoop() { + delete m_o; +} + +void +FrameLoop::advanceToFrame(int f) { + for (auto c : m_calls) + delete c; + m_calls.clear(); + + trace::Call *call; + while ((call = parser->parse_call()) && m_current_frame < f) { + retracer.retrace(*call); + const bool frame_boundary = call->flags & trace::CALL_FLAG_END_FRAME; + delete call; + if (frame_boundary) { + ++m_current_frame; + if (m_current_frame == f) + break; + } + } + + while ((call = parser->parse_call())) { + m_calls.push_back(call); + retracer.retrace(*call); + const bool frame_boundary = call->flags & trace::CALL_FLAG_END_FRAME; + if (frame_boundary) { + ++m_current_frame; + break; + } + } +} +#ifdef _MSC_VER +#include "Windows.h" +inline unsigned int +get_ms_time() { + LARGE_INTEGER frequency; + ::QueryPerformanceFrequency(&frequency); + + LARGE_INTEGER start; + ::QueryPerformanceCounter(&start); + + return start.QuadPart / (frequency.QuadPart / 1000); +} +#else +inline unsigned int +get_ms_time() { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC_RAW, &t); + unsigned int ms = t.tv_sec * 1000; + ms += (t.tv_nsec / 1000000); + return ms; +} +#endif + +void +FrameLoop::loop(int count) { + std::vector<unsigned int> frame_times; + frame_times.reserve(count); + + // warm up with 5 frames + // retrace count frames and output frame time + for (int i = 0; i < 5; ++i) { + for (auto c : m_calls) { + retracer.retrace(*c); + } + } + unsigned int begin = get_ms_time(); + for (int i = 0; i < count; ++i) { + for (auto c : m_calls) { + retracer.retrace(*c); + } + const unsigned int end = get_ms_time(); + frame_times.push_back(end - begin); + begin = end; + } + std::stringstream frame_name; + frame_name << "frame " << m_current_frame - 1; + m_o->beginMember(frame_name.str().c_str()); + m_o->beginArray(); + for (auto t : frame_times) + m_o->writeInt(t); + m_o->endArray(); +} + diff --git a/retrace/daemon/framestat/glframe_loop.hpp b/retrace/daemon/framestat/glframe_loop.hpp new file mode 100644 index 00000000..07fc4a9e --- /dev/null +++ b/retrace/daemon/framestat/glframe_loop.hpp @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2016 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. + * + * Authors: + * Mark Janes <mark.a.janes@intel.com> + **************************************************************************/ + +#ifndef _GLFRAME_LOOP_HPP_ +#define _GLFRAME_LOOP_HPP_ + +#include <string> +#include <vector> + +#include <fstream> // NOLINT + +#include "json.hpp" + +namespace trace { +class Call; +} + +namespace glretrace { + +class FrameLoop { + public: + FrameLoop(const std::string filepath, + const std::string out_path); + ~FrameLoop(); + + void advanceToFrame(int f); + void loop(int count); + + private: + std::ofstream m_of; + JSONWriter *m_o; + int m_current_frame; + std::vector<trace::Call*> m_calls; +}; + +} // namespace glretrace + +#endif + diff --git a/retrace/daemon/framestat/main.cpp b/retrace/daemon/framestat/main.cpp new file mode 100644 index 00000000..679888a9 --- /dev/null +++ b/retrace/daemon/framestat/main.cpp @@ -0,0 +1,89 @@ +// Copyright (C) Intel Corp. 2016. 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 (including the +// next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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. + +// **********************************************************************/ +// * Authors: +// * Mark Janes <mark.a.janes@intel.com> +// **********************************************************************/ + +#include <getopt.h> + +#include <string> +#include <vector> + +#include "glframe_loop.hpp" + +using glretrace::FrameLoop; + +int main(int argc, char *argv[]) { + int loop_count = 0; + std::string frame_file, out_file; + std::vector<int> frames; + const char *usage = "USAGE: framestat -n {loop_count} [-o {out_file}]" + "-f {trace} frame_1 frame_2 ... frame_n\n"; + int opt; + while ((opt = getopt(argc, argv, "n:f:p:o:h")) != -1) { + switch (opt) { + case 'n': + loop_count = atoi(optarg); + continue; + case 'f': + frame_file = optarg; + continue; + case 'o': + out_file = optarg; + continue; + case 'h': + default: /* '?' */ + printf("%s", usage); + return 0; + } + } + + for (int index = optind; index < argc; index++) { + frames.push_back(atoi(argv[index])); + } + if (FILE *file = fopen(frame_file.c_str(), "r")) { + fclose(file); + } else { + printf("ERROR: frame file not found: %s\n", frame_file.c_str()); + printf("%s", usage); + return -1; + } + if (loop_count == 0) { + printf("ERROR: loop count not specified.\n"); + printf("%s", usage); + return -1; + } + if (frames.empty()) { + printf("ERROR: target frames not specified.\n"); + printf("%s", usage); + return -1; + } + + FrameLoop loop(frame_file, out_file); + for (auto f : frames) { + loop.advanceToFrame(f); + loop.loop(loop_count); + } + return 0; +} |