OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::FrameProfiler Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/FrameProfiler.hpp>

Collaboration diagram for Slic3r::GUI::FrameProfiler:

Classes

struct  Section
struct  Frame

Public Member Functions

void begin_frame ()
void mark (const char *name)
void end_frame ()
const std::vector< Section > & sections () const
void start_averaging ()
bool is_averaging () const
std::vector< Section > finish_averaging (bool wait)
void reset ()

Private Member Functions

void collect (bool wait)

Private Attributes

std::array< Frame, FRAMES_IN_FLIGHT > m_frames
Frame * m_recording { nullptr }
size_t m_next { 0 }
std::chrono::steady_clock::time_point m_last_mark
std::vector< Section > m_sections
bool m_averaging { false }
std::vector< Section > m_sums
size_t m_averaged_frames { 0 }

Static Private Attributes

static constexpr size_t FRAMES_IN_FLIGHT = 4
static constexpr size_t MAX_SECTIONS = 32

Detailed Description


Class Documentation

◆ Slic3r::GUI::FrameProfiler::Section

struct Slic3r::GUI::FrameProfiler::Section
Class Members
double cpu_ms { 0.0 }
double gpu_ms { 0.0 }
const char * name { nullptr }

◆ Slic3r::GUI::FrameProfiler::Frame

struct Slic3r::GUI::FrameProfiler::Frame
Collaboration diagram for Slic3r::GUI::FrameProfiler::Frame:
Class Members
bool averaged { false }
size_t count { 0 }
array< double, MAX_SECTIONS > cpu_ms {}
array< const char *, MAX_SECTIONS > names {}
bool pending { false }
array< unsigned int, 2 *MAX_SECTIONS > queries {}

Member Function Documentation

◆ begin_frame()

void Slic3r::GUI::FrameProfiler::begin_frame ( )
19{
20 m_recording = nullptr;
21 // GL 3.3 or ARB_timer_query
22 if (glQueryCounter == nullptr)
23 return;
24
25 collect(false);
26 Frame& frame = m_frames[m_next];
27 // Every frame in flight still waits for the GPU: skip this one rather than stall.
28 if (frame.pending)
29 return;
30
31 if (frame.queries[0] == 0)
32 glsafe(::glGenQueries(GLsizei(frame.queries.size()), frame.queries.data()));
33 glsafe(::glQueryCounter(frame.queries[0], GL_TIMESTAMP));
34 frame.count = 0;
35 frame.averaged = m_averaging;
36 m_recording = &frame;
37 m_last_mark = std::chrono::steady_clock::now();
38}
#define glsafe(cmd)
Definition OpenGLUtils.hpp:25
std::chrono::steady_clock::time_point m_last_mark
Definition FrameProfiler.hpp:58
size_t m_next
Definition FrameProfiler.hpp:57
Frame * m_recording
Definition FrameProfiler.hpp:56
void collect(bool wait)
Definition FrameProfiler.cpp:69
bool m_averaging
Definition FrameProfiler.hpp:60
std::array< Frame, FRAMES_IN_FLIGHT > m_frames
Definition FrameProfiler.hpp:55
Definition FrameProfiler.hpp:43
#define GL_TIMESTAMP
Definition gl.h:1858
int GLsizei
Definition gl.h:2065
#define glGenQueries
Definition gl.h:3779
#define glQueryCounter
Definition gl.h:4607

References Slic3r::GUI::FrameProfiler::Frame::averaged, collect(), Slic3r::GUI::FrameProfiler::Frame::count, GL_TIMESTAMP, glGenQueries, glQueryCounter, glsafe, m_averaging, m_frames, m_last_mark, m_next, m_recording, Slic3r::GUI::FrameProfiler::Frame::pending, and Slic3r::GUI::FrameProfiler::Frame::queries.

Here is the call graph for this function:

◆ collect()

void Slic3r::GUI::FrameProfiler::collect ( bool wait)
private
70{
71 constexpr double SMOOTHING = 0.1;
72
73 // Oldest first: a frame whose results are not in yet holds back the newer ones too.
74 for (size_t i = 0; i < FRAMES_IN_FLIGHT; ++i) {
75 Frame& frame = m_frames[(m_next + i) % FRAMES_IN_FLIGHT];
76 if (!frame.pending)
77 continue;
78
79 if (!wait) {
80 GLint available = 0;
81 glsafe(::glGetQueryObjectiv(frame.queries[2 * frame.count - 1], GL_QUERY_RESULT_AVAILABLE, &available));
82 if (available == 0)
83 break;
84 }
85
86 std::array<GLuint64, 2 * MAX_SECTIONS> stamps{};
87 for (size_t j = 0; j < 2 * frame.count; ++j)
88 glsafe(::glGetQueryObjectui64v(frame.queries[j], GL_QUERY_RESULT, &stamps[j]));
89 frame.pending = false;
90
91 const bool averaged = frame.averaged && m_averaging;
92 if (averaged)
94 std::vector<Section> sections;
95 sections.reserve(frame.count);
96 for (size_t j = 0; j < frame.count; ++j) {
97 Section section{ frame.names[j], frame.cpu_ms[j], stamps[2 * j + 1] > stamps[2 * j] ? double(stamps[2 * j + 1] - stamps[2 * j]) * 1e-6 : 0.0 };
98 if (averaged) {
99 auto sum = std::find_if(m_sums.begin(), m_sums.end(), [&section](const Section& s) { return std::strcmp(s.name, section.name) == 0; });
100 if (sum == m_sums.end())
101 m_sums.push_back(section);
102 else {
103 sum->cpu_ms += section.cpu_ms;
104 sum->gpu_ms += section.gpu_ms;
105 }
106 }
107 for (const Section& prev : m_sections) {
108 if (std::strcmp(prev.name, section.name) == 0) {
109 section.cpu_ms = prev.cpu_ms + SMOOTHING * (section.cpu_ms - prev.cpu_ms);
110 section.gpu_ms = prev.gpu_ms + SMOOTHING * (section.gpu_ms - prev.gpu_ms);
111 break;
112 }
113 }
114 sections.push_back(section);
115 }
116 m_sections = std::move(sections);
117 }
118}
std::vector< Section > m_sums
Definition FrameProfiler.hpp:61
std::vector< Section > m_sections
Definition FrameProfiler.hpp:59
const std::vector< Section > & sections() const
Definition FrameProfiler.hpp:29
size_t m_averaged_frames
Definition FrameProfiler.hpp:62
static constexpr size_t FRAMES_IN_FLIGHT
Definition FrameProfiler.hpp:39
Definition FrameProfiler.hpp:19
int GLint
Definition gl.h:2062
#define GL_QUERY_RESULT
Definition gl.h:1382
#define glGetQueryObjectui64v
Definition gl.h:3961
#define glGetQueryObjectiv
Definition gl.h:3959
#define GL_QUERY_RESULT_AVAILABLE
Definition gl.h:1383

References Slic3r::GUI::FrameProfiler::Frame::averaged, Slic3r::GUI::FrameProfiler::Frame::count, Slic3r::GUI::FrameProfiler::Frame::cpu_ms, Slic3r::GUI::FrameProfiler::Section::cpu_ms, FRAMES_IN_FLIGHT, GL_QUERY_RESULT, GL_QUERY_RESULT_AVAILABLE, glGetQueryObjectiv, glGetQueryObjectui64v, glsafe, Slic3r::GUI::FrameProfiler::Section::gpu_ms, m_averaged_frames, m_averaging, m_frames, m_next, m_sections, m_sums, Slic3r::GUI::FrameProfiler::Section::name, Slic3r::GUI::FrameProfiler::Frame::names, Slic3r::GUI::FrameProfiler::Frame::pending, Slic3r::GUI::FrameProfiler::Frame::queries, and sections().

Referenced by begin_frame(), and finish_averaging().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ end_frame()

void Slic3r::GUI::FrameProfiler::end_frame ( )
60{
61 if (m_recording == nullptr)
62 return;
63
64 m_recording->pending = m_recording->count > 0;
65 m_recording = nullptr;
67}

References FRAMES_IN_FLIGHT, m_next, and m_recording.

◆ finish_averaging()

std::vector< FrameProfiler::Section > Slic3r::GUI::FrameProfiler::finish_averaging ( bool wait)
128{
129 if (wait && glQueryCounter != nullptr)
130 collect(true);
131 std::vector<Section> averages = std::move(m_sums);
132 for (Section& section : averages) {
133 section.cpu_ms /= double(m_averaged_frames);
134 section.gpu_ms /= double(m_averaged_frames);
135 }
136 m_averaging = false;
137 m_sums.clear();
139 return averages;
140}

References collect(), glQueryCounter, m_averaged_frames, m_averaging, and m_sums.

Here is the call graph for this function:

◆ is_averaging()

bool Slic3r::GUI::FrameProfiler::is_averaging ( ) const
inline
32{ return m_averaging; }

References m_averaging.

◆ mark()

void Slic3r::GUI::FrameProfiler::mark ( const char * name)
41{
42 if (m_recording == nullptr || m_recording->count == MAX_SECTIONS)
43 return;
44
45 Frame& frame = *m_recording;
46 const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
47 glsafe(::glQueryCounter(frame.queries[2 * frame.count + 1], GL_TIMESTAMP));
48 // Else the GPU time would include the CPU time spent until the driver flushes on its own.
50 // Sent with the next section's commands, so the time the GPU waits for them is not billed to it.
51 if (frame.count + 1 < MAX_SECTIONS)
52 glsafe(::glQueryCounter(frame.queries[2 * frame.count + 2], GL_TIMESTAMP));
53 frame.names[frame.count] = name;
54 frame.cpu_ms[frame.count] = std::chrono::duration<double, std::milli>(now - m_last_mark).count();
55 ++frame.count;
56 m_last_mark = now;
57}
static constexpr size_t MAX_SECTIONS
Definition FrameProfiler.hpp:40
#define glFlush
Definition gl.h:3719

References Slic3r::GUI::FrameProfiler::Frame::count, Slic3r::GUI::FrameProfiler::Frame::cpu_ms, GL_TIMESTAMP, glFlush, glQueryCounter, glsafe, m_last_mark, m_recording, MAX_SECTIONS, Slic3r::GUI::FrameProfiler::Frame::names, and Slic3r::GUI::FrameProfiler::Frame::queries.

◆ reset()

void Slic3r::GUI::FrameProfiler::reset ( )
143{
144 for (Frame& frame : m_frames) {
145 if (frame.queries[0] != 0)
146 glsafe(::glDeleteQueries(GLsizei(frame.queries.size()), frame.queries.data()));
147 frame = Frame();
148 }
149 m_recording = nullptr;
150 m_sections.clear();
151 m_averaging = false;
152 m_sums.clear();
154}
#define glDeleteQueries
Definition gl.h:3575

References glDeleteQueries, glsafe, m_averaged_frames, m_averaging, m_frames, m_recording, m_sections, and m_sums.

◆ sections()

const std::vector< Section > & Slic3r::GUI::FrameProfiler::sections ( ) const
inline
29{ return m_sections; }

References m_sections.

Referenced by collect().

Here is the caller graph for this function:

◆ start_averaging()

void Slic3r::GUI::FrameProfiler::start_averaging ( )
121{
122 m_averaging = true;
123 m_sums.clear();
125}

References m_averaged_frames, m_averaging, and m_sums.

Member Data Documentation

◆ FRAMES_IN_FLIGHT

size_t Slic3r::GUI::FrameProfiler::FRAMES_IN_FLIGHT = 4
staticconstexprprivate

Referenced by collect(), and end_frame().

◆ m_averaged_frames

size_t Slic3r::GUI::FrameProfiler::m_averaged_frames { 0 }
private
62{ 0 };

Referenced by collect(), finish_averaging(), reset(), and start_averaging().

◆ m_averaging

bool Slic3r::GUI::FrameProfiler::m_averaging { false }
private

◆ m_frames

std::array<Frame, FRAMES_IN_FLIGHT> Slic3r::GUI::FrameProfiler::m_frames
private

Referenced by begin_frame(), collect(), and reset().

◆ m_last_mark

std::chrono::steady_clock::time_point Slic3r::GUI::FrameProfiler::m_last_mark
private

Referenced by begin_frame(), and mark().

◆ m_next

size_t Slic3r::GUI::FrameProfiler::m_next { 0 }
private
57{ 0 };

Referenced by begin_frame(), collect(), and end_frame().

◆ m_recording

Frame* Slic3r::GUI::FrameProfiler::m_recording { nullptr }
private
56{ nullptr };

Referenced by begin_frame(), end_frame(), mark(), and reset().

◆ m_sections

std::vector<Section> Slic3r::GUI::FrameProfiler::m_sections
private

Referenced by collect(), reset(), and sections().

◆ m_sums

std::vector<Section> Slic3r::GUI::FrameProfiler::m_sums
private

◆ MAX_SECTIONS

size_t Slic3r::GUI::FrameProfiler::MAX_SECTIONS = 32
staticconstexprprivate

Referenced by mark().


The documentation for this class was generated from the following files: