View Issue Details

IDProjectCategoryView StatusLast Update
0001700NoesisGUIC++ SDKpublic2020-05-28 17:33
Reportersteveh Assigned Tojsantos  
PrioritynormalSeveritymajor 
Status resolvedResolutionfixed 
Product Version3.0.0 
Target Version3.0.1Fixed in Version3.0.1 
Summary0001700: Crash / memory stomp in SDF generator
Description

Hi guys,

I'm seeing an assert which is ultimately leading to a memory overwrite in the SDF Generator. We are running at 4k UI and we have a text popup we plays an animation and scales larger than the screen. The text is also drawing to the offscreen buffer, I'm not sure if that makes a difference.

The full callstack is as follows:

Noesis::SDFGenerator::Begin(int width, int height) Line 1103 C++
Noesis::GlyphCache::RenderSDF(Noesis::GlyphCache::Glyph glyph, Noesis::FTFaceRec face, unsigned int index, unsigned int size, long stroke) Line 397 C++
Noesis::GlyphCache::GetGlyph(Noesis::VGLFontFace face, unsigned int index, unsigned int size, long stroke, bool inLayer) Line 527 C++
Noesis::GlyphCache::CacheGlyph(Noesis::VGLFontFace
face, unsigned int index, unsigned int size, long stroke) Line 147 C++
Noesis::VGLContext::DrawRunForeground(Noesis::VGLTextLayout layout, const Noesis::Transform2 & mtx, Noesis::Glyph glyphs, const Noesis::GlyphRun & run, const Noesis::TextProperties & p, Noesis::VGLPaint paint, const Noesis::BatchGroup & k, float scale, Noesis::GeoBuilderType builder, unsigned short runIndex, unsigned char flags) Line 3028 C++
Noesis::VGLContext::DrawTextLayout(Noesis::VGLTextLayout
layout, const Noesis::Transform2 & mtx, Noesis::VGLPaint paints, unsigned int numPaints, unsigned int flags_) Line 1228 C++
Noesis::RenderTreeHelper::DrawTextLayout(Noesis::VGLTextLayout textLayout, Noesis::BrushProxy brushes, unsigned int numBrushes, unsigned int flags, const Noesis::Rect & bounds, const Noesis::Transform2 & transform) Line 470 C++
Noesis::RenderTreeHelper::DrawCommands(Noesis::RenderNode
node, const Noesis::Recti & surfaceRect, Noesis::DrawingCommandsProxy drawCommands, const Noesis::Transform2 & transform, const Noesis::Matrix4 & projection, bool isProjectionIdentity, unsigned int bitmapScalingMode) Line 274 C++
[Inline Frame] Noesis::RenderTreeHelper::RenderDraw(Noesis::RenderNode
) Line 743 C++
Noesis::RenderTreeHelper::RenderNodeRecursive(Noesis::RenderNode node, const Noesis::Recti & surfaceRect, const Noesis::Transform2 & transform, const Noesis::Matrix4 & projection, bool isProjectionIdentity, float opacity, unsigned int depth) Line 703 C++
[Inline Frame] Noesis::RenderTreeHelper::RenderChildren(Noesis::RenderNode
isProjectionIdentity, const Noesis::Recti &) Line 760 C++
Noesis::RenderTreeHelper::RenderNodeRecursive(Noesis::RenderNode node, const Noesis::Recti & surfaceRect, const Noesis::Transform2 & transform, const Noesis::Matrix4 & projection, bool isProjectionIdentity, float opacity, unsigned int depth) Line 703 C++
[Inline Frame] Noesis::RenderTreeHelper::RenderChildren(Noesis::RenderNode
isProjectionIdentity, const Noesis::Recti &) Line 760 C++
Noesis::RenderTreeHelper::RenderNodeRecursive(Noesis::RenderNode node, const Noesis::Recti & surfaceRect, const Noesis::Transform2 & transform, const Noesis::Matrix4 & projection, bool isProjectionIdentity, float opacity, unsigned int depth) Line 703 C++
Noesis::RenderTreeHelper::RenderOffscreenNodes() Line 592 C++
Noesis::RenderTreeHelper::RenderOffscreen(Noesis::RenderNode
node, const Noesis::Matrix4 & projection) Line 97 C++
Noesis::RenderTree::RenderOffscreen(const Noesis::Matrix4 & projection) Line 280 C++
Noesis::Renderer::RenderOffscreen(const Noesis::Matrix4 & projection) Line 164 C++
Noesis::Renderer::RenderOffscreen() Line 148 C++

void SDFGenerator::Begin(int width, int height)
{
NS_ASSERT(width height <= (int)sizeof(mSDF)); // <--- this hits
NS_ASSERT(width
height * (int)sizeof(DFData) <= (int)sizeof(mData));

In my case, width is 79 and height is 66. If I go back up the stack, the cbox.xMax is 3840 (the width of my render target) and the cbox.xmin is -704. So width ends up being (3840 + 704) >> 6 which is 79, and the height ends up as (2816 + 896) >> 6 which is 66.

I tried to reproduce this locally in XamlPlayer but was unable to. I'm attaching something very similar to what we have in game, but it doesn't assert or crash in XamlPlayer.

Steps To Reproduce
  1. Create a textblock which is almost the full screen in 4k.
  2. Scale the textblock. Also change the opacity to ensure it draws to an offscreen buffer.
Attached Files
test.xaml (1,383 bytes)   
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions"
  Background="Gray" Width="3840" Height="2160">
  <Grid.Resources>
    <Storyboard x:Key="zoom" RepeatBehavior="Forever">
      <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Popup" Storyboard.TargetProperty="RenderTransform.ScaleX">
        <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="2"/>
      </DoubleAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Popup" Storyboard.TargetProperty="RenderTransform.ScaleY">
        <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="2"/>
      </DoubleAnimationUsingKeyFrames>
    </Storyboard>
  </Grid.Resources>
  <Grid.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
      <BeginStoryboard Storyboard="{StaticResource zoom}"/>
    </EventTrigger>
  </Grid.Triggers>
  <TextBlock Name="Popup" Text="POPUP!" FontSize="1024" TextAlignment="Center" RenderTransformOrigin="0.5,0.5" Opacity="0.5">
    <TextBlock.RenderTransform>
       <ScaleTransform ScaleX="1.0" ScaleY="1.0" />
    </TextBlock.RenderTransform>
  </TextBlock>
</Grid>
test.xaml (1,383 bytes)   
PlatformAny

Activities

steveh

steveh

2020-05-27 00:52

reporter   ~0006391

I've just realised it actually crashes on the stroke. I've added strokes to the test XAML and it doesn't assert, but I do notice some artifacts. It seems the large the text the more noticeable the artifacts. I wonder if it is causing an issue but the compiled XAMLPlayer hasn't got asserts enabled? I'm attaching a new version with a stroke.

test2.xaml (1,447 bytes)   
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions"
  Background="Gray" Width="3840" Height="2160">
  <Grid.Resources>
    <Storyboard x:Key="zoom" RepeatBehavior="Forever">
      <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Popup" Storyboard.TargetProperty="RenderTransform.ScaleX">
        <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="2"/>
      </DoubleAnimationUsingKeyFrames>
      <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Popup" Storyboard.TargetProperty="RenderTransform.ScaleY">
        <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="2"/>
      </DoubleAnimationUsingKeyFrames>
    </Storyboard>
  </Grid.Resources>
  <Grid.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded">
      <BeginStoryboard Storyboard="{StaticResource zoom}"/>
    </EventTrigger>
  </Grid.Triggers>
  <TextBlock Name="Popup" Text="POPUP!" FontSize="512" TextAlignment="Center" RenderTransformOrigin="0.5,0.5" Opacity="0.5" noesis:Text.Stroke="#FFE4E4E4" noesis:Text.StrokeThickness="12" >
    <TextBlock.RenderTransform>
       <ScaleTransform ScaleX="1.0" ScaleY="1.0" />
    </TextBlock.RenderTransform>
  </TextBlock>
</Grid>
test2.xaml (1,447 bytes)   
jsantos

jsantos

2020-05-27 01:54

manager   ~0006392

I am able to reproduce this and it's been reported by more clients. It will be fixed in 3.0.1, the artifacts are probably a different thing, I will analyze it carefully and tell you.

jsantos

jsantos

2020-05-28 17:33

manager   ~0006412

Artifacts in the stroke are a different thing. That's related to the new SDF algorithm. Please, open a new ticket if after this fix that's still an issue for you.
Thanks for your great feedback!

Issue History

Date Modified Username Field Change
2020-05-27 00:45 steveh New Issue
2020-05-27 00:45 steveh File Added: test.xaml
2020-05-27 00:52 steveh File Added: test2.xaml
2020-05-27 00:52 steveh Note Added: 0006391
2020-05-27 01:53 jsantos Assigned To => jsantos
2020-05-27 01:53 jsantos Status new => assigned
2020-05-27 01:53 jsantos Target Version => 3.0.1
2020-05-27 01:53 jsantos Description Updated
2020-05-27 01:53 jsantos Steps to Reproduce Updated
2020-05-27 01:54 jsantos Note Added: 0006392
2020-05-28 17:33 jsantos Status assigned => resolved
2020-05-28 17:33 jsantos Resolution open => fixed
2020-05-28 17:33 jsantos Fixed in Version => 3.0.1
2020-05-28 17:33 jsantos Note Added: 0006412