summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Janes <mark.a.janes@intel.com>2016-11-11 13:17:18 -0800
committerMark Janes <mark.a.janes@intel.com>2017-06-19 14:04:49 -0700
commit63a3dbaf180a6fc6917df499fccf3f05c0babd31 (patch)
tree98eb3096c5e3dc7412547861243ffe0048ff549c
parent3c48faa1df3d7dd29341986cbff588e550c78772 (diff)
Implement framestat
Framestat loops over specified frames, providing frame time in milliseconds.
-rw-r--r--retrace/daemon/CMakeLists.txt1
-rw-r--r--retrace/daemon/framestat/CMakeLists.txt41
-rw-r--r--retrace/daemon/framestat/glframe_loop.cpp154
-rw-r--r--retrace/daemon/framestat/glframe_loop.hpp63
-rw-r--r--retrace/daemon/framestat/main.cpp89
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;
+}