visibility_budget.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #pragma once
  2. #include "entity/registry.h"
  3. #include "graphics_settings.h"
  4. #include <atomic>
  5. #include <cstdint>
  6. namespace Render {
  7. class VisibilityBudgetTracker {
  8. public:
  9. static auto instance() noexcept -> VisibilityBudgetTracker & {
  10. static VisibilityBudgetTracker inst;
  11. return inst;
  12. }
  13. void reset_frame() noexcept {
  14. m_full_detail_count.store(0, std::memory_order_relaxed);
  15. }
  16. [[nodiscard]] auto request_humanoid_lod(GL::HumanoidLOD distance_lod) noexcept
  17. -> GL::HumanoidLOD {
  18. const auto &budget = GraphicsSettings::instance().visibility_budget();
  19. if (!budget.enabled) {
  20. return distance_lod;
  21. }
  22. if (distance_lod != GL::HumanoidLOD::Full) {
  23. return distance_lod;
  24. }
  25. if (try_consume_budget(budget.max_full_detail_units)) {
  26. return GL::HumanoidLOD::Full;
  27. }
  28. return GL::HumanoidLOD::Reduced;
  29. }
  30. [[nodiscard]] auto
  31. request_horse_lod(GL::HorseLOD distance_lod) noexcept -> GL::HorseLOD {
  32. const auto &budget = GraphicsSettings::instance().visibility_budget();
  33. if (!budget.enabled) {
  34. return distance_lod;
  35. }
  36. if (distance_lod != GL::HorseLOD::Full) {
  37. return distance_lod;
  38. }
  39. if (try_consume_budget(budget.max_full_detail_units)) {
  40. return GL::HorseLOD::Full;
  41. }
  42. return GL::HorseLOD::Reduced;
  43. }
  44. [[nodiscard]] auto full_detail_count() const noexcept -> int {
  45. return m_full_detail_count.load(std::memory_order_relaxed);
  46. }
  47. private:
  48. VisibilityBudgetTracker() = default;
  49. [[nodiscard]] auto try_consume_budget(int max_units) noexcept -> bool {
  50. int current = m_full_detail_count.load(std::memory_order_relaxed);
  51. while (current < max_units) {
  52. if (m_full_detail_count.compare_exchange_weak(
  53. current, current + 1, std::memory_order_relaxed,
  54. std::memory_order_relaxed)) {
  55. return true;
  56. }
  57. }
  58. return false;
  59. }
  60. std::atomic<int> m_full_detail_count{0};
  61. };
  62. } // namespace Render