载入中...
搜索中...
未找到
Profiler.cpp
浏览该文件的文档.
1#include "profiler/Profiler.h"
2
3#include "common/GpuTimer.h"
4#include "common/Capability.h"
5
6#include <simplesquirrel/simplesquirrel.hpp>
7
8#include <chrono>
9#include <cstdint>
10
11namespace eve::profiler {
12
14
15namespace {
16int64_t nowNs() {
17 return std::chrono::duration_cast<std::chrono::nanoseconds>(
18 std::chrono::steady_clock::now().time_since_epoch())
19 .count();
20}
21} // namespace
22
27
31
32void Profiler::setEnabled(bool on) {
34 if (!on) {
35 frameMs_ = 0.f;
36 }
37}
38
40
43 frameMs_ = 0.f;
44 captureSequence_ = 0;
45}
46
47void Profiler::ensureGpuTimer() const {
48 // Retry only while unbound so a late graphics provider can still attach; once
49 // resolved (including to nullptr after a successful provide/revoke cycle is
50 // not re-probed from hot paths — callers rebind by constructing a new module).
51 if (!gpuTimer_) gpuTimer_ = eve::cap::ProviderRef<eve::service::IGpuTimer>::bind();
52}
53
55 frameBeginNs_ = nowNs();
56 ensureGpuTimer();
57}
58
60 if (!enabled()) return;
61 const double totalMs = static_cast<double>(nowNs() - frameBeginNs_) / 1'000'000.0;
62 frameMs_ = static_cast<float>(totalMs);
64 ++captureSequence_;
65}
66
67void Profiler::begin(const char* name) {
68 if (!enabled()) return;
69 eve::prof::Profiler::zoneBegin(name ? name : "scope", nullptr);
70}
71
73 if (!enabled()) return;
75}
76
78
80
81void Profiler::passBegin(const char* name) {
82 if (!enabled()) return;
83 eve::prof::Profiler::zoneBegin(name ? name : "pass", "graphics");
84}
85
86void Profiler::passEnd(const char* name) {
87 if (!enabled()) return;
89}
90
92
93float Profiler::frameMs() const { return frameMs_; }
94
95float Profiler::gpuFrameMs() const {
96 ensureGpuTimer();
97 return gpuTimer_ ? gpuTimer_->gpuFrameMs() : 0.f;
98}
99
101 if (!hasFrame()) {
103 eve::DiagnosticCode::NotFound, "No completed profiler frame is available",
104 "profiler.frame", {}, "profiler.capture-frame"));
105 }
106 ProfilerFrameSnapshot snapshot;
107 snapshot.sequence = captureSequence_;
108 snapshot.cpuFrameMs = frameMs_;
109 ensureGpuTimer();
110 if (gpuTimer_) {
111 snapshot.gpuTimingAvailable = gpuTimer_->gpuTimingAvailable();
112 if (snapshot.gpuTimingAvailable) snapshot.gpuFrameMs = gpuTimer_->gpuFrameMs();
113 }
114 const auto& samples = eve::prof::Profiler::lastFrame();
115 snapshot.zones.reserve(samples.size());
116 for (const auto& sample : samples) {
117 snapshot.zones.push_back({sample.module, sample.name, sample.thread, sample.selfMs,
118 sample.totalMs, sample.count, sample.minDepth});
119 }
120 return eve::Result<ProfilerFrameSnapshot>::success(std::move(snapshot));
121}
122
123std::string Profiler::textReport() const {
124 std::string report = eve::prof::Profiler::textReport();
125 ensureGpuTimer();
126 if (gpuTimer_ && gpuTimer_->gpuTimingAvailable()) {
127 char buf[64];
128 std::snprintf(buf, sizeof(buf), " GPU frame: %.2f ms\n", gpuTimer_->gpuFrameMs());
129 report += buf;
130 }
131 return report;
132}
133
134ssq::Object Profiler::capture() {
135 ssq::Array out(vm_);
136 for (const auto& s : eve::prof::Profiler::lastFrame()) {
137 ssq::Table t(vm_);
138 t.set("module", s.module);
139 t.set("name", s.name);
140 t.set("thread", s.thread);
141 t.set("selfMs", static_cast<float>(s.selfMs));
142 t.set("totalMs", static_cast<float>(s.totalMs));
143 t.set("count", s.count);
144 out.push(t);
145 }
146 return out;
147}
148
149void Profiler::expose(ssq::Table& table) {
150 if (Profiler* self = Profiler::create()) self->vm_ = table.getHandle();
151 auto cls = table.addClass(name, Profiler::create, false);
152 expose(cls);
153}
154
155void Profiler::expose(ssq::Class& cls) {
156 cls.addFunc("setEnabled", &Profiler::setEnabled);
157 cls.addFunc("enabled", &Profiler::enabled);
158 cls.addFunc("reset", &Profiler::reset);
159 cls.addFunc("beginFrame", &Profiler::beginFrame);
160 cls.addFunc("endFrame", &Profiler::endFrame);
161 cls.addFunc("begin", &Profiler::begin);
162 cls.addFunc("end", &Profiler::end);
163 cls.addFunc("hasFrame", &Profiler::hasFrame);
164 cls.addFunc("frameMs", &Profiler::frameMs);
165 cls.addFunc("gpuFrameMs", &Profiler::gpuFrameMs);
166 cls.addFunc("textReport", &Profiler::textReport);
167 cls.addFunc("capture", &Profiler::capture);
168}
169
170} // namespace eve::profiler
const std::string & s
HSQOBJECT cls
Definition ECS.cpp:21
std::string name
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:26
float t
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static ProviderRef bind()
Resolve I once from the registry.
Definition Capability.h:128
static std::string textReport()
Human-readable report of the last frame.
Definition Profile.cpp:226
static void setEnabled(bool on)
Turns collection on/off globally (off = single-branch no-op).
Definition Profile.cpp:92
static const std::vector< ZoneSample > & lastFrame()
Per-module/per-zone samples of the last frame, sorted by self time.
Definition Profile.cpp:224
static void zoneBegin(const char *name, const char *module=nullptr)
Opens a scoped zone on the current thread.
Definition Profile.cpp:96
static double frameMark()
Finalizes the current frame: snapshots all thread buffers and aggregates them into lastFrame().
Definition Profile.cpp:132
static void reset()
Clears all collected state.
Definition Profile.cpp:122
static void zoneEnd()
Closes the innermost open zone on the current thread.
Definition Profile.cpp:113
static bool hasFrame()
True once at least one frame has been aggregated.
Definition Profile.cpp:222
static bool enabled()
True when collection is active.
Definition Profile.cpp:94
Script-facing wrapper around the engine-wide profiler core (eve::prof, see common/Profile....
Definition Profiler.h:67
void frameBegin() override
Frame begin.
Definition Profiler.cpp:77
void end()
Closes the innermost open user scope.
Definition Profiler.cpp:72
void passEnd(const char *name) override
Pass end.
Definition Profiler.cpp:86
float gpuFrameMs() const
GPU execution time of the last presented frame (0 when unavailable).
Definition Profiler.cpp:95
void begin(const char *name)
Opens a user timing scope under the current frame.
Definition Profiler.cpp:67
void reset()
Clears all collected data.
Definition Profiler.cpp:41
bool hasFrame() const
True once at least one frame has been aggregated.
Definition Profiler.cpp:91
float frameMs() const
Total CPU frame time of the last frame, in milliseconds.
Definition Profiler.cpp:93
void passBegin(const char *name) override
Pass begin.
Definition Profiler.cpp:81
bool enabled() const
True when collection is active.
Definition Profiler.cpp:39
ssq::Object capture()
Structured report of the last frame.
Definition Profiler.cpp:134
void setEnabled(bool on)
Enables/disables engine-wide collection. Disabled = cheap no-op.
Definition Profiler.cpp:32
~Profiler() override
Profiler.
Definition Profiler.cpp:28
void frameEnd() override
Frame end.
Definition Profiler.cpp:79
eve::Result< ProfilerFrameSnapshot > captureFrame() const
Copy the latest completed frame for editor and diagnostics consumers.
Definition Profiler.cpp:100
std::string textReport() const
Human-readable hotspot report (per module / per zone).
Definition Profiler.cpp:123
void endFrame()
Finalizes the current frame and aggregates the collected zones.
Definition Profiler.cpp:59
void beginFrame()
Marks the start of a frame for total-frame timing.
Definition Profiler.cpp:54
virtual bool gpuTimingAvailable() const =0
True when the renderer captured a valid GPU frame this frame.
virtual float gpuFrameMs() const =0
GPU execution time of the last presented frame, in milliseconds.
void setRenderTracer(IRenderTracer *tracer)
Sets the render tracer.
IRenderTracer * renderTracer()
Renders tracer.
void registerProfilerCapabilities()
Publish the read-only profiler capability (eve::IProfilerQuery).
Owning CPU/GPU profiler snapshot safe to retain across later frames.
Definition Profiler.h:36
std::vector< ProfilerZoneSnapshot > zones
Definition Profiler.h:41