#include "PerformanceShower_p.h" namespace YSG { PerformanceShower::PerformanceShower() { dPtr = new PerformanceShowerPrivate; mObjectName = "PerformanceShower"; setIndependentPixelCache(true); } PerformanceShowerPrivate* PerformanceShower::d() { return reinterpret_cast(dPtr); } RenderData* PerformanceShower::createRenderData() { return new PerformanceShowerPrivate; } RenderState* PerformanceShower::createRenderState() { return new PerformanceShowerRenderState; } InputData* PerformanceShower::createInputData() { return new PerformanceShowerInputData; } void PerformanceShower::setEnabled(bool enabled) { mEnabled.store(enabled, std::memory_order_release); if(enabled) { appendEvent({PerformanceEventType::Clear}); } markRenderDirty(); } bool PerformanceShower::enabled() const { return mEnabled.load(std::memory_order_acquire); } void PerformanceShower::refreshCounter() { appendEvent({PerformanceEventType::Clear}); } void PerformanceShower::counterIncrease(const QString& counterName) { incrementCounter("General", counterName); } void PerformanceShower::incrementCounter(const QString& scope, const QString& name) { PerformanceEvent event; event.type = PerformanceEventType::Counter; event.scope = scope; event.key = name; appendEvent(event); } void PerformanceShower::setPerformanceLine(const QString& key, const PerformanceLine& line) { PerformanceEvent event; event.type = PerformanceEventType::Line; event.scope = "General"; event.key = key; event.line = line; appendEvent(event); } void PerformanceShower::setInfo(const QString& key, const QString& value) { setState("General", key, value); } void PerformanceShower::setState(const QString& scope, const QString& name, const QString& value) { PerformanceEvent event; event.type = PerformanceEventType::State; event.scope = scope; event.key = name; event.value = value; appendEvent(event); } void PerformanceShower::setGauge(const QString& scope, const QString& name, double value) { PerformanceEvent event; event.type = PerformanceEventType::Gauge; event.scope = scope; event.key = name; event.number = value; appendEvent(event); } void PerformanceShower::recordCost(const QString& key, double value) { recordDuration("General", key, value); } void PerformanceShower::recordDuration(const QString& scope, const QString& name, double value) { PerformanceEvent event; event.type = PerformanceEventType::Duration; event.scope = scope; event.key = name; event.number = value; appendEvent(event); } void PerformanceShower::setViewFilter(const QString& name) { setViewFilter(name, {}); } void PerformanceShower::setViewFilter(const QString& group, const QString& name) { PerformanceEvent event; event.type = PerformanceEventType::SelectView; event.scope = group; event.key = name; appendEvent(event); } void PerformanceShower::scrollView(int lines) { PerformanceEvent event; event.type = PerformanceEventType::ScrollView; event.number = lines; appendEvent(event); } void PerformanceShower::appendEvent(const PerformanceEvent& event) { if(!enabled() && event.type != PerformanceEventType::Clear) return; auto pd = d(); Triple_Buffer_Lease inputLease = pd->mInputControl.wait_mark_use_role(Input_Edit); auto input = reinterpret_cast(pd->inputDataByIndex(inputLease.index)); input->events.append(event); pd->markInputDirty(inputLease, false); pd->mInputControl.unmark_use(inputLease); notifyObservedUpdate(event.type == PerformanceEventType::Clear || event.type == PerformanceEventType::SelectView || event.type == PerformanceEventType::ScrollView); } void PerformanceShower::notifyObservedUpdate(bool force) { std::uint64_t now = static_cast(std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count()); std::uint64_t last = mLastNotifyNs.load(std::memory_order_acquire); if(!force && now - last < 100000000) return; if(force) { mLastNotifyNs.store(now, std::memory_order_release); markRenderDirty(); return; } if(force || mLastNotifyNs.compare_exchange_strong(last, now, std::memory_order_acq_rel, std::memory_order_acquire)) markRenderDirty(); } }