Serenity Operating System
1/*
2 * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include "SamplesModel.h"
9#include "Profile.h"
10#include <AK/StringBuilder.h>
11
12namespace Profiler {
13
14SamplesModel::SamplesModel(Profile& profile)
15 : m_profile(profile)
16{
17 m_user_frame_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/inspector-object.png"sv).release_value_but_fixme_should_propagate_errors());
18 m_kernel_frame_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/inspector-object-red.png"sv).release_value_but_fixme_should_propagate_errors());
19}
20
21int SamplesModel::row_count(GUI::ModelIndex const&) const
22{
23 return m_profile.filtered_event_indices().size();
24}
25
26int SamplesModel::column_count(GUI::ModelIndex const&) const
27{
28 return Column::__Count;
29}
30
31DeprecatedString SamplesModel::column_name(int column) const
32{
33 switch (column) {
34 case Column::SampleIndex:
35 return "#";
36 case Column::Timestamp:
37 return "Timestamp";
38 case Column::ProcessID:
39 return "PID";
40 case Column::ThreadID:
41 return "TID";
42 case Column::ExecutableName:
43 return "Executable";
44 case Column::LostSamples:
45 return "Lost Samples";
46 case Column::InnermostStackFrame:
47 return "Innermost Frame";
48 case Column::Path:
49 return "Path";
50 default:
51 VERIFY_NOT_REACHED();
52 }
53}
54
55GUI::Variant SamplesModel::data(GUI::ModelIndex const& index, GUI::ModelRole role) const
56{
57 u32 event_index = m_profile.filtered_event_indices()[index.row()];
58 auto const& event = m_profile.events().at(event_index);
59
60 if (role == GUI::ModelRole::Custom) {
61 return event_index;
62 }
63
64 if (role == GUI::ModelRole::Display) {
65 if (index.column() == Column::SampleIndex)
66 return event_index;
67
68 if (index.column() == Column::ProcessID)
69 return event.pid;
70
71 if (index.column() == Column::ThreadID)
72 return event.tid;
73
74 if (index.column() == Column::ExecutableName) {
75 if (auto const* process = m_profile.find_process(event.pid, event.serial))
76 return process->executable;
77 return "";
78 }
79
80 if (index.column() == Column::Timestamp) {
81 return (u32)event.timestamp;
82 }
83
84 if (index.column() == Column::LostSamples) {
85 return event.lost_samples;
86 }
87
88 if (index.column() == Column::InnermostStackFrame) {
89 return event.frames.last().symbol;
90 }
91
92 if (index.column() == Column::Path) {
93 if (!event.data.has<Profile::Event::ReadData>())
94 return "";
95 return event.data.get<Profile::Event::ReadData>().path;
96 }
97
98 return {};
99 }
100 return {};
101}
102
103}