Merge branch 'development' into Atom/guthadam/atomtools_updating_cmake_config

This commit is contained in:
Guthrie Adams
2021-09-20 11:27:04 -05:00
1463 changed files with 60543 additions and 54258 deletions
@@ -38,7 +38,7 @@ namespace AtomToolsFramework
m_propertyEditor->Setup(context, instanceNotificationHandler, false);
m_propertyEditor->AddInstance(instance, instanceClassId, nullptr, instanceToCompare);
m_propertyEditor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_propertyEditor->QueueInvalidation(AzToolsFramework::PropertyModificationRefreshLevel::Refresh_EntireTree);
m_propertyEditor->InvalidateAll();
m_layout->addWidget(m_propertyEditor);
setLayout(m_layout);
@@ -29,30 +29,40 @@ namespace AtomToolsFramework
{
}
void InspectorWidget::AddHeading(QWidget* headingWidget)
{
headingWidget->setParent(m_ui->m_headingSection);
m_ui->m_headingSectionLayout->addWidget(headingWidget);
}
void InspectorWidget::ClearHeading()
{
qDeleteAll(m_ui->m_headingSection->findChildren<QWidget*>(QString(), Qt::FindDirectChildrenOnly));
qDeleteAll(m_ui->m_headingSectionLayout->children());
}
void InspectorWidget::Reset()
{
qDeleteAll(m_ui->m_propertyContent->children());
m_layout = new QVBoxLayout(m_ui->m_propertyContent);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(0);
qDeleteAll(m_ui->m_groupContents->findChildren<QWidget*>(QString(), Qt::FindDirectChildrenOnly));
qDeleteAll(m_ui->m_groupContentsLayout->children());
m_groups.clear();
}
void InspectorWidget::AddGroupsBegin()
{
setUpdatesEnabled(false);
setVisible(false);
Reset();
}
void InspectorWidget::AddGroupsEnd()
{
m_layout->addStretch();
m_ui->m_groupContentsLayout->addStretch();
// Scroll to top whenever there is new content
m_ui->m_propertyScrollArea->verticalScrollBar()->setValue(m_ui->m_propertyScrollArea->verticalScrollBar()->minimum());
m_ui->m_groupScrollArea->verticalScrollBar()->setValue(m_ui->m_groupScrollArea->verticalScrollBar()->minimum());
setUpdatesEnabled(true);
setVisible(true);
}
void InspectorWidget::AddGroup(
@@ -61,14 +71,14 @@ namespace AtomToolsFramework
const AZStd::string& groupDescription,
QWidget* groupWidget)
{
InspectorGroupHeaderWidget* groupHeader = new InspectorGroupHeaderWidget(m_ui->m_propertyContent);
InspectorGroupHeaderWidget* groupHeader = new InspectorGroupHeaderWidget(m_ui->m_groupContents);
groupHeader->setText(groupDisplayName.c_str());
groupHeader->setToolTip(groupDescription.c_str());
m_layout->addWidget(groupHeader);
m_ui->m_groupContentsLayout->addWidget(groupHeader);
groupWidget->setObjectName(groupNameId.c_str());
groupWidget->setParent(m_ui->m_propertyContent);
m_layout->addWidget(groupWidget);
groupWidget->setParent(m_ui->m_groupContents);
m_ui->m_groupContentsLayout->addWidget(groupWidget);
m_groups[groupNameId] = {groupHeader, groupWidget};
@@ -101,28 +111,18 @@ namespace AtomToolsFramework
bool InspectorWidget::IsGroupVisible(const AZStd::string& groupNameId) const
{
auto groupItr = m_groups.find(groupNameId);
if (groupItr != m_groups.end())
{
return groupItr->second.m_header->isVisible();
}
return false;
return groupItr != m_groups.end() ? groupItr->second.m_header->isVisible() : false;
}
bool InspectorWidget::IsGroupHidden(const AZStd::string& groupNameId) const
{
auto groupItr = m_groups.find(groupNameId);
if (groupItr != m_groups.end())
{
return groupItr->second.m_header->isHidden();
}
return false;
return groupItr != m_groups.end() ? groupItr->second.m_header->isHidden() : false;
}
void InspectorWidget::RefreshGroup(const AZStd::string& groupNameId)
{
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
{
groupWidget->Refresh();
}
@@ -130,7 +130,7 @@ namespace AtomToolsFramework
void InspectorWidget::RebuildGroup(const AZStd::string& groupNameId)
{
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>(groupNameId.c_str()))
{
groupWidget->Rebuild();
}
@@ -138,7 +138,7 @@ namespace AtomToolsFramework
void InspectorWidget::RefreshAll()
{
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>())
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>())
{
groupWidget->Refresh();
}
@@ -146,7 +146,7 @@ namespace AtomToolsFramework
void InspectorWidget::RebuildAll()
{
for (auto groupWidget : m_ui->m_propertyContent->findChildren<InspectorGroupWidget*>())
for (auto groupWidget : m_ui->m_groupContents->findChildren<InspectorGroupWidget*>())
{
groupWidget->Rebuild();
}
@@ -6,20 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>693</width>
<height>798</height>
<width>685</width>
<height>775</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Inspector</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QVBoxLayout" name="m_inspectorLayout">
<property name="spacing">
<number>0</number>
</property>
@@ -36,50 +30,103 @@
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="m_propertyScrollArea">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>691</width>
<height>796</height>
</rect>
<widget class="QWidget" name="m_sections">
<layout class="QVBoxLayout" name="m_sectionsLayout">
<property name="spacing">
<number>0</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="m_propertyContent">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="m_headingSection" native="true">
<layout class="QVBoxLayout" name="m_headingSectionLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<property name="leftMargin">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="m_groupSection" native="true">
<layout class="QVBoxLayout" name="m_groupSectionLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="m_groupScrollArea">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="m_groupContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>683</width>
<height>763</height>
</rect>
</property>
<layout class="QVBoxLayout" name="m_groupContentsLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
@@ -6,23 +6,42 @@
*
*/
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
#include <Atom/Bootstrap/BootstrapRequestBus.h>
#include <Atom/RHI/RHISystemInterface.h>
#include <Atom/RPI.Public/View.h>
#include <Atom/RPI.Public/ViewportContext.h>
#include <Atom/RPI.Public/ViewportContextBus.h>
#include <Atom/RPI.Public/View.h>
#include <AtomToolsFramework/Viewport/RenderViewportWidget.h>
#include <AzCore/Console/Console.h>
#include <AzCore/Math/MathUtils.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzFramework/Viewport/ViewportControllerList.h>
#include <AzFramework/Viewport/ViewportScreen.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
#include <AzCore/Math/MathUtils.h>
#include <Atom/RHI/RHISystemInterface.h>
#include <Atom/Bootstrap/BootstrapRequestBus.h>
#include <QApplication>
#include <QCursor>
#include <QBoxLayout>
#include <QWindow>
#include <QCursor>
#include <QMouseEvent>
#include <QScreen>
#include <QTimer>
#include <QWindow>
static void OnInactiveViewportFrameRateChanged(const float& fpsLimit)
{
AtomToolsFramework::RenderViewportWidgetNotificationBus::Broadcast(
&AtomToolsFramework::RenderViewportWidgetNotificationBus::Events::OnInactiveViewportFrameRateChanged, fpsLimit);
}
AZ_CVAR(
float,
ed_inactive_viewport_fps_limit,
0,
OnInactiveViewportFrameRateChanged,
AZ::ConsoleFunctorFlags::Null,
"The maximum framerate to render viewports that don't have focus at");
static constexpr const char* LastFocusedViewportVariableName = "AtomToolsFramework::RenderViewportWidget::LastFocusedViewport";
namespace AtomToolsFramework
{
@@ -30,6 +49,12 @@ namespace AtomToolsFramework
: QWidget(parent)
, AzFramework::InputChannelEventListener(AzFramework::InputChannelEventListener::GetPriorityDefault())
{
m_lastFocusedViewport = AZ::Environment::FindVariable<RenderViewportWidget*>(LastFocusedViewportVariableName);
if (!m_lastFocusedViewport)
{
m_lastFocusedViewport = AZ::Environment::CreateVariable<RenderViewportWidget*>(LastFocusedViewportVariableName, nullptr);
}
if (shouldInitializeViewportContext)
{
InitializeViewportContext();
@@ -38,13 +63,24 @@ namespace AtomToolsFramework
setUpdatesEnabled(false);
setFocusPolicy(Qt::FocusPolicy::WheelFocus);
setMouseTracking(true);
// Wait a frame for our window handle to be constructed, then wire up our screen change signals.
QTimer::singleShot(
0,
[this]()
{
QObject::connect(windowHandle(), &QWindow::screenChanged, this, &RenderViewportWidget::SetScreen);
});
SetScreen(screen());
}
bool RenderViewportWidget::InitializeViewportContext(AzFramework::ViewportId id)
{
if (m_viewportContext != nullptr)
{
AZ_Assert(id == AzFramework::InvalidViewportId || m_viewportContext->GetId() == id, "Attempted to reinitialize RenderViewportWidget with a different ID");
AZ_Assert(
id == AzFramework::InvalidViewportId || m_viewportContext->GetId() == id,
"Attempted to reinitialize RenderViewportWidget with a different ID");
return true;
}
@@ -59,7 +95,7 @@ namespace AtomToolsFramework
// Before we do anything else, we must create a ViewportContext which will give us a ViewportId if we didn't manually specify one.
AZ::RPI::ViewportContextRequestsInterface::CreationParameters params;
params.device = AZ::RHI::RHISystemInterface::Get()->GetDevice();
params.windowHandle = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
params.windowHandle = GetNativeWindowHandle();
params.id = id;
AzFramework::WindowRequestBus::Handler::BusConnect(params.windowHandle);
m_viewportContext = viewportContextManager->CreateViewportContext(AZ::Name(), params);
@@ -80,29 +116,46 @@ namespace AtomToolsFramework
AzFramework::InputChannelEventListener::Connect();
AZ::TickBus::Handler::BusConnect();
AzFramework::WindowRequestBus::Handler::BusConnect(params.windowHandle);
AZ::Render::Bootstrap::NotificationBus::Handler::BusConnect();
AtomToolsFramework::RenderViewportWidgetNotificationBus::Handler::BusConnect();
m_inputChannelMapper = new AzToolsFramework::QtEventToAzInputMapper(this, id);
// Forward input events to our controller list.
QObject::connect(m_inputChannelMapper, &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, this,
QObject::connect(
m_inputChannelMapper, &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, this,
[this](const AzFramework::InputChannel* inputChannel, QEvent* event)
{
AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
if (m_controllerList->HandleInputChannelEvent(AzFramework::ViewportControllerInputEvent{GetId(), windowId, *inputChannel}))
{
// If the controller handled the input event, mark the event as accepted so it doesn't continue to propagate.
if (event)
const AzFramework::NativeWindowHandle windowId = GetNativeWindowHandle();
if (m_controllerList->HandleInputChannelEvent(
AzFramework::ViewportControllerInputEvent{ GetId(), windowId, *inputChannel }))
{
event->setAccepted(true);
// If the controller handled the input event, mark the event as accepted so it doesn't continue to propagate.
if (event)
{
event->setAccepted(true);
}
}
}
});
});
// Update our target frame rate. If we're the only viewport, become active.
if (m_lastFocusedViewport.Get() == nullptr)
{
m_lastFocusedViewport.Set(this);
}
UpdateFrameRate();
return true;
}
RenderViewportWidget::~RenderViewportWidget()
{
if (m_lastFocusedViewport.Get() == this)
{
m_lastFocusedViewport.Set(nullptr);
}
AzFramework::WindowRequestBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
AzFramework::InputChannelEventListener::Disconnect();
@@ -181,17 +234,22 @@ namespace AtomToolsFramework
bool shouldConsumeEvent = true;
AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
const bool eventHandled = m_controllerList->HandleInputChannelEvent({GetId(), windowId, inputChannel});
const bool eventHandled = m_controllerList->HandleInputChannelEvent({ GetId(), GetNativeWindowHandle(), inputChannel });
// If our controllers handled the event and it's one we can safely consume (i.e. it's not an Ended event that other viewports might need), consume it.
// If our controllers handled the event and it's one we can safely consume (i.e. it's not an Ended event that other viewports might
// need), consume it.
return eventHandled && shouldConsumeEvent;
}
void RenderViewportWidget::OnTick([[maybe_unused]]float deltaTime, AZ::ScriptTimePoint time)
void RenderViewportWidget::OnTick([[maybe_unused]] float deltaTime, AZ::ScriptTimePoint time)
{
m_time = time;
m_controllerList->UpdateViewport({GetId(), AzFramework::FloatSeconds(deltaTime), m_time});
m_controllerList->UpdateViewport({ GetId(), AzFramework::FloatSeconds(deltaTime), m_time });
}
int RenderViewportWidget::GetTickOrder()
{
return AZ::ComponentTickBus::TICK_PRE_RENDER;
}
void RenderViewportWidget::resizeEvent([[maybe_unused]] QResizeEvent* event)
@@ -236,6 +294,75 @@ namespace AtomToolsFramework
m_mousePosition = event->localPos();
}
void RenderViewportWidget::focusInEvent([[maybe_unused]] QFocusEvent* event)
{
RenderViewportWidget* lastFocusedViewport = m_lastFocusedViewport.Get();
if (lastFocusedViewport == this)
{
return;
}
RenderViewportWidget* previousFocusWidget = lastFocusedViewport;
m_lastFocusedViewport.Set(this);
// Ensure this viewport and whatever viewport last had focus (if any) respect
// the active / inactive viewport frame rate settings.
UpdateFrameRate();
if (previousFocusWidget != nullptr)
{
previousFocusWidget->UpdateFrameRate();
}
}
void RenderViewportWidget::OnFrameRateLimitChanged([[maybe_unused]] float fpsLimit)
{
UpdateFrameRate();
}
void RenderViewportWidget::OnInactiveViewportFrameRateChanged([[maybe_unused]] float fpsLimit)
{
UpdateFrameRate();
}
AzFramework::NativeWindowHandle RenderViewportWidget::GetNativeWindowHandle() const
{
return reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
}
void RenderViewportWidget::UpdateFrameRate()
{
if (ed_inactive_viewport_fps_limit > 0.f && m_lastFocusedViewport.Get() != this)
{
m_viewportContext->SetFpsLimit(ed_inactive_viewport_fps_limit);
}
else
{
float fpsLimit = 0.f;
AZ::Render::Bootstrap::RequestBus::BroadcastResult(fpsLimit, &AZ::Render::Bootstrap::RequestBus::Events::GetFrameRateLimit);
m_viewportContext->SetFpsLimit(fpsLimit);
}
}
void RenderViewportWidget::SetScreen(QScreen* screen)
{
if (m_screen != screen)
{
if (m_screen)
{
QObject::disconnect(m_screen, &QScreen::refreshRateChanged, this, &RenderViewportWidget::NotifyUpdateRefreshRate);
}
if (screen)
{
QObject::connect(m_screen, &QScreen::refreshRateChanged, this, &RenderViewportWidget::NotifyUpdateRefreshRate);
}
NotifyUpdateRefreshRate();
m_screen = screen;
}
}
void RenderViewportWidget::SendWindowResizeEvent()
{
// Scale the size by the DPI of the platform to
@@ -243,11 +370,17 @@ namespace AtomToolsFramework
const QSize uiWindowSize = size();
const QSize windowSize = uiWindowSize * devicePixelRatioF();
const AzFramework::NativeWindowHandle windowId = reinterpret_cast<AzFramework::NativeWindowHandle>(winId());
AzFramework::WindowNotificationBus::Event(windowId, &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height());
AzFramework::WindowNotificationBus::Event(
GetNativeWindowHandle(), &AzFramework::WindowNotifications::OnWindowResized, windowSize.width(), windowSize.height());
m_windowResizedEvent = false;
}
void RenderViewportWidget::NotifyUpdateRefreshRate()
{
AzFramework::WindowNotificationBus::Event(
GetNativeWindowHandle(), &AzFramework::WindowNotificationBus::Events::OnRefreshRateChanged, GetDisplayRefreshRate());
}
AZ::Name RenderViewportWidget::GetCurrentContextName() const
{
return m_viewportContext->GetName();
@@ -303,9 +436,7 @@ namespace AtomToolsFramework
// Build camera state from Atom camera transforms
AzFramework::CameraState cameraState = AzFramework::CreateCameraFromWorldFromViewMatrix(
currentView->GetViewToWorldMatrix(),
AZ::Vector2{aznumeric_cast<float>(width()), aznumeric_cast<float>(height())}
);
currentView->GetViewToWorldMatrix(), AZ::Vector2{ aznumeric_cast<float>(width()), aznumeric_cast<float>(height()) });
AzFramework::SetCameraClippingVolumeFromPerspectiveFovMatrixRH(cameraState, currentView->GetViewToClipMatrix());
// Convert from Z-up
@@ -317,8 +448,7 @@ namespace AtomToolsFramework
AzFramework::ScreenPoint RenderViewportWidget::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
{
if (AZ::RPI::ViewPtr currentView = m_viewportContext->GetDefaultView();
currentView == nullptr)
if (AZ::RPI::ViewPtr currentView = m_viewportContext->GetDefaultView(); currentView == nullptr)
{
return AzFramework::ScreenPoint(0, 0);
}
@@ -331,12 +461,10 @@ namespace AtomToolsFramework
const auto& cameraProjection = m_viewportContext->GetCameraProjectionMatrix();
const auto& cameraView = m_viewportContext->GetCameraViewMatrix();
const AZ::Vector4 normalizedScreenPosition {
screenPosition.m_x * 2.f / width() - 1.0f,
(height() - screenPosition.m_y) * 2.f / height() - 1.0f,
1.f - depth, // [GFX TODO] [ATOM-1501] Currently we always assume reverse depth
1.f
};
const AZ::Vector4 normalizedScreenPosition{ screenPosition.m_x * 2.f / width() - 1.0f,
(height() - screenPosition.m_y) * 2.f / height() - 1.0f,
1.f - depth, // [GFX TODO] [ATOM-1501] Currently we always assume reverse depth
1.f };
AZ::Matrix4x4 worldFromScreen = cameraProjection * cameraView;
worldFromScreen.InvertFull();
@@ -365,7 +493,7 @@ namespace AtomToolsFramework
AZ::Vector3 rayDirection = pos1.value() - pos0.value();
rayDirection.Normalize();
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{rayOrigin, rayDirection};
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection };
}
float RenderViewportWidget::DeviceScalingFactor()
@@ -395,12 +523,12 @@ namespace AtomToolsFramework
AzFramework::WindowSize RenderViewportWidget::GetClientAreaSize() const
{
return AzFramework::WindowSize{aznumeric_cast<uint32_t>(width()), aznumeric_cast<uint32_t>(height())};
return AzFramework::WindowSize{ aznumeric_cast<uint32_t>(width()), aznumeric_cast<uint32_t>(height()) };
}
void RenderViewportWidget::ResizeClientArea(AzFramework::WindowSize clientAreaSize)
{
const QSize targetSize = QSize{aznumeric_cast<int>(clientAreaSize.m_width), aznumeric_cast<int>(clientAreaSize.m_height)};
const QSize targetSize = QSize{ aznumeric_cast<int>(clientAreaSize.m_width), aznumeric_cast<int>(clientAreaSize.m_height) };
resize(targetSize);
}
@@ -410,7 +538,7 @@ namespace AtomToolsFramework
return false;
}
void RenderViewportWidget::SetFullScreenState([[maybe_unused]]bool fullScreenState)
void RenderViewportWidget::SetFullScreenState([[maybe_unused]] bool fullScreenState)
{
// The RenderViewportWidget does not currently support full screen.
}
@@ -433,11 +561,20 @@ namespace AtomToolsFramework
uint32_t RenderViewportWidget::GetDisplayRefreshRate() const
{
return 60;
return static_cast<uint32_t>(screen()->refreshRate());
}
uint32_t RenderViewportWidget::GetSyncInterval() const
{
return 1;
uint32_t interval = 1;
// Get vsync_interval from AzFramework::NativeWindow, which owns it.
// NativeWindow also handles broadcasting OnVsyncIntervalChanged to all
// WindowNotificationBus listeners.
if (auto console = AZ::Interface<AZ::IConsole>::Get())
{
console->GetCvarValue<uint32_t>("vsync_interval", interval);
}
return interval;
}
} //namespace AtomToolsFramework
} // namespace AtomToolsFramework