DebugComponent.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. #pragma once
  9. #include <AzCore/RTTI/RTTI.h>
  10. #include <AzCore/Asset/AssetCommon.h>
  11. #include <AzCore/Component/Component.h>
  12. #include <AzCore/Math/Vector3.h>
  13. #include <AzFramework/Entity/EntityDebugDisplayBus.h>
  14. #include <AzFramework/Visibility/BoundsBus.h>
  15. #include <AzCore/PlatformDef.h>
  16. #include <Vegetation/Ebuses/InstanceSystemRequestBus.h>
  17. #include <Vegetation/Ebuses/SystemConfigurationBus.h>
  18. #include <Vegetation/Ebuses/DebugRequestsBus.h>
  19. #include <Vegetation/Ebuses/DebugNotificationBus.h>
  20. #include <Vegetation/Ebuses/DebugSystemDataBus.h>
  21. #include <Vegetation/InstanceData.h>
  22. namespace LmbrCentral
  23. {
  24. template<typename, typename>
  25. class EditorWrappedComponentBase;
  26. }
  27. namespace Vegetation
  28. {
  29. //////////////////////////////////////////////////////////////////////////
  30. class DebugConfig
  31. : public AZ::ComponentConfig
  32. {
  33. public:
  34. AZ_CLASS_ALLOCATOR(DebugConfig, AZ::SystemAllocator);
  35. AZ_RTTI(DebugConfig, "{10750041-ABCA-4515-8D5D-B3E4769C3829}", AZ::ComponentConfig);
  36. static void Reflect(AZ::ReflectContext* context);
  37. DebugRequests::FilterTypeLevel m_filterLevel = DebugRequests::FilterTypeLevel::Warning;
  38. DebugRequests::SortType m_sortType = DebugRequests::SortType::BySector;
  39. AZ::u32 m_collectionFrequencyUs = 500000;
  40. AZ::u32 m_minThresholdUs = 500;
  41. AZ::u32 m_maxThresholdUs = 1500;
  42. AZ::u32 m_maxLabelDisplayDistance = 40;
  43. AZ::u32 m_maxDatapointDisplayCount = 1000;
  44. bool m_showVisualization = {};
  45. bool m_showDebugStats = {};
  46. bool m_showInstanceVisualization = {};
  47. };
  48. //////////////////////////////////////////////////////////////////////////
  49. class DebugComponent
  50. : public AZ::Component
  51. , private AzFramework::EntityDebugDisplayEventBus::Handler
  52. , private AzFramework::BoundsRequestBus::Handler
  53. , private DebugRequestBus::Handler
  54. , private DebugNotificationBus::Handler
  55. , private SystemConfigurationRequestBus::Handler
  56. {
  57. public:
  58. template<typename, typename> friend class LmbrCentral::EditorWrappedComponentBase;
  59. AZ_COMPONENT(DebugComponent, "{E62A9E15-E763-4069-8AE5-93276F1E7AC7}");
  60. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services);
  61. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services);
  62. static void Reflect(AZ::ReflectContext* context);
  63. DebugComponent(const DebugConfig& configuration) : m_configuration(configuration) {}
  64. DebugComponent() = default;
  65. ~DebugComponent() = default;
  66. //////////////////////////////////////////////////////////////////////////
  67. // AZ::Component interface implementation
  68. void Activate() override;
  69. void Deactivate() override;
  70. bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
  71. bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
  72. //////////////////////////////////////////////////////////////////////////
  73. // EntityDebugDisplayEventBus
  74. // Ideally this would use ViewportDebugDisplayEventBus::DisplayViewport, but that doesn't currently work in game mode,
  75. // so instead we use this plus the BoundsRequestBus with a large AABB to get ourselves rendered.
  76. void DisplayEntityViewport(
  77. const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override;
  78. //////////////////////////////////////////////////////////////////////////
  79. // DebugNotifications
  80. void FillSectorStart(int sectorX, int sectorY, TimePoint timePoint) override;
  81. void FillSectorEnd(int sectorX, int sectorY, TimePoint timePoint, AZ::u32 unusedClaimPointCount) override;
  82. void FillAreaStart(AZ::EntityId areaId, TimePoint timePoint) override;
  83. void MarkAreaRejectedByMask(AZ::EntityId areaId) override;
  84. void FillAreaEnd(AZ::EntityId areaId, TimePoint timePoint, AZ::u32 unusedClaimPointCount) override;
  85. void FilterInstance(AZ::EntityId areaId, AZStd::string_view filterReason) override;
  86. void CreateInstance(InstanceId instanceId, AZ::Vector3 position, AZ::EntityId areaId) override;
  87. void DeleteInstance(InstanceId instanceId) override;
  88. void DeleteAllInstances() override;
  89. void ExportCurrentReport() override;
  90. void ToggleVisualization() override;
  91. //////////////////////////////////////////////////////////////////////////
  92. // DebugRequests
  93. void GetPerformanceReport(PerformanceReport& report) const override;
  94. void DumpPerformanceReport(const PerformanceReport& report, FilterTypeLevel filter, SortType sort) const override;
  95. void ClearPerformanceReport() override;
  96. //////////////////////////////////////////////////////////////////////////
  97. // SystemConfigurationRequestBus
  98. void UpdateSystemConfig(const AZ::ComponentConfig* config) override;
  99. void GetSystemConfig([[maybe_unused]] AZ::ComponentConfig* config) const override {}; // ignore this call
  100. //////////////////////////////////////////////////////////////////////////
  101. // BoundsRequestBus
  102. AZ::Aabb GetWorldBounds() const override
  103. {
  104. // DisplayEntityViewport relies on the BoundsRequestBus to get the entity bounds to determine when to call debug drawing
  105. // for that entity. Since this is a level component that can draw infinitely far in every direction, we return an
  106. // effectively infinite AABB so that it always draws.
  107. return AZ::Aabb::CreateFromMinMax(AZ::Vector3(-AZ::Constants::FloatMax), AZ::Vector3(AZ::Constants::FloatMax));
  108. }
  109. AZ::Aabb GetLocalBounds() const override
  110. {
  111. // The local and world bounds will be the same for this component.
  112. return GetWorldBounds();
  113. }
  114. protected:
  115. void PrepareNextReport();
  116. void CopyReportToSortedList();
  117. void DrawSectorTimingData(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay);
  118. void DrawDebugStats(AzFramework::DebugDisplayRequests& debugDisplay);
  119. void DrawInstanceDebug(AzFramework::DebugDisplayRequests& debugDisplay);
  120. private:
  121. AZStd::atomic_bool m_exportCurrentReport{ false };
  122. mutable AZStd::recursive_mutex m_reportMutex;
  123. DebugRequests::PerformanceReport m_thePerformanceReport;
  124. DebugConfig m_configuration;
  125. TimePoint m_lastCollectionTime = {};
  126. // internal tracking
  127. struct SectorAreaData
  128. {
  129. TimePoint m_start;
  130. TimePoint m_end;
  131. size_t m_numInstancesCreated = 0; // number of instances in this sector/area combination
  132. FilterReasonCount m_numInstancesRejectedByFilters;
  133. bool m_filteredByMasks = false; // if this area was filtered because of the inclusive/exclusive masks in this sector/area combination
  134. };
  135. struct SectorTracker
  136. {
  137. SectorId m_id;
  138. TimePoint m_start;
  139. TimePoint m_end;
  140. size_t m_numInstancesCreated = 0;// number of instances in the sector over all areas.
  141. size_t m_numClaimPointsRemaining = 0;
  142. AZStd::unordered_map<AreaId, SectorAreaData> m_perAreaTracking;
  143. };
  144. using SectorData = AZStd::vector<SectorTracker>;
  145. SectorTracker m_currentSectorTiming;
  146. SectorData m_sectorData;
  147. struct AreaTracker
  148. {
  149. AreaId m_id;
  150. TimePoint m_start;
  151. TimePoint m_end;
  152. SectorId m_sectorId;
  153. size_t m_numInstancesCreated; // number of instances in this area over all sectors
  154. FilterReasonCount m_numInstancesRejectedByFilters;
  155. size_t m_numClaimPointsRemaining = 0;
  156. bool m_filteredByMasks; // true if this area was always filtered
  157. };
  158. using AreaData = AZStd::vector<AreaTracker>;
  159. AZStd::size_t MakeAreaSectorKey(AZ::EntityId areaId, SectorId sectorId);
  160. AZStd::unordered_map<uint64_t, AreaTracker> m_currentAreasTiming;
  161. AreaData m_areaData;
  162. AZStd::vector<SectorTiming> m_currentSortedTimingList;
  163. //! Cached pointer to the veg system debug data
  164. DebugData* m_debugData = nullptr;
  165. struct DebugInstanceData
  166. {
  167. AZ::Vector3 m_position;
  168. AreaId m_areaId;
  169. };
  170. AZStd::unordered_map<InstanceId, DebugInstanceData> m_activeInstances;
  171. };
  172. } // namespace Vegetation