ShaderManagementConsoleStatisticView.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/RPI.Edit/Common/AssetUtils.h>
  9. #include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
  10. #include <Window/ShaderManagementConsoleStatisticView.h>
  11. #include <ShaderManagementConsoleRequestBus.h>
  12. #include <QHeaderView>
  13. #include <QMenu>
  14. #include <QMessageBox>
  15. #include <QProgressDialog>
  16. namespace ShaderManagementConsole
  17. {
  18. ShaderManagementConsoleStatisticView::ShaderManagementConsoleStatisticView(ShaderVariantStatisticData statisticData, QWidget* parent)
  19. : QTableWidget(parent)
  20. {
  21. setEditTriggers(QAbstractItemView::NoEditTriggers);
  22. setSelectionBehavior(QAbstractItemView::SelectItems);
  23. setSelectionMode(QAbstractItemView::NoSelection);
  24. horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
  25. setContextMenuPolicy(Qt::CustomContextMenu);
  26. m_statisticData = statisticData;
  27. BuildTable();
  28. }
  29. ShaderManagementConsoleStatisticView::~ShaderManagementConsoleStatisticView()
  30. {
  31. }
  32. void ShaderManagementConsoleStatisticView::BuildTable()
  33. {
  34. QSignalBlocker blocker(this);
  35. clear();
  36. setRowCount(static_cast<int>(m_statisticData.m_shaderVariantUsage.size()));
  37. setColumnCount(static_cast<int>(m_statisticData.m_shaderOptionUsage.size()));
  38. int optionColumn = 0;
  39. for (auto const& optionUsage : m_statisticData.m_shaderOptionUsage)
  40. {
  41. AZ::Name optionName = optionUsage.first;
  42. setHorizontalHeaderItem(optionColumn, new QTableWidgetItem(optionName.GetCStr()));
  43. optionColumn++;
  44. }
  45. int row = 0;
  46. for (auto const& variantUsage : m_statisticData.m_shaderVariantUsage)
  47. {
  48. ShaderVariantInfo info = variantUsage.second;
  49. auto* countVHeader = new QTableWidgetItem(QString::number(info.m_count));
  50. countVHeader->setToolTip(tr("Count of materials x shaders using this variant ID"));
  51. setVerticalHeaderItem(row, countVHeader);
  52. for (int column = 0; column < columnCount(); ++column)
  53. {
  54. QTableWidgetItem* widgetItem = horizontalHeaderItem(column);
  55. for (auto& shaderOptionDescriptor : info.m_shaderOptionGroup.GetShaderOptionDescriptors())
  56. {
  57. AZ::Name optionName = shaderOptionDescriptor.GetName();
  58. AZ::RPI::ShaderOptionValue optionValue = info.m_shaderOptionGroup.GetValue(optionName);
  59. if (!optionValue.IsValid())
  60. {
  61. continue;
  62. }
  63. AZ::Name valueName = shaderOptionDescriptor.GetValueName(optionValue);
  64. QByteArray ba = widgetItem->text().toLocal8Bit();
  65. const char* columnTitle = ba.data();
  66. if (strcmp(columnTitle, optionName.GetCStr()) == 0)
  67. {
  68. int count = m_statisticData.m_shaderOptionUsage[optionName][valueName];
  69. AZStd::string itemText = AZStd::string::format("%s %d", valueName.GetCStr(), count);
  70. auto* cellWidget = new QTableWidgetItem(itemText.c_str());
  71. cellWidget->setToolTip(tr(reinterpret_cast<const char*>(u8"value \u23B5 usage count of this value")));
  72. setItem(row, column, cellWidget);
  73. break;
  74. }
  75. }
  76. }
  77. row++;
  78. }
  79. connect(this, &QTableWidget::customContextMenuRequested, this, &ShaderManagementConsoleStatisticView::ShowContextMenu);
  80. }
  81. void ShaderManagementConsoleStatisticView::ShowContextMenu(const QPoint& pos)
  82. {
  83. //QTableWidgetItem* item = itemAt(pos);
  84. QMenu contextMenu(tr("Context menu"), this);
  85. QString optionText = horizontalHeaderItem(currentColumn())->text();
  86. AZ::Name optionName = AZ::Name(optionText.toLocal8Bit().data());
  87. QAction* action = new QAction(QString(tr("See materials using %1")).arg(optionText), this);
  88. connect(action, &QAction::triggered, this, [this, optionName]() {
  89. ShowMaterialList(optionName);
  90. });
  91. contextMenu.addAction(action);
  92. contextMenu.exec(mapToGlobal(pos));
  93. }
  94. void ShaderManagementConsoleStatisticView::ShowMaterialList(AZ::Name optionName)
  95. {
  96. AZStd::vector<AZ::Data::AssetId> materialAssetIdList;
  97. ShaderManagementConsoleRequestBus::BroadcastResult(
  98. materialAssetIdList, &ShaderManagementConsoleRequestBus::Events::GetAllMaterialAssetIds);
  99. QString materialList;
  100. QProgressDialog progressDialog(AzToolsFramework::GetActiveWindow());
  101. progressDialog.setWindowModality(Qt::WindowModal);
  102. progressDialog.setMaximum(static_cast<int>(materialAssetIdList.size()));
  103. progressDialog.setMaximumWidth(400);
  104. progressDialog.setMaximumHeight(100);
  105. progressDialog.setWindowTitle(tr("Gather information from material assets"));
  106. progressDialog.setLabelText(tr("Gather shader variant information..."));
  107. int materialCount = 0;
  108. for (int i = 0; i < materialAssetIdList.size(); ++i)
  109. {
  110. AZStd::vector<AZ::RPI::ShaderCollection::Item> shaderItemList;
  111. ShaderManagementConsoleRequestBus::BroadcastResult(
  112. shaderItemList, &ShaderManagementConsoleRequestBus::Events::GetMaterialInstanceShaderItems, materialAssetIdList[i]);
  113. for (auto& shaderItem : shaderItemList)
  114. {
  115. bool found = false;
  116. for (auto& descriptor : shaderItem.GetShaderOptionGroup().GetShaderOptionDescriptors())
  117. {
  118. if (descriptor.GetName() == optionName)
  119. {
  120. // the material is using this option
  121. AZ::IO::Path assetPath = AZ::IO::Path(AZ::RPI::AssetUtils::GetSourcePathByAssetId(materialAssetIdList[i]));
  122. materialList += QString(assetPath.Stem().Native().data());
  123. materialList += "\n";
  124. materialCount++;
  125. found = true;
  126. break;
  127. }
  128. }
  129. if (found)
  130. {
  131. break;
  132. }
  133. }
  134. progressDialog.setValue(i);
  135. if (progressDialog.wasCanceled())
  136. {
  137. return;
  138. }
  139. }
  140. progressDialog.close();
  141. if (!materialList.isEmpty())
  142. {
  143. QMessageBox msgBox(AzToolsFramework::GetActiveWindow());
  144. QString message = QString(tr("%2 materials used %1. Show details for the complete list."))
  145. .arg(optionName.GetCStr()).arg(QString::number(materialCount));
  146. msgBox.setText(message);
  147. msgBox.setDetailedText(materialList);
  148. msgBox.exec();
  149. }
  150. else
  151. {
  152. QMessageBox msgBox(AzToolsFramework::GetActiveWindow());
  153. msgBox.setText(tr("There are no material using this option now."));
  154. msgBox.exec();
  155. }
  156. }
  157. }