mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	Remove built-in (non-Microprofile) profiler
This commit is contained in:
		@@ -69,7 +69,6 @@ set(HEADERS
 | 
			
		||||
set(UIS
 | 
			
		||||
            debugger/callstack.ui
 | 
			
		||||
            debugger/disassembler.ui
 | 
			
		||||
            debugger/profiler.ui
 | 
			
		||||
            debugger/registers.ui
 | 
			
		||||
            configure.ui
 | 
			
		||||
            configure_audio.ui
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,8 @@
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <QAction>
 | 
			
		||||
#include <QLayout>
 | 
			
		||||
#include <QMouseEvent>
 | 
			
		||||
#include <QPainter>
 | 
			
		||||
#include <QString>
 | 
			
		||||
@@ -9,121 +11,12 @@
 | 
			
		||||
#include "citra_qt/util/util.h"
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "common/microprofile.h"
 | 
			
		||||
#include "common/profiler_reporting.h"
 | 
			
		||||
 | 
			
		||||
// Include the implementation of the UI in this file. This isn't in microprofile.cpp because the
 | 
			
		||||
// non-Qt frontends don't need it (and don't implement the UI drawing hooks either).
 | 
			
		||||
#if MICROPROFILE_ENABLED
 | 
			
		||||
#define MICROPROFILEUI_IMPL 1
 | 
			
		||||
#include "common/microprofileui.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace Common::Profiling;
 | 
			
		||||
 | 
			
		||||
static QVariant GetDataForColumn(int col, const AggregatedDuration& duration) {
 | 
			
		||||
    static auto duration_to_float = [](Duration dur) -> float {
 | 
			
		||||
        using FloatMs = std::chrono::duration<float, std::chrono::milliseconds::period>;
 | 
			
		||||
        return std::chrono::duration_cast<FloatMs>(dur).count();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    switch (col) {
 | 
			
		||||
    case 1:
 | 
			
		||||
        return duration_to_float(duration.avg);
 | 
			
		||||
    case 2:
 | 
			
		||||
        return duration_to_float(duration.min);
 | 
			
		||||
    case 3:
 | 
			
		||||
        return duration_to_float(duration.max);
 | 
			
		||||
    default:
 | 
			
		||||
        return QVariant();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ProfilerModel::ProfilerModel(QObject* parent) : QAbstractItemModel(parent) {
 | 
			
		||||
    updateProfilingInfo();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVariant ProfilerModel::headerData(int section, Qt::Orientation orientation, int role) const {
 | 
			
		||||
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
 | 
			
		||||
        switch (section) {
 | 
			
		||||
        case 0:
 | 
			
		||||
            return tr("Category");
 | 
			
		||||
        case 1:
 | 
			
		||||
            return tr("Avg");
 | 
			
		||||
        case 2:
 | 
			
		||||
            return tr("Min");
 | 
			
		||||
        case 3:
 | 
			
		||||
            return tr("Max");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return QVariant();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QModelIndex ProfilerModel::index(int row, int column, const QModelIndex& parent) const {
 | 
			
		||||
    return createIndex(row, column);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QModelIndex ProfilerModel::parent(const QModelIndex& child) const {
 | 
			
		||||
    return QModelIndex();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ProfilerModel::columnCount(const QModelIndex& parent) const {
 | 
			
		||||
    return 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ProfilerModel::rowCount(const QModelIndex& parent) const {
 | 
			
		||||
    if (parent.isValid()) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        return 2;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVariant ProfilerModel::data(const QModelIndex& index, int role) const {
 | 
			
		||||
    if (role == Qt::DisplayRole) {
 | 
			
		||||
        if (index.row() == 0) {
 | 
			
		||||
            if (index.column() == 0) {
 | 
			
		||||
                return tr("Frame");
 | 
			
		||||
            } else {
 | 
			
		||||
                return GetDataForColumn(index.column(), results.frame_time);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (index.row() == 1) {
 | 
			
		||||
            if (index.column() == 0) {
 | 
			
		||||
                return tr("Frame (with swapping)");
 | 
			
		||||
            } else {
 | 
			
		||||
                return GetDataForColumn(index.column(), results.interframe_time);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return QVariant();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ProfilerModel::updateProfilingInfo() {
 | 
			
		||||
    results = GetTimingResultsAggregator()->GetAggregatedResults();
 | 
			
		||||
    emit dataChanged(createIndex(0, 1), createIndex(rowCount() - 1, 3));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ProfilerWidget::ProfilerWidget(QWidget* parent) : QDockWidget(parent) {
 | 
			
		||||
    ui.setupUi(this);
 | 
			
		||||
 | 
			
		||||
    model = new ProfilerModel(this);
 | 
			
		||||
    ui.treeView->setModel(model);
 | 
			
		||||
 | 
			
		||||
    connect(this, SIGNAL(visibilityChanged(bool)), SLOT(setProfilingInfoUpdateEnabled(bool)));
 | 
			
		||||
    connect(&update_timer, SIGNAL(timeout()), model, SLOT(updateProfilingInfo()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ProfilerWidget::setProfilingInfoUpdateEnabled(bool enable) {
 | 
			
		||||
    if (enable) {
 | 
			
		||||
        update_timer.start(100);
 | 
			
		||||
        model->updateProfilingInfo();
 | 
			
		||||
    } else {
 | 
			
		||||
        update_timer.stop();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if MICROPROFILE_ENABLED
 | 
			
		||||
 | 
			
		||||
class MicroProfileWidget : public QWidget {
 | 
			
		||||
public:
 | 
			
		||||
 
 | 
			
		||||
@@ -8,46 +8,6 @@
 | 
			
		||||
#include <QDockWidget>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include "common/microprofile.h"
 | 
			
		||||
#include "common/profiler_reporting.h"
 | 
			
		||||
#include "ui_profiler.h"
 | 
			
		||||
 | 
			
		||||
class ProfilerModel : public QAbstractItemModel {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit ProfilerModel(QObject* parent);
 | 
			
		||||
 | 
			
		||||
    QVariant headerData(int section, Qt::Orientation orientation,
 | 
			
		||||
                        int role = Qt::DisplayRole) const override;
 | 
			
		||||
    QModelIndex index(int row, int column,
 | 
			
		||||
                      const QModelIndex& parent = QModelIndex()) const override;
 | 
			
		||||
    QModelIndex parent(const QModelIndex& child) const override;
 | 
			
		||||
    int columnCount(const QModelIndex& parent = QModelIndex()) const override;
 | 
			
		||||
    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
 | 
			
		||||
    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void updateProfilingInfo();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Common::Profiling::AggregatedFrameResult results;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ProfilerWidget : public QDockWidget {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit ProfilerWidget(QWidget* parent = nullptr);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void setProfilingInfoUpdateEnabled(bool enable);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Ui::Profiler ui;
 | 
			
		||||
    ProfilerModel* model;
 | 
			
		||||
 | 
			
		||||
    QTimer update_timer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MicroProfileDialog : public QWidget {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>Profiler</class>
 | 
			
		||||
 <widget class="QDockWidget" name="Profiler">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>400</width>
 | 
			
		||||
    <height>300</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Profiler</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <widget class="QWidget" name="dockWidgetContents">
 | 
			
		||||
   <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
    <item>
 | 
			
		||||
     <widget class="QTreeView" name="treeView">
 | 
			
		||||
      <property name="alternatingRowColors">
 | 
			
		||||
       <bool>true</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
      <property name="uniformRowHeights">
 | 
			
		||||
       <bool>true</bool>
 | 
			
		||||
      </property>
 | 
			
		||||
     </widget>
 | 
			
		||||
    </item>
 | 
			
		||||
   </layout>
 | 
			
		||||
  </widget>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -113,11 +113,6 @@ void GMainWindow::InitializeDebugWidgets() {
 | 
			
		||||
 | 
			
		||||
    QMenu* debug_menu = ui.menu_View_Debugging;
 | 
			
		||||
 | 
			
		||||
    profilerWidget = new ProfilerWidget(this);
 | 
			
		||||
    addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
 | 
			
		||||
    profilerWidget->hide();
 | 
			
		||||
    debug_menu->addAction(profilerWidget->toggleViewAction());
 | 
			
		||||
 | 
			
		||||
#if MICROPROFILE_ENABLED
 | 
			
		||||
    microProfileDialog = new MicroProfileDialog(this);
 | 
			
		||||
    microProfileDialog->hide();
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@ set(SRCS
 | 
			
		||||
            memory_util.cpp
 | 
			
		||||
            microprofile.cpp
 | 
			
		||||
            misc.cpp
 | 
			
		||||
            profiler.cpp
 | 
			
		||||
            scm_rev.cpp
 | 
			
		||||
            string_util.cpp
 | 
			
		||||
            symbols.cpp
 | 
			
		||||
@@ -45,7 +44,6 @@ set(HEADERS
 | 
			
		||||
            microprofile.h
 | 
			
		||||
            microprofileui.h
 | 
			
		||||
            platform.h
 | 
			
		||||
            profiler_reporting.h
 | 
			
		||||
            quaternion.h
 | 
			
		||||
            scm_rev.h
 | 
			
		||||
            scope_exit.h
 | 
			
		||||
 
 | 
			
		||||
@@ -1,101 +0,0 @@
 | 
			
		||||
// Copyright 2015 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/profiler_reporting.h"
 | 
			
		||||
#include "common/synchronized_wrapper.h"
 | 
			
		||||
 | 
			
		||||
namespace Common {
 | 
			
		||||
namespace Profiling {
 | 
			
		||||
 | 
			
		||||
ProfilingManager::ProfilingManager()
 | 
			
		||||
    : last_frame_end(Clock::now()), this_frame_start(Clock::now()) {}
 | 
			
		||||
 | 
			
		||||
void ProfilingManager::BeginFrame() {
 | 
			
		||||
    this_frame_start = Clock::now();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ProfilingManager::FinishFrame() {
 | 
			
		||||
    Clock::time_point now = Clock::now();
 | 
			
		||||
 | 
			
		||||
    results.interframe_time = now - last_frame_end;
 | 
			
		||||
    results.frame_time = now - this_frame_start;
 | 
			
		||||
 | 
			
		||||
    last_frame_end = now;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TimingResultsAggregator::TimingResultsAggregator(size_t window_size)
 | 
			
		||||
    : max_window_size(window_size), window_size(0) {
 | 
			
		||||
    interframe_times.resize(window_size, Duration::zero());
 | 
			
		||||
    frame_times.resize(window_size, Duration::zero());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TimingResultsAggregator::Clear() {
 | 
			
		||||
    window_size = cursor = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TimingResultsAggregator::AddFrame(const ProfilingFrameResult& frame_result) {
 | 
			
		||||
    interframe_times[cursor] = frame_result.interframe_time;
 | 
			
		||||
    frame_times[cursor] = frame_result.frame_time;
 | 
			
		||||
 | 
			
		||||
    ++cursor;
 | 
			
		||||
    if (cursor == max_window_size)
 | 
			
		||||
        cursor = 0;
 | 
			
		||||
    if (window_size < max_window_size)
 | 
			
		||||
        ++window_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static AggregatedDuration AggregateField(const std::vector<Duration>& v, size_t len) {
 | 
			
		||||
    AggregatedDuration result;
 | 
			
		||||
    result.avg = Duration::zero();
 | 
			
		||||
    result.min = result.max = (len == 0 ? Duration::zero() : v[0]);
 | 
			
		||||
 | 
			
		||||
    for (size_t i = 0; i < len; ++i) {
 | 
			
		||||
        Duration value = v[i];
 | 
			
		||||
        result.avg += value;
 | 
			
		||||
        result.min = std::min(result.min, value);
 | 
			
		||||
        result.max = std::max(result.max, value);
 | 
			
		||||
    }
 | 
			
		||||
    if (len != 0)
 | 
			
		||||
        result.avg /= len;
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static float tof(Common::Profiling::Duration dur) {
 | 
			
		||||
    using FloatMs = std::chrono::duration<float, std::chrono::milliseconds::period>;
 | 
			
		||||
    return std::chrono::duration_cast<FloatMs>(dur).count();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AggregatedFrameResult TimingResultsAggregator::GetAggregatedResults() const {
 | 
			
		||||
    AggregatedFrameResult result;
 | 
			
		||||
 | 
			
		||||
    result.interframe_time = AggregateField(interframe_times, window_size);
 | 
			
		||||
    result.frame_time = AggregateField(frame_times, window_size);
 | 
			
		||||
 | 
			
		||||
    if (result.interframe_time.avg != Duration::zero()) {
 | 
			
		||||
        result.fps = 1000.0f / tof(result.interframe_time.avg);
 | 
			
		||||
    } else {
 | 
			
		||||
        result.fps = 0.0f;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ProfilingManager& GetProfilingManager() {
 | 
			
		||||
    // Takes advantage of "magic" static initialization for race-free initialization.
 | 
			
		||||
    static ProfilingManager manager;
 | 
			
		||||
    return manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SynchronizedRef<TimingResultsAggregator> GetTimingResultsAggregator() {
 | 
			
		||||
    static SynchronizedWrapper<TimingResultsAggregator> aggregator(30);
 | 
			
		||||
    return SynchronizedRef<TimingResultsAggregator>(aggregator);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Profiling
 | 
			
		||||
} // namespace Common
 | 
			
		||||
@@ -1,83 +0,0 @@
 | 
			
		||||
// Copyright 2015 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2 or any later version
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "common/synchronized_wrapper.h"
 | 
			
		||||
 | 
			
		||||
namespace Common {
 | 
			
		||||
namespace Profiling {
 | 
			
		||||
 | 
			
		||||
using Clock = std::chrono::high_resolution_clock;
 | 
			
		||||
using Duration = Clock::duration;
 | 
			
		||||
 | 
			
		||||
struct ProfilingFrameResult {
 | 
			
		||||
    /// Time since the last delivered frame
 | 
			
		||||
    Duration interframe_time;
 | 
			
		||||
 | 
			
		||||
    /// Time spent processing a frame, excluding VSync
 | 
			
		||||
    Duration frame_time;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ProfilingManager final {
 | 
			
		||||
public:
 | 
			
		||||
    ProfilingManager();
 | 
			
		||||
 | 
			
		||||
    /// This should be called after swapping screen buffers.
 | 
			
		||||
    void BeginFrame();
 | 
			
		||||
    /// This should be called before swapping screen buffers.
 | 
			
		||||
    void FinishFrame();
 | 
			
		||||
 | 
			
		||||
    /// Get the timing results from the previous frame. This is updated when you call FinishFrame().
 | 
			
		||||
    const ProfilingFrameResult& GetPreviousFrameResults() const {
 | 
			
		||||
        return results;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Clock::time_point last_frame_end;
 | 
			
		||||
    Clock::time_point this_frame_start;
 | 
			
		||||
 | 
			
		||||
    ProfilingFrameResult results;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct AggregatedDuration {
 | 
			
		||||
    Duration avg, min, max;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct AggregatedFrameResult {
 | 
			
		||||
    /// Time since the last delivered frame
 | 
			
		||||
    AggregatedDuration interframe_time;
 | 
			
		||||
 | 
			
		||||
    /// Time spent processing a frame, excluding VSync
 | 
			
		||||
    AggregatedDuration frame_time;
 | 
			
		||||
 | 
			
		||||
    float fps;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TimingResultsAggregator final {
 | 
			
		||||
public:
 | 
			
		||||
    TimingResultsAggregator(size_t window_size);
 | 
			
		||||
 | 
			
		||||
    void Clear();
 | 
			
		||||
 | 
			
		||||
    void AddFrame(const ProfilingFrameResult& frame_result);
 | 
			
		||||
 | 
			
		||||
    AggregatedFrameResult GetAggregatedResults() const;
 | 
			
		||||
 | 
			
		||||
    size_t max_window_size;
 | 
			
		||||
    size_t window_size;
 | 
			
		||||
    size_t cursor;
 | 
			
		||||
 | 
			
		||||
    std::vector<Duration> interframe_times;
 | 
			
		||||
    std::vector<Duration> frame_times;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ProfilingManager& GetProfilingManager();
 | 
			
		||||
SynchronizedRef<TimingResultsAggregator> GetTimingResultsAggregator();
 | 
			
		||||
 | 
			
		||||
} // namespace Profiling
 | 
			
		||||
} // namespace Common
 | 
			
		||||
@@ -10,7 +10,6 @@
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/bit_field.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/profiler_reporting.h"
 | 
			
		||||
#include "common/synchronized_wrapper.h"
 | 
			
		||||
#include "core/core.h"
 | 
			
		||||
#include "core/frontend/emu_window.h"
 | 
			
		||||
@@ -146,12 +145,6 @@ void RendererOpenGL::SwapBuffers() {
 | 
			
		||||
 | 
			
		||||
    DrawScreens();
 | 
			
		||||
 | 
			
		||||
    auto& profiler = Common::Profiling::GetProfilingManager();
 | 
			
		||||
    profiler.FinishFrame();
 | 
			
		||||
    {
 | 
			
		||||
        auto aggregator = Common::Profiling::GetTimingResultsAggregator();
 | 
			
		||||
        aggregator->AddFrame(profiler.GetPreviousFrameResults());
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        auto perf_stats = Core::System::GetInstance().perf_stats.Lock();
 | 
			
		||||
        perf_stats->EndSystemFrame();
 | 
			
		||||
@@ -163,7 +156,6 @@ void RendererOpenGL::SwapBuffers() {
 | 
			
		||||
 | 
			
		||||
    prev_state.Apply();
 | 
			
		||||
 | 
			
		||||
    profiler.BeginFrame();
 | 
			
		||||
    {
 | 
			
		||||
        auto perf_stats = Core::System::GetInstance().perf_stats.Lock();
 | 
			
		||||
        perf_stats->BeginSystemFrame();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user