You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
8.0 KiB
C++
233 lines
8.0 KiB
C++
/*=========================================================================
|
|
|
|
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 */
|
|
|
|
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);
|
|
ScopedEventLogger& operator=(ScopedEventLogger&& other);
|
|
~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();
|
|
|
|
/**
|
|
* 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;
|
|
|
|
bool LoggingEnabled;
|
|
unsigned int FrameLimit;
|
|
|
|
private:
|
|
vtkRenderTimerLog(const vtkRenderTimerLog&) = delete;
|
|
void operator=(const vtkRenderTimerLog&) = delete;
|
|
};
|
|
|
|
#endif // vtkRenderTimerLog_h
|