BsProfilerOverlay.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #include "BsProfilerOverlay.h"
  2. #include "CmSceneObject.h"
  3. #include "BsGUIWidget.h"
  4. #include "BsGUIArea.h"
  5. #include "BsGUILayout.h"
  6. #include "BsGUIElement.h"
  7. #include "BsGUILabel.h"
  8. #include "BsGUISpace.h"
  9. #include "BsEngineGUI.h"
  10. #include "CmProfiler.h"
  11. #include "CmViewport.h"
  12. using namespace CamelotFramework;
  13. namespace BansheeEngine
  14. {
  15. class BasicRowFiller
  16. {
  17. public:
  18. UINT32 curIdx;
  19. GUILayout& labelLayout;
  20. GUILayout& contentLayout;
  21. GUIWidget& widget;
  22. Vector<ProfilerOverlay::BasicRow>::type& rows;
  23. BasicRowFiller(Vector<ProfilerOverlay::BasicRow>::type& _rows, GUILayout& _labelLayout, GUILayout& _contentLayout, GUIWidget& _widget)
  24. :rows(_rows), curIdx(0), labelLayout(_labelLayout), contentLayout(_contentLayout), widget(_widget)
  25. { }
  26. ~BasicRowFiller()
  27. {
  28. UINT32 excessEntries = (UINT32)rows.size() - curIdx;
  29. for(UINT32 i = 0; i < excessEntries; i++)
  30. {
  31. labelLayout.removeChildAt(labelLayout.getNumChildren() - 2); // -2 because last element is flexible space and we want to skip it
  32. contentLayout.removeChildAt(contentLayout.getNumChildren() - 2); // -2 because last element is flexible space and we want to skip it
  33. ProfilerOverlay::BasicRow& row = rows[curIdx + i];
  34. for(auto& element : row.elements)
  35. GUIElement::destroy(element);
  36. }
  37. rows.resize(curIdx);
  38. }
  39. void addData(UINT32 depth, const String& name, float pctOfParent, UINT32 numCalls, UINT64 numAllocs,
  40. UINT64 numFrees, double avgTime, double totalTime, double avgSelfTime, double totalSelfTime)
  41. {
  42. if(curIdx >= rows.size())
  43. {
  44. rows.push_back(ProfilerOverlay::BasicRow());
  45. ProfilerOverlay::BasicRow& newRow = rows.back();
  46. newRow.name = HString(L"{0}");
  47. newRow.pctOfParent = HString(L"{0} %");
  48. newRow.numCalls = HString(L"{0}");
  49. newRow.numAllocs = HString(L"{0}");
  50. newRow.numFrees = HString(L"{0}");
  51. newRow.avgTime = HString(L"{0}");
  52. newRow.totalTime = HString(L"{0}");
  53. newRow.avgTimeSelf = HString(L"{0}");
  54. newRow.totalTimeSelf = HString(L"{0}");
  55. newRow.labelLayout = &labelLayout.insertLayoutX(labelLayout.getNumChildren() - 1); // Insert before flexible space
  56. newRow.contentLayout = &contentLayout.insertLayoutX(contentLayout.getNumChildren() - 1); // Insert before flexible space
  57. GUILabel* name = GUILabel::create(widget, newRow.name, GUIOptions(GUIOption::fixedWidth(200)));
  58. GUILabel* pctOfParent = GUILabel::create(widget, newRow.pctOfParent, GUIOptions(GUIOption::fixedWidth(50)));
  59. GUILabel* numCalls = GUILabel::create(widget, newRow.numCalls, GUIOptions(GUIOption::fixedWidth(50)));
  60. GUILabel* numAllocs = GUILabel::create(widget, newRow.numAllocs, GUIOptions(GUIOption::fixedWidth(50)));
  61. GUILabel* numFrees = GUILabel::create(widget, newRow.numFrees, GUIOptions(GUIOption::fixedWidth(50)));
  62. GUILabel* avgTime = GUILabel::create(widget, newRow.avgTime, GUIOptions(GUIOption::fixedWidth(60)));
  63. GUILabel* totalTime = GUILabel::create(widget, newRow.totalTime, GUIOptions(GUIOption::fixedWidth(60)));
  64. GUILabel* avgTimeSelf = GUILabel::create(widget, newRow.avgTimeSelf, GUIOptions(GUIOption::fixedWidth(100)));
  65. GUILabel* totalTimeSelf = GUILabel::create(widget, newRow.totalTimeSelf, GUIOptions(GUIOption::fixedWidth(100)));
  66. newRow.labelLayout->addSpace(0);
  67. newRow.labelLayout->addElement(name);
  68. newRow.contentLayout->addElement(pctOfParent);
  69. newRow.contentLayout->addElement(numCalls);
  70. newRow.contentLayout->addElement(numAllocs);
  71. newRow.contentLayout->addElement(numFrees);
  72. newRow.contentLayout->addElement(avgTime);
  73. newRow.contentLayout->addElement(totalTime);
  74. newRow.contentLayout->addElement(avgTimeSelf);
  75. newRow.contentLayout->addElement(totalTimeSelf);
  76. newRow.elements.push_back(name);
  77. newRow.elements.push_back(pctOfParent);
  78. newRow.elements.push_back(numCalls);
  79. newRow.elements.push_back(numAllocs);
  80. newRow.elements.push_back(numFrees);
  81. newRow.elements.push_back(avgTime);
  82. newRow.elements.push_back(totalTime);
  83. newRow.elements.push_back(avgTimeSelf);
  84. newRow.elements.push_back(totalTimeSelf);
  85. }
  86. ProfilerOverlay::BasicRow& row = rows[curIdx];
  87. row.labelLayout->removeChildAt(0);
  88. row.labelLayout->insertSpace(0, depth * 20);
  89. row.name.setParameter(0, toWString(name));
  90. row.pctOfParent.setParameter(0, toWString(pctOfParent * 100.0f, 2, 0, ' ', std::ios::fixed));
  91. row.numCalls.setParameter(0, toWString(numCalls));
  92. row.numAllocs.setParameter(0, toWString(numAllocs));
  93. row.numFrees.setParameter(0, toWString(numFrees));
  94. row.avgTime.setParameter(0, toWString(avgTime, 2, 0, ' ', std::ios::fixed));
  95. row.totalTime.setParameter(0, toWString(totalTime, 2, 0, ' ', std::ios::fixed));
  96. row.avgTimeSelf.setParameter(0, toWString(avgSelfTime, 2, 0, ' ', std::ios::fixed));
  97. row.totalTimeSelf.setParameter(0, toWString(totalSelfTime, 2, 0, ' ', std::ios::fixed));
  98. curIdx++;
  99. }
  100. };
  101. class PreciseRowFiller
  102. {
  103. public:
  104. UINT32 curIdx;
  105. GUILayout& labelLayout;
  106. GUILayout& contentLayout;
  107. GUIWidget& widget;
  108. Vector<ProfilerOverlay::PreciseRow>::type& rows;
  109. PreciseRowFiller(Vector<ProfilerOverlay::PreciseRow>::type& _rows, GUILayout& _labelLayout, GUILayout& _contentLayout, GUIWidget& _widget)
  110. :rows(_rows), curIdx(0), labelLayout(_labelLayout), contentLayout(_contentLayout), widget(_widget)
  111. { }
  112. ~PreciseRowFiller()
  113. {
  114. UINT32 excessEntries = (UINT32)rows.size() - curIdx;
  115. for(UINT32 i = 0; i < excessEntries; i++)
  116. {
  117. labelLayout.removeChildAt(labelLayout.getNumChildren() - i - 1); // -1 because last element is flexible space and we want to skip it
  118. contentLayout.removeChildAt(contentLayout.getNumChildren() - i - 1); // -1 because last element is flexible space and we want to skip it
  119. ProfilerOverlay::PreciseRow& row = rows[curIdx + i];
  120. for(auto& element : row.elements)
  121. GUIElement::destroy(element);
  122. }
  123. rows.resize(curIdx);
  124. }
  125. void addData(UINT32 depth, const String& name, float pctOfParent, UINT32 numCalls, UINT64 numAllocs,
  126. UINT64 numFrees, UINT64 avgCycles, UINT64 totalCycles, UINT64 avgSelfCycles, UINT64 totalSelfCycles)
  127. {
  128. if(curIdx >= rows.size())
  129. {
  130. rows.push_back(ProfilerOverlay::PreciseRow());
  131. ProfilerOverlay::PreciseRow& newRow = rows.back();
  132. newRow.name = HString(L"{0}");
  133. newRow.pctOfParent = HString(L"{0}");
  134. newRow.numCalls = HString(L"{0}");
  135. newRow.numAllocs = HString(L"{0}");
  136. newRow.numFrees = HString(L"{0}");
  137. newRow.avgCycles = HString(L"{0}");
  138. newRow.totalCycles = HString(L"{0}");
  139. newRow.avgCyclesSelf = HString(L"{0}");
  140. newRow.totalCyclesSelf = HString(L"{0}");
  141. newRow.labelLayout = &labelLayout.insertLayoutX(labelLayout.getNumChildren() - 1); // Insert before flexible space
  142. newRow.contentLayout = &contentLayout.insertLayoutX(contentLayout.getNumChildren() - 1); // Insert before flexible space
  143. GUILabel* name = GUILabel::create(widget, newRow.name, GUIOptions(GUIOption::fixedWidth(200)));
  144. GUILabel* pctOfParent = GUILabel::create(widget, newRow.pctOfParent, GUIOptions(GUIOption::fixedWidth(50)));
  145. GUILabel* numCalls = GUILabel::create(widget, newRow.numCalls, GUIOptions(GUIOption::fixedWidth(50)));
  146. GUILabel* numAllocs = GUILabel::create(widget, newRow.numAllocs, GUIOptions(GUIOption::fixedWidth(50)));
  147. GUILabel* numFrees = GUILabel::create(widget, newRow.numFrees, GUIOptions(GUIOption::fixedWidth(50)));
  148. GUILabel* avgCycles = GUILabel::create(widget, newRow.avgCycles,GUIOptions(GUIOption::fixedWidth(60)));
  149. GUILabel* totalCycles = GUILabel::create(widget, newRow.totalCycles, GUIOptions(GUIOption::fixedWidth(60)));
  150. GUILabel* avgCyclesSelf = GUILabel::create(widget, newRow.avgCyclesSelf, GUIOptions(GUIOption::fixedWidth(100)));
  151. GUILabel* totalCyclesSelf = GUILabel::create(widget, newRow.totalCyclesSelf, GUIOptions(GUIOption::fixedWidth(100)));
  152. newRow.labelLayout->addSpace(0);
  153. newRow.labelLayout->addElement(name);
  154. newRow.contentLayout->addElement(pctOfParent);
  155. newRow.contentLayout->addElement(numCalls);
  156. newRow.contentLayout->addElement(numAllocs);
  157. newRow.contentLayout->addElement(numFrees);
  158. newRow.contentLayout->addElement(avgCycles);
  159. newRow.contentLayout->addElement(totalCycles);
  160. newRow.contentLayout->addElement(avgCyclesSelf);
  161. newRow.contentLayout->addElement(totalCyclesSelf);
  162. newRow.elements.push_back(name);
  163. newRow.elements.push_back(pctOfParent);
  164. newRow.elements.push_back(numCalls);
  165. newRow.elements.push_back(numAllocs);
  166. newRow.elements.push_back(numFrees);
  167. newRow.elements.push_back(avgCycles);
  168. newRow.elements.push_back(totalCycles);
  169. newRow.elements.push_back(avgCyclesSelf);
  170. newRow.elements.push_back(totalCyclesSelf);
  171. }
  172. ProfilerOverlay::PreciseRow& row = rows[curIdx];
  173. row.labelLayout->removeChildAt(0);
  174. row.labelLayout->insertSpace(0, depth * 20);
  175. row.name.setParameter(0, toWString(name));
  176. row.pctOfParent.setParameter(0, toWString(pctOfParent * 100.0f, 2, 0, ' ', std::ios::fixed));
  177. row.numCalls.setParameter(0, toWString(numCalls));
  178. row.numAllocs.setParameter(0, toWString(numAllocs));
  179. row.numFrees.setParameter(0, toWString(numFrees));
  180. row.avgCycles.setParameter(0, toWString(avgCycles));
  181. row.totalCycles.setParameter(0, toWString(totalCycles));
  182. row.avgCyclesSelf.setParameter(0, toWString(avgSelfCycles));
  183. row.totalCyclesSelf.setParameter(0, toWString(totalSelfCycles));
  184. curIdx++;
  185. }
  186. };
  187. const UINT32 ProfilerOverlay::MAX_DEPTH = 4;
  188. ProfilerOverlay::ProfilerOverlay(const CM::ViewportPtr& target)
  189. :mIsShown(false), mBasicAreaLabels(nullptr), mPreciseAreaLabels(nullptr), mBasicAreaContents(nullptr), mPreciseAreaContents(nullptr),
  190. mBasicLayoutLabels(nullptr), mPreciseLayoutLabels(nullptr), mBasicLayoutContents(nullptr), mPreciseLayoutContents(nullptr),
  191. mTitleBasicName(nullptr), mTitleBasicPctOfParent(nullptr), mTitleBasicNumCalls(nullptr), mTitleBasicNumAllocs(nullptr), mTitleBasicNumFrees(nullptr),
  192. mTitleBasicAvgTime(nullptr), mTitleBasicTotalTime(nullptr), mTitleBasicAvgTitleSelf(nullptr), mTitleBasicTotalTimeSelf(nullptr),
  193. mTitlePreciseName(nullptr), mTitlePrecisePctOfParent(nullptr), mTitlePreciseNumCalls(nullptr), mTitlePreciseNumAllocs(nullptr),
  194. mTitlePreciseNumFrees(nullptr), mTitlePreciseAvgCycles(nullptr), mTitlePreciseTotalCycles(nullptr), mTitlePreciseAvgCyclesSelf(nullptr),
  195. mTitlePreciseTotalCyclesSelf(nullptr)
  196. {
  197. setTarget(target);
  198. }
  199. ProfilerOverlay::~ProfilerOverlay()
  200. {
  201. if(mIsShown)
  202. hide();
  203. if(mTarget != nullptr)
  204. mTargetResizedConn.disconnect();
  205. if(mWidgetSO)
  206. mWidgetSO->destroy();
  207. }
  208. void ProfilerOverlay::setTarget(const CM::ViewportPtr& target)
  209. {
  210. if(mTarget != nullptr)
  211. mTargetResizedConn.disconnect();
  212. mTarget = target;
  213. mTargetResizedConn = target->onResized.connect(boost::bind(&ProfilerOverlay::targetResized, this));
  214. if(mWidgetSO)
  215. mWidgetSO->destroy();
  216. mWidgetSO = SceneObject::create("ProfilerOverlay");
  217. mWidget = mWidgetSO->addComponent<GUIWidget>(mTarget.get());
  218. mWidget->setDepth(127);
  219. mWidget->setSkin(EngineGUI::instance().getSkin());
  220. mBasicAreaLabels = GUIArea::create(*mWidget, 0, 0);
  221. mPreciseAreaLabels = GUIArea::create(*mWidget, 0, 0);
  222. mBasicAreaContents = GUIArea::create(*mWidget, 0, 0);
  223. mPreciseAreaContents = GUIArea::create(*mWidget, 0, 0);
  224. mBasicLayoutLabels = &mBasicAreaLabels->getLayout().addLayoutY();
  225. mPreciseLayoutLabels = &mPreciseAreaLabels->getLayout().addLayoutY();
  226. mBasicLayoutContents = &mBasicAreaContents->getLayout().addLayoutY();
  227. mPreciseLayoutContents = &mPreciseAreaContents->getLayout().addLayoutY();
  228. // Set up title bars
  229. mTitleBasicName = GUILabel::create(*mWidget, HString(L"Name"), GUIOptions(GUIOption::fixedWidth(200)));
  230. mTitleBasicPctOfParent = GUILabel::create(*mWidget, HString(L"% parent"), GUIOptions(GUIOption::fixedWidth(50)));
  231. mTitleBasicNumCalls = GUILabel::create(*mWidget, HString(L"# calls"), GUIOptions(GUIOption::fixedWidth(50)));
  232. mTitleBasicNumAllocs = GUILabel::create(*mWidget, HString(L"# allocs"), GUIOptions(GUIOption::fixedWidth(50)));
  233. mTitleBasicNumFrees = GUILabel::create(*mWidget, HString(L"# frees"), GUIOptions(GUIOption::fixedWidth(50)));
  234. mTitleBasicAvgTime = GUILabel::create(*mWidget, HString(L"Avg. time"), GUIOptions(GUIOption::fixedWidth(60)));
  235. mTitleBasicTotalTime = GUILabel::create(*mWidget, HString(L"Total time"), GUIOptions(GUIOption::fixedWidth(60)));
  236. mTitleBasicAvgTitleSelf = GUILabel::create(*mWidget, HString(L"Avg. self time"), GUIOptions(GUIOption::fixedWidth(100)));
  237. mTitleBasicTotalTimeSelf = GUILabel::create(*mWidget, HString(L"Total self time"), GUIOptions(GUIOption::fixedWidth(100)));
  238. mTitlePreciseName = GUILabel::create(*mWidget, HString(L"Name"), GUIOptions(GUIOption::fixedWidth(200)));
  239. mTitlePrecisePctOfParent = GUILabel::create(*mWidget, HString(L"% parent"), GUIOptions(GUIOption::fixedWidth(50)));
  240. mTitlePreciseNumCalls = GUILabel::create(*mWidget, HString(L"# calls"), GUIOptions(GUIOption::fixedWidth(50)));
  241. mTitlePreciseNumAllocs = GUILabel::create(*mWidget, HString(L"# allocs"), GUIOptions(GUIOption::fixedWidth(50)));
  242. mTitlePreciseNumFrees = GUILabel::create(*mWidget, HString(L"# frees"), GUIOptions(GUIOption::fixedWidth(50)));
  243. mTitlePreciseAvgCycles = GUILabel::create(*mWidget, HString(L"Avg. cycles"), GUIOptions(GUIOption::fixedWidth(60)));
  244. mTitlePreciseTotalCycles = GUILabel::create(*mWidget, HString(L"Total cycles"), GUIOptions(GUIOption::fixedWidth(60)));
  245. mTitlePreciseAvgCyclesSelf = GUILabel::create(*mWidget, HString(L"Avg. self cycles"), GUIOptions(GUIOption::fixedWidth(100)));
  246. mTitlePreciseTotalCyclesSelf = GUILabel::create(*mWidget, HString(L"Total self cycles"), GUIOptions(GUIOption::fixedWidth(100)));
  247. GUILayout& basicTitleLabelLayout = mBasicLayoutLabels->addLayoutX();
  248. GUILayout& preciseTitleLabelLayout = mPreciseLayoutLabels->addLayoutX();
  249. GUILayout& basicTitleContentLayout = mBasicLayoutContents->addLayoutX();
  250. GUILayout& preciseTitleContentLayout = mPreciseLayoutContents->addLayoutX();
  251. basicTitleLabelLayout.addElement(mTitleBasicName);
  252. basicTitleContentLayout.addElement(mTitleBasicPctOfParent);
  253. basicTitleContentLayout.addElement(mTitleBasicNumCalls);
  254. basicTitleContentLayout.addElement(mTitleBasicNumAllocs);
  255. basicTitleContentLayout.addElement(mTitleBasicNumFrees);
  256. basicTitleContentLayout.addElement(mTitleBasicAvgTime);
  257. basicTitleContentLayout.addElement(mTitleBasicTotalTime);
  258. basicTitleContentLayout.addElement(mTitleBasicAvgTitleSelf);
  259. basicTitleContentLayout.addElement(mTitleBasicTotalTimeSelf);
  260. preciseTitleLabelLayout.addElement(mTitlePreciseName);
  261. preciseTitleContentLayout.addElement(mTitlePrecisePctOfParent);
  262. preciseTitleContentLayout.addElement(mTitlePreciseNumCalls);
  263. preciseTitleContentLayout.addElement(mTitlePreciseNumAllocs);
  264. preciseTitleContentLayout.addElement(mTitlePreciseNumFrees);
  265. preciseTitleContentLayout.addElement(mTitlePreciseAvgCycles);
  266. preciseTitleContentLayout.addElement(mTitlePreciseTotalCycles);
  267. preciseTitleContentLayout.addElement(mTitlePreciseAvgCyclesSelf);
  268. preciseTitleContentLayout.addElement(mTitlePreciseTotalCyclesSelf);
  269. mBasicLayoutLabels->addFlexibleSpace();
  270. mPreciseLayoutLabels->addFlexibleSpace();
  271. mBasicLayoutContents->addFlexibleSpace();
  272. mPreciseLayoutContents->addFlexibleSpace();
  273. updateAreaSizes();
  274. }
  275. void ProfilerOverlay::show()
  276. {
  277. if(mIsShown)
  278. return;
  279. mBasicAreaLabels->enable();
  280. mPreciseAreaLabels->enable();
  281. mBasicAreaContents->enable();
  282. mPreciseAreaContents->enable();
  283. mIsShown = true;
  284. }
  285. void ProfilerOverlay::hide()
  286. {
  287. if(!mIsShown)
  288. return;
  289. mBasicAreaLabels->disable();
  290. mPreciseAreaLabels->disable();
  291. mBasicAreaContents->disable();
  292. mPreciseAreaContents->disable();
  293. mIsShown = false;
  294. }
  295. void ProfilerOverlay::update()
  296. {
  297. const ProfilerReport& latestSimReport = Profiler::instance().getReport(ProfiledThread::Sim);
  298. const ProfilerReport& latestCoreReport = Profiler::instance().getReport(ProfiledThread::Core);
  299. updateContents(latestSimReport, latestCoreReport);
  300. }
  301. void ProfilerOverlay::targetResized()
  302. {
  303. updateAreaSizes();
  304. }
  305. void ProfilerOverlay::updateAreaSizes()
  306. {
  307. static const INT32 PADDING = 10;
  308. static const float LABELS_CONTENT_RATIO = 0.3f;
  309. UINT32 width = (UINT32)std::max(0, (INT32)mTarget->getWidth() - PADDING * 2);
  310. UINT32 height = (UINT32)std::max(0, (INT32)(mTarget->getHeight() - PADDING * 3)/2);
  311. UINT32 labelsWidth = Math::ceilToInt(width * LABELS_CONTENT_RATIO);
  312. UINT32 contentWidth = width - labelsWidth;
  313. mBasicAreaLabels->setPosition(PADDING, PADDING);
  314. mBasicAreaLabels->setSize(labelsWidth, height);
  315. mPreciseAreaLabels->setPosition(PADDING, height + PADDING * 2);
  316. mPreciseAreaLabels->setSize(labelsWidth, height);
  317. mBasicAreaContents->setPosition(PADDING + labelsWidth, PADDING);
  318. mBasicAreaContents->setSize(contentWidth, height);
  319. mPreciseAreaContents->setPosition(PADDING + labelsWidth, height + PADDING * 2);
  320. mPreciseAreaContents->setSize(contentWidth, height);
  321. }
  322. void ProfilerOverlay::updateContents(const CM::ProfilerReport& simReport, const CM::ProfilerReport& coreReport)
  323. {
  324. static const UINT32 NUM_ROOT_ENTRIES = 2;
  325. const CPUProfilerBasicSamplingEntry& simBasicRootEntry = simReport.cpuReport.getBasicSamplingData();
  326. const CPUProfilerPreciseSamplingEntry& simPreciseRootEntry = simReport.cpuReport.getPreciseSamplingData();
  327. const CPUProfilerBasicSamplingEntry& coreBasicRootEntry = coreReport.cpuReport.getBasicSamplingData();
  328. const CPUProfilerPreciseSamplingEntry& corePreciseRootEntry = coreReport.cpuReport.getPreciseSamplingData();
  329. struct TodoBasic
  330. {
  331. TodoBasic(const CPUProfilerBasicSamplingEntry& _entry, UINT32 _depth)
  332. :entry(_entry), depth(_depth)
  333. { }
  334. const CPUProfilerBasicSamplingEntry& entry;
  335. UINT32 depth;
  336. };
  337. struct TodoPrecise
  338. {
  339. TodoPrecise(const CPUProfilerPreciseSamplingEntry& _entry, UINT32 _depth)
  340. :entry(_entry), depth(_depth)
  341. { }
  342. const CPUProfilerPreciseSamplingEntry& entry;
  343. UINT32 depth;
  344. };
  345. BasicRowFiller basicRowFiller(mBasicRows, *mBasicLayoutLabels, *mBasicLayoutContents, *mWidget);
  346. Stack<TodoBasic>::type todoBasic;
  347. const CPUProfilerBasicSamplingEntry* basicRootEntries[NUM_ROOT_ENTRIES];
  348. basicRootEntries[0] = &simBasicRootEntry;
  349. basicRootEntries[1] = &coreBasicRootEntry;
  350. for(UINT32 i = 0; i < NUM_ROOT_ENTRIES; i++)
  351. {
  352. todoBasic.push(TodoBasic(*basicRootEntries[i], 0));
  353. while(!todoBasic.empty())
  354. {
  355. TodoBasic curEntry = todoBasic.top();
  356. todoBasic.pop();
  357. const CPUProfilerBasicSamplingEntry::Data& data = curEntry.entry.data;
  358. basicRowFiller.addData(curEntry.depth, data.name, data.pctOfParent, data.numCalls, data.memAllocs, data.memFrees,
  359. data.avgTimeMs, data.totalTimeMs, data.avgSelfTimeMs, data.totalSelfTimeMs);
  360. if(curEntry.depth <= MAX_DEPTH)
  361. {
  362. for(auto iter = curEntry.entry.childEntries.rbegin(); iter != curEntry.entry.childEntries.rend(); ++iter)
  363. {
  364. todoBasic.push(TodoBasic(*iter, curEntry.depth + 1));
  365. }
  366. }
  367. }
  368. }
  369. PreciseRowFiller preciseRowFiller(mPreciseRows, *mBasicLayoutLabels, *mBasicLayoutContents, *mWidget);
  370. Stack<TodoPrecise>::type todoPrecise;
  371. const CPUProfilerPreciseSamplingEntry* preciseRootEntries[NUM_ROOT_ENTRIES];
  372. preciseRootEntries[0] = &simPreciseRootEntry;
  373. preciseRootEntries[1] = &corePreciseRootEntry;
  374. for(UINT32 i = 0; i < NUM_ROOT_ENTRIES; i++)
  375. {
  376. todoPrecise.push(TodoPrecise(*preciseRootEntries[i], 0));
  377. while(!todoBasic.empty())
  378. {
  379. TodoPrecise curEntry = todoPrecise.top();
  380. todoPrecise.pop();
  381. const CPUProfilerPreciseSamplingEntry::Data& data = curEntry.entry.data;
  382. preciseRowFiller.addData(curEntry.depth, data.name, data.pctOfParent, data.numCalls, data.memAllocs, data.memFrees,
  383. data.avgCycles, data.totalCycles, data.avgSelfCycles, data.totalSelfCycles);
  384. if(curEntry.depth <= MAX_DEPTH)
  385. {
  386. for(auto iter = curEntry.entry.childEntries.rbegin(); iter != curEntry.entry.childEntries.rend(); ++iter)
  387. {
  388. todoPrecise.push(TodoPrecise(*iter, curEntry.depth + 1));
  389. }
  390. }
  391. }
  392. }
  393. }
  394. }