PerViewportDynamicDrawManager.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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 "PerViewportDynamicDrawManager.h"
  9. #include <Atom/RPI.Public/ViewportContextBus.h>
  10. #include <Atom/RPI.Public/ViewportContext.h>
  11. namespace AZ::AtomBridge
  12. {
  13. PerViewportDynamicDrawManager::PerViewportDynamicDrawManager()
  14. {
  15. PerViewportDynamicDraw::Register(this);
  16. }
  17. PerViewportDynamicDrawManager::~PerViewportDynamicDrawManager()
  18. {
  19. PerViewportDynamicDraw::Unregister(this);
  20. }
  21. void PerViewportDynamicDrawManager::RegisterDynamicDrawContext(AZ::Name name, DrawContextFactory contextInitializer)
  22. {
  23. AZStd::lock_guard lock(m_mutexDrawContexts);
  24. const bool alreadyRegistered = m_registeredDrawContexts.find(name) != m_registeredDrawContexts.end();
  25. AZ_Error("AtomBridge", !alreadyRegistered, "Attempted to call RegisterDynamicDrawContext for already registered name: \"%s\"", name.GetCStr());
  26. if (alreadyRegistered)
  27. {
  28. return;
  29. }
  30. m_registeredDrawContexts[name] = contextInitializer;
  31. }
  32. void PerViewportDynamicDrawManager::UnregisterDynamicDrawContext(AZ::Name name)
  33. {
  34. AZStd::lock_guard lock(m_mutexDrawContexts);
  35. auto drawContextFactoryIt = m_registeredDrawContexts.find(name);
  36. const bool registered = drawContextFactoryIt != m_registeredDrawContexts.end();
  37. AZ_Error("AtomBridge", registered, "Attempted to call UnregisterDynamicDrawContext for unregistered name: \"%s\"", name.GetCStr());
  38. if (!registered)
  39. {
  40. return;
  41. }
  42. m_registeredDrawContexts.erase(drawContextFactoryIt);
  43. for (auto& viewportData : m_viewportData)
  44. {
  45. viewportData.second.m_dynamicDrawContexts.erase(name);
  46. }
  47. }
  48. RHI::Ptr<RPI::DynamicDrawContext> PerViewportDynamicDrawManager::GetDynamicDrawContextForViewport(
  49. AZ::Name name, AzFramework::ViewportId viewportId)
  50. {
  51. AZStd::lock_guard lock(m_mutexDrawContexts);
  52. auto contextFactoryIt = m_registeredDrawContexts.find(name);
  53. if (contextFactoryIt == m_registeredDrawContexts.end())
  54. {
  55. return nullptr;
  56. }
  57. auto viewportContextManager = RPI::ViewportContextRequests::Get();
  58. RPI::ViewportContextPtr viewportContext = viewportContextManager->GetViewportContextById(viewportId);
  59. if (viewportContext == nullptr)
  60. {
  61. return nullptr;
  62. }
  63. // Get or create a ViewportData if one doesn't already exist
  64. ViewportData& viewportData = m_viewportData[viewportId];
  65. if (!viewportData.m_initialized)
  66. {
  67. viewportData.m_pipelineChangedHandler = AZ::Event<RPI::RenderPipelinePtr>::Handler([this, viewportId](RPI::RenderPipelinePtr pipeline)
  68. {
  69. AZStd::lock_guard lock(m_mutexDrawContexts);
  70. ViewportData& viewportData = m_viewportData[viewportId];
  71. for (auto& context : viewportData.m_dynamicDrawContexts)
  72. {
  73. context.second->SetOutputScope(pipeline.get());
  74. }
  75. });
  76. viewportData.m_viewportDestroyedHandler = AZ::Event<AzFramework::ViewportId>::Handler([this](AzFramework::ViewportId id)
  77. {
  78. AZStd::lock_guard lock(m_mutexDrawContexts);
  79. m_viewportData.erase(id);
  80. });
  81. viewportContext->ConnectCurrentPipelineChangedHandler(viewportData.m_pipelineChangedHandler);
  82. viewportContext->ConnectAboutToBeDestroyedHandler(viewportData.m_viewportDestroyedHandler);
  83. viewportData.m_initialized = true;
  84. }
  85. RHI::Ptr<RPI::DynamicDrawContext>& context = viewportData.m_dynamicDrawContexts[name];
  86. if (context == nullptr)
  87. {
  88. auto pipeline = viewportContext->GetCurrentPipeline().get();
  89. if (pipeline == nullptr)
  90. {
  91. return nullptr;
  92. }
  93. context = RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext();
  94. context->SetOutputScope(pipeline);
  95. contextFactoryIt->second(context);
  96. }
  97. return context;
  98. }
  99. } //namespace AZ::AtomBridge