File: vtkRenderTimerLog.h

package info (click to toggle)
paraview 5.11.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 497,236 kB
  • sloc: cpp: 3,171,290; ansic: 1,315,072; python: 134,290; xml: 103,324; sql: 65,887; sh: 5,286; javascript: 4,901; yacc: 4,383; java: 3,977; perl: 2,363; lex: 1,909; f90: 1,255; objc: 143; makefile: 119; tcl: 59; pascal: 50; fortran: 29
file content (234 lines) | stat: -rw-r--r-- 8,259 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRenderTimerLog.h

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

/**
 * @class   vtkRenderTimerLog
 * @brief   Asynchronously measures GPU execution times for a series of events.
 *
 * This class measures the time it takes for events to occur on the GPU by
 * posting timing events into the rendering command stream. This can be used
 * to compute the time spent doing work on the GPU without stalling the
 * CPU.
 *
 * To aid asynchronous usage, this class uses the concepts "Event" and "Frame",
 * where a Frame is a logical collection of Events. The timer log can manage
 * multiple Frames at a time:
 * - The current Frame, where new Events are created.
 * - Pending Frames, for which all Events have been marked, but the results are
 *   not available (the timer requests are still waiting to be processed by the
 *   graphics device).
 * - Ready Frames, which have been completed by the graphics device and may be
 *   retrieved.
 *
 * Call MarkFrame() to begin a new Frame. This pushes the current Frame to the
 * collection of pending Frames, and creates a new one to store future Events.
 *
 * Call MarkStartEvent() and MarkEndEvent() to mark the beginning and end of
 * an Event. These Events may be nested, but all child Events must have their
 * end marked before the parent Event ends.
 *
 * Use FrameReady() and PopFirstReadyFrame() to check for completed Frames and
 * retrieve results.
 *
 * This is currently only implemented for the OpenGL2 backend. The IsSupported()
 * method can be used to detect if there is a valid implementation available.
 */

#ifndef vtkRenderTimerLog_h
#define vtkRenderTimerLog_h

#include "vtkObject.h"
#include "vtkRenderingCoreModule.h" // For export macro
#include "vtkType.h"                // For vtkTypeUint64, etc
#include <sstream>                  // for std::ostringstream
#include <string>                   // for std::string
#include <vector>                   // for std::vector

/**
 * Creates a ScopedEventLogger on @a timer with the given @a name. @a name is
 * passed into a stream and may be constructed using the << operator.
 */
#define VTK_SCOPED_RENDER_EVENT(eventName, timer) VTK_SCOPED_RENDER_EVENT2(eventName, timer, _event)

/**
 * Creates a ScopedEventLogger on @a timer with the given @a name. @a name is
 * passed into a stream and may be constructed using the << operator. The logger
 * will be created with the provided @a identifier.
 */
#define VTK_SCOPED_RENDER_EVENT2(eventName, timer, identifier)                                     \
  vtkRenderTimerLog::ScopedEventLogger identifier;                                                 \
  do                                                                                               \
  {                                                                                                \
    std::ostringstream _eventNameStream;                                                           \
    _eventNameStream << eventName;                                                                 \
    identifier = timer->StartScopedEvent(_eventNameStream.str());                                  \
    (void)identifier; /* Prevent set-but-not-used var warnings */                                  \
  } while (false)     /* Do-while loop prevents duplicate semicolon warnings */

VTK_ABI_NAMESPACE_BEGIN
class VTKRENDERINGCORE_EXPORT vtkRenderTimerLog : public vtkObject
{
public:
  struct Frame;

  /** Container for a single timed event. */
  struct VTKRENDERINGCORE_EXPORT Event
  {
    /** Event name. */
    std::string Name;

    /** Times are in nanoseconds. @{ */
    vtkTypeUInt64 StartTime;
    vtkTypeUInt64 EndTime;
    /**@}*/

    /** Convenience methods to compute times */
    float ElapsedTimeSeconds() const { return this->ElapsedTimeNanoseconds() * 1e-9f; }
    float ElapsedTimeMilliseconds() const { return this->ElapsedTimeNanoseconds() * 1e-6f; }
    vtkTypeUInt64 ElapsedTimeNanoseconds() const { return this->EndTime - this->StartTime; }

    /** Child events that occurred while this event was running. */
    std::vector<Event> Events;

    /** Print details of the event to a stream.
     * @param os The stream.
     * @param threshMs Only print events with a time > threshMs milliseconds.
     * @param indent Starting indentation for the first event.
     */
    void Print(std::ostream& os, float threshMs = 0.f, vtkIndent indent = vtkIndent())
    {
      this->Print(os, 0.f, threshMs, indent);
    }

    friend struct vtkRenderTimerLog::Frame;

  protected:
    void Print(std::ostream& os, float parentTime, float threshMs, vtkIndent indent);
  };

  /** Container for a frame's events. */
  struct VTKRENDERINGCORE_EXPORT Frame
  {
    std::vector<Event> Events;

    /** Print details of all events in this frame to a stream.
     * @param os The stream.
     * @param threshMs Only print events with a time > threshMs milliseconds.
     */
    void Print(std::ostream& os, float threshMs = 0.f);
  };

  /**
   * RAII struct for logging events. Such events start when
   * vtkRenderTimerLog::StartScopedEvent(name) is called, and end when the
   * returned object is destroyed, or ScopedEventLogger::Stop() is called.
   */
  struct VTKRENDERINGCORE_EXPORT ScopedEventLogger
  {
    ScopedEventLogger()
      : Log(nullptr)
    {
    }
    ScopedEventLogger(ScopedEventLogger&& other) noexcept;
    ScopedEventLogger& operator=(ScopedEventLogger&& other) noexcept;
    ~ScopedEventLogger() { this->Stop(); }
    void Stop();
    friend class vtkRenderTimerLog;

  protected:
    ScopedEventLogger(vtkRenderTimerLog* log)
      : Log(log)
    {
    }

  private:
    void operator=(const ScopedEventLogger&) = delete;
    ScopedEventLogger(const ScopedEventLogger& other) = delete;
    vtkRenderTimerLog* Log;
  };

  static vtkRenderTimerLog* New();
  vtkTypeMacro(vtkRenderTimerLog, vtkObject);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  /**
   * Returns true if stream timings are implemented for the current graphics
   * backend.
   */
  virtual bool IsSupported() VTK_FUTURE_CONST;

  /**
   * Call to mark the start of a new frame, or the end of an old one. Does
   * nothing if no events have been recorded in the current frame.
   */
  virtual void MarkFrame();

  /**
   * Create a RAII scoped event. See ScopedEventLogger for details.
   */
  ScopedEventLogger StartScopedEvent(const std::string& name);

  /**
   * Mark the beginning or end of an event. @{
   */
  virtual void MarkStartEvent(const std::string& name);
  virtual void MarkEndEvent();
  /**@}*/

  /**
   * Returns true if there are any frames ready with complete timing info.
   */
  virtual bool FrameReady();

  /**
   * Retrieve the first available frame's timing info. The returned frame is
   * removed from this log.
   */
  virtual Frame PopFirstReadyFrame();

  /** If false, no events are recorded. Default is false. @{ */
  vtkSetMacro(LoggingEnabled, bool);
  vtkGetMacro(LoggingEnabled, bool);
  vtkBooleanMacro(LoggingEnabled, bool);
  /**@}*/

  /**
   * If there are more than FrameLimit frames pending/ready, drop the old ones
   * until we are under this limit. Prevents things from backing up.
   * Default is 32. Set to 0 to disable. @{
   */
  vtkSetMacro(FrameLimit, unsigned int);
  vtkGetMacro(FrameLimit, unsigned int);
  /**@}*/

  /**
   * Releases any resources allocated on the graphics device.
   */
  virtual void ReleaseGraphicsResources();

protected:
  vtkRenderTimerLog();
  ~vtkRenderTimerLog() override;

  mutable bool LoggingEnabled;
  unsigned int FrameLimit;

private:
  vtkRenderTimerLog(const vtkRenderTimerLog&) = delete;
  void operator=(const vtkRenderTimerLog&) = delete;
};

VTK_ABI_NAMESPACE_END
#endif // vtkRenderTimerLog_h