From daf4dbb54d94b1c4240a273a9fdd831cce543339 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Tue, 4 Jan 2022 15:14:35 -0800 Subject: [PATCH] Fix LyShine debug display to work with Atom (#6516) * LyShine cleanup pass for Atom conversion Signed-off-by: abrmich * Add GHI numbers to comments Signed-off-by: abrmich * Fix debug texture data Signed-off-by: abrmich * Fix debug canvas and draw call data Signed-off-by: abrmich * Add GHI issue Signed-off-by: abrmich * Address PR feedback Signed-off-by: abrmich * Remove unused variable Signed-off-by: abrmich --- Gems/LyShine/Code/Include/LyShine/Draw2d.h | 3 + Gems/LyShine/Code/Source/Draw2d.cpp | 6 + Gems/LyShine/Code/Source/RenderGraph.cpp | 15 ++- Gems/LyShine/Code/Source/UiCanvasManager.cpp | 30 ++--- Gems/LyShine/Code/Source/UiRenderer.cpp | 123 +++++++++---------- Gems/LyShine/Code/Source/UiRenderer.h | 7 +- 6 files changed, 92 insertions(+), 92 deletions(-) diff --git a/Gems/LyShine/Code/Include/LyShine/Draw2d.h b/Gems/LyShine/Code/Include/LyShine/Draw2d.h index 8123a834a1..881479bd23 100644 --- a/Gems/LyShine/Code/Include/LyShine/Draw2d.h +++ b/Gems/LyShine/Code/Include/LyShine/Draw2d.h @@ -205,6 +205,9 @@ public: // member functions //! Get the height of the rendering viewport (in pixels). float GetViewportHeight() const; + //! Get dpi scale factor + float GetViewportDpiScalingFactor() const; + //! Get the default values that would be used if no image options were passed in // //! This is a convenient way to initialize the imageOptions struct diff --git a/Gems/LyShine/Code/Source/Draw2d.cpp b/Gems/LyShine/Code/Source/Draw2d.cpp index f2c7c360d2..6b6356aa4f 100644 --- a/Gems/LyShine/Code/Source/Draw2d.cpp +++ b/Gems/LyShine/Code/Source/Draw2d.cpp @@ -452,6 +452,12 @@ float CDraw2d::GetViewportHeight() const return viewHeight; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +float CDraw2d::GetViewportDpiScalingFactor() const +{ + return GetViewportContext()->GetDpiScalingFactor(); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// const CDraw2d::ImageOptions& CDraw2d::GetDefaultImageOptions() const { diff --git a/Gems/LyShine/Code/Source/RenderGraph.cpp b/Gems/LyShine/Code/Source/RenderGraph.cpp index db17fde601..c05e87bc64 100644 --- a/Gems/LyShine/Code/Source/RenderGraph.cpp +++ b/Gems/LyShine/Code/Source/RenderGraph.cpp @@ -122,14 +122,10 @@ namespace LyShine uint32_t isClampTextureMode = 0; for (int i = 0; i < m_numTextures; ++i) { - const AZ::RHI::ImageView* imageView = m_textures[i].m_texture ? m_textures[i].m_texture->GetImageView() : nullptr; - - if (!imageView) - { - // Default to white texture - auto image = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White); - imageView = image->GetImageView(); - } + // Default to white texture + const AZ::Data::Instance& image = m_textures[i].m_texture ? m_textures[i].m_texture + : AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White); + const AZ::RHI::ImageView* imageView = image->GetImageView(); if (imageView) { @@ -138,6 +134,9 @@ namespace LyShine { isClampTextureMode |= (1 << i); } +#ifndef _RELEASE + uiRenderer->DebugUseTexture(image); +#endif } } diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.cpp b/Gems/LyShine/Code/Source/UiCanvasManager.cpp index 62d1c6e2a8..c6564f9b3a 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasManager.cpp @@ -999,26 +999,23 @@ void UiCanvasManager::DebugDisplayCanvasData(int setting) const CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); - float xOffset = 20.0f; - float yOffset = 20.0f; + float dpiScale = draw2d->GetViewportDpiScalingFactor(); + float xOffset = 20.0f * dpiScale; + float yOffset = 20.0f * dpiScale; const int elementNameFieldLength = 20; auto blackTexture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::Black); - float textOpacity = 1.0f; - float backgroundRectOpacity = 0.75f; + float backgroundRectOpacity = 0.0f; // 0.75f; // [GHI #6515] Reenable background rect const AZ::Vector3 white(1.0f, 1.0f, 1.0f); const AZ::Vector3 grey(0.5f, 0.5f, 0.5f); const AZ::Vector3 red(1.0f, 0.3f, 0.3f); const AZ::Vector3 blue(0.3f, 0.3f, 1.0f); - // If the viewport is narrow then a font size of 16 might be too large, so we use a size between 12 and 16 depending - // on the viewport width. - float fontSize(draw2d->GetViewportWidth() / 75.f); - fontSize = AZ::GetClamp(fontSize, 12.f, 16.f); - const float lineSpacing = fontSize; + const float fontSize = 8.0f; + const float lineSpacing = 20.0f * dpiScale; // local function to write a line of text (with a background rect) and increment Y offset AZStd::function WriteLine = [&](const char* buffer, const AZ::Vector3& color) @@ -1157,13 +1154,13 @@ void UiCanvasManager::DebugDisplayDrawCallData() const { CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); - float xOffset = 20.0f; - float yOffset = 20.0f; + float dpiScale = draw2d->GetViewportDpiScalingFactor(); + float xOffset = 20.0f * dpiScale; + float yOffset = 20.0f * dpiScale; auto blackTexture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::Black); float textOpacity = 1.0f; - float backgroundRectOpacity = 0.75f; - const float lineSpacing = 20.0f; + float backgroundRectOpacity = 0.0f; // 0.75f; // [GHI #6515] Reenable background rect const AZ::Vector3 white(1,1,1); const AZ::Vector3 red(1,0.3f,0.3f); @@ -1171,16 +1168,19 @@ void UiCanvasManager::DebugDisplayDrawCallData() const const AZ::Vector3 green(0.3f,1,0.3f); const AZ::Vector3 yellow(0.7f,0.7f,0.2f); + const float fontSize = 8.0f; + const float lineSpacing = 20.0f * dpiScale; + // local function to write a line of text (with a background rect) and increment Y offset AZStd::function WriteLine = [&](const char* buffer, const AZ::Vector3& color) { CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); textOptions.color = color; - AZ::Vector2 textSize = draw2d->GetTextSize(buffer, 16, &textOptions); + AZ::Vector2 textSize = draw2d->GetTextSize(buffer, fontSize, &textOptions); AZ::Vector2 rectTopLeft = AZ::Vector2(xOffset - 2, yOffset); AZ::Vector2 rectSize = AZ::Vector2(textSize.GetX() + 4, lineSpacing); draw2d->DrawImage(blackTexture, rectTopLeft, rectSize, backgroundRectOpacity); - draw2d->DrawText(buffer, AZ::Vector2(xOffset, yOffset), 16, textOpacity, &textOptions); + draw2d->DrawText(buffer, AZ::Vector2(xOffset, yOffset), fontSize, textOpacity, &textOptions); yOffset += lineSpacing; }; diff --git a/Gems/LyShine/Code/Source/UiRenderer.cpp b/Gems/LyShine/Code/Source/UiRenderer.cpp index b43be90a36..64ec1bb485 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.cpp +++ b/Gems/LyShine/Code/Source/UiRenderer.cpp @@ -216,17 +216,11 @@ void UiRenderer::BeginUiFrameRender() m_texturesUsedInFrame.clear(); } #endif - - // Various platform drivers expect all texture slots used in the shader to be bound - BindNullTexture(); } //////////////////////////////////////////////////////////////////////////////////////////////////// void UiRenderer::EndUiFrameRender() { - // We never want to leave a texture bound that could get unloaded before the next render - // So bind the global white texture for all the texture units we use. - BindNullTexture(); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -384,45 +378,6 @@ void UiRenderer::DecrementStencilRef() --m_stencilRef; } -#ifdef LYSHINE_ATOM_TODO -//////////////////////////////////////////////////////////////////////////////////////////////////// -void UiRenderer::SetTexture(ITexture* texture, int texUnit, bool clamp) -{ - if (!texture) - { - texture = m_renderer->GetWhiteTexture(); - } - else - { - texture->SetClamp(clamp); - } - - m_renderer->SetTexture(texture->GetTextureID(), texUnit); - -#ifndef _RELEASE - if (m_debugTextureDataRecordLevel > 0) - { - m_texturesUsedInFrame.insert(texture); - } -#endif -} -#endif - - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void UiRenderer::BindNullTexture() -{ -#ifdef LYSHINE_ATOM_TODO - // Bind the global white texture for all the texture units we use - const int MaxTextures = 16; - int whiteTexId = m_renderer->GetWhiteTextureId(); - for (int texUnit = 0; texUnit < MaxTextures; ++texUnit) - { - m_renderer->SetTexture(whiteTexId, texUnit); - } -#endif -} - #ifndef _RELEASE //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -436,38 +391,42 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption) { if (recordingOption > 0) { -#ifdef LYSHINE_ATOM_TODO // [GHI #3568] Support canvas debug display with Atom // compute the total area of all the textures, also create a vector that we can sort by area - AZStd::vector textures; + AZStd::vector, uint32_t>> textures; int totalArea = 0; int totalDataSize = 0; - for (ITexture* texture : m_texturesUsedInFrame) + for (AZ::Data::Instance image : m_texturesUsedInFrame) { - int area = texture->GetWidth() * texture->GetHeight(); - int dataSize = texture->GetDataSize(); + const AZ::RHI::ImageDescriptor& imageDescriptor = image->GetRHIImage()->GetDescriptor(); + AZ::RHI::Size size = imageDescriptor.m_size; + int area = size.m_width * size.m_height; + uint32_t dataSize = AZ::RHI::GetFormatSize(imageDescriptor.m_format) * area; + totalArea += area; totalDataSize += dataSize; - textures.push_back(texture); + textures.push_back(AZStd::pair, uint32_t>(image, dataSize)); } // sort the vector by data size - std::sort( textures.begin( ), textures.end( ), [ ]( const ITexture* lhs, const ITexture* rhs ) + std::sort( textures.begin( ), textures.end( ), [ ]( const AZStd::pair, uint32_t> lhs, const AZStd::pair, uint32_t> rhs ) { - return lhs->GetDataSize() > rhs->GetDataSize(); + return lhs.second > rhs.second; }); CDraw2d* draw2d = Draw2dHelper::GetDefaultDraw2d(); // setup to render lines of text for the debug display - float xOffset = 20.0f; - float yOffset = 20.0f; + float dpiScale = GetViewportContext()->GetDpiScalingFactor(); + float xOffset = 20.0f * dpiScale; + float yOffset = 20.0f * dpiScale; auto blackTexture = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::Black); float textOpacity = 1.0f; - float backgroundRectOpacity = 0.75f; - const float lineSpacing = 20.0f; + float backgroundRectOpacity = 0.0f; // 0.75f; // [GHI #6515] Reenable background rect + const float fontSize = 8.0f; + const float lineSpacing = 20.0f * dpiScale; const AZ::Vector3 white(1,1,1); const AZ::Vector3 red(1,0.3f,0.3f); @@ -492,29 +451,61 @@ void UiRenderer::DebugDisplayTextureData(int recordingOption) { CDraw2d::TextOptions textOptions = draw2d->GetDefaultTextOptions(); textOptions.color = color; - AZ::Vector2 textSize = draw2d->GetTextSize(buffer, 16, &textOptions); + AZ::Vector2 textSize = draw2d->GetTextSize(buffer, fontSize, &textOptions); AZ::Vector2 rectTopLeft = AZ::Vector2(xOffset - 2, yOffset); AZ::Vector2 rectSize = AZ::Vector2(textSize.GetX() + 4, lineSpacing); draw2d->DrawImage(blackTexture, rectTopLeft, rectSize, backgroundRectOpacity); - draw2d->DrawText(buffer, AZ::Vector2(xOffset, yOffset), 16, textOpacity, &textOptions); + draw2d->DrawText(buffer, AZ::Vector2(xOffset, yOffset), fontSize, textOpacity, &textOptions); yOffset += lineSpacing; }; - int numTexturesUsedInFrame = m_texturesUsedInFrame.size(); + size_t numTexturesUsedInFrame = m_texturesUsedInFrame.size(); char buffer[200]; - sprintf_s(buffer, "There are %d unique UI textures rendered in this frame, the total texture area is %d (%d x %d), total data size is %d (%.2f MB)", + sprintf_s(buffer, "There are %zu unique UI textures rendered in this frame, the total texture area is %d (%d x %d), total data size is %d (%.2f MB)", numTexturesUsedInFrame, totalArea, xDim, yDim, totalDataSize, totalDataSizeMB); WriteLine(buffer, white); - sprintf_s(buffer, "Dimensions Data Size Format Texture name"); + sprintf_s(buffer, "Dimensions Data Size Format Texture name"); WriteLine(buffer, blue); - for (ITexture* texture : textures) + for (auto texture : textures) { - sprintf_s(buffer, "%4d x %4d, %9d %8s %s", - texture->GetWidth(), texture->GetHeight(), texture->GetDataSize(), texture->GetFormatName(), texture->GetName()); + AZ::Data::Instance image = texture.first; + const AZ::RHI::ImageDescriptor& imageDescriptor = image->GetRHIImage()->GetDescriptor(); + uint32_t width = imageDescriptor.m_size.m_width; + uint32_t height = imageDescriptor.m_size.m_height; + uint32_t dataSize = texture.second; + + const char* displayName = "Unnamed Texture"; + AZStd::string imagePath; + // Check if the image has been assigned a name (ex. if it's an attachment image or a cpu generated image) + const AZ::Name& imageName = image->GetRHIImage()->GetName(); + if (!imageName.IsEmpty()) + { + displayName = imageName.GetCStr(); + } + else + { + // Use the image's asset path as the display name + AZ::Data::AssetCatalogRequestBus::BroadcastResult(imagePath, + &AZ::Data::AssetCatalogRequests::GetAssetPathById, image->GetAssetId()); + if (!imagePath.empty()) + { + displayName = imagePath.c_str(); + } + } + + sprintf_s(buffer, "%4u x %4u, %9u %19s %s", + width, height, dataSize, AZ::RHI::ToString(imageDescriptor.m_format), displayName); WriteLine(buffer, white); } -#endif + } +} + +void UiRenderer::DebugUseTexture(AZ::Data::Instance image) +{ + if (m_debugTextureDataRecordLevel > 0) + { + m_texturesUsedInFrame.insert(image); } } diff --git a/Gems/LyShine/Code/Source/UiRenderer.h b/Gems/LyShine/Code/Source/UiRenderer.h index 3ff3de5507..35705441f5 100644 --- a/Gems/LyShine/Code/Source/UiRenderer.h +++ b/Gems/LyShine/Code/Source/UiRenderer.h @@ -19,8 +19,6 @@ #include #endif -class ITexture; - //////////////////////////////////////////////////////////////////////////////////////////////////// //! UI render interface // @@ -137,6 +135,9 @@ public: // member functions //! Display debug texture data after rendering void DebugDisplayTextureData(int recordingOption); + + //! Track textures being used in the current frame + void DebugUseTexture(AZ::Data::Instance image); #endif private: // member functions @@ -179,6 +180,6 @@ protected: // attributes #ifndef _RELEASE int m_debugTextureDataRecordLevel = 0; - AZStd::unordered_set m_texturesUsedInFrame; // [LYN-7857] - Support debug display with Atom + AZStd::unordered_set> m_texturesUsedInFrame; #endif };