View Issue Details

IDProjectCategoryView StatusLast Update
0001415NoesisGUIC++ SDKpublic2020-12-24 12:58
Reporternikobarli Assigned Tojsantos  
PrioritynormalSeverityblock 
Status assignedResolutionopen 
Product Version2.2.0b6 
Summary0001415: Drawing Path takes a very long time when the pitch is less than 0.5 pixel
Description

We have a scenario where we draws a line path from approx 1000~2000 points, and in some cases NoesisGUI rendering became very slow to more than 500 ms (less than 2 fps).

We tracked down the problem and it seems that it happens when the pitch of the points are less than 0.5 pixel.
I attached the sample XAML and cpp that reproduce the problem and the screen shot. Please adjust the bar so that the pitch length becomes less than 0.5.

Attached Files
DataBinding.cpp (3,807 bytes)   
#include "stdafx.h"
#include <boost/make_shared.hpp>
#include "NoesisTutorial.h"

#include <ZioLog/ZioLog.h>
#include <ZioLog/ZBLK.h>

// #ifdef _DEBUG
// #define new DEBUG_NEW
// #endif

ZLOGFACILITY("DataBinding");

using namespace Noesis;
using namespace NoesisUtil;

namespace NoesisTutorial {
    //----------------------------------------------------
    // DataBinding NoesisGUI element
    //----------------------------------------------------
    class DataBinding : public UserControl
    {
    private:
        void InitializeComponent()
        {
            __ZBLK__;
            LINFO((__FUNCTION__));
            GUI::LoadComponent(this, FormatResourcePath("DataBinding.xaml").c_str());
        }

    public:
        DataBinding()
        {
            LINFO((__FUNCTION__));
            InitializeComponent();
        }

        virtual ~DataBinding()
        {
            __ZBLK__;
            LINFO((__FUNCTION__));
        }

    public:
        NS_IMPLEMENT_INLINE_REFLECTION(DataBinding, UserControl)
        {
            NsMeta<TypeId>("NoesisTutorial.DataBinding");
        }
    };



    //----------------------------------------------------
    // DataBindingVM
    //----------------------------------------------------
    
    NS_DECLARE_SYMBOL(PointCount);
    NS_DECLARE_SYMBOL(PathLength);
    NS_DECLARE_SYMBOL(Pitch);
    NS_DECLARE_SYMBOL(PathData);

    class DataBindingVM : public BaseComponent, public INotifyPropertyChanged
    {
    public:
        NS_IMPLEMENT_INTERFACE_FIXUP

    public:
        DataBindingVM()
        {
            setupPath();
        }

        void setupPath()
        {
            int yBase = 50;
            m_pitch = (float)m_length / (float)m_count;

            m_pathData = MakePtr<StreamGeometry>();
            StreamGeometryContext context = m_pathData->Open();
            context.BeginFigure(Point(0, yBase), false);

            for (int i = 0; i < m_count; i++) {
                float x = i * m_pitch;
                float y = yBase + (((i % 2) == 0) ? 10 : -10);
                context.LineTo(Point(x, y));
            }
            context.Close();

            _propertyChanged(this, NSS(Pitch));
            _propertyChanged(this, NSS(PathData));
        }

        // From INotifyPropertyChanged
        PropertyChangedEventHandler& PropertyChanged() override { return _propertyChanged; }

    private:
        Ptr<StreamGeometry> m_pathData;
        int m_count = 100;
        int m_length = 300;
        float m_pitch = .0f;

        int GetPointNum() const { return m_count; }
        float GetLength() const { return m_length; }

        void SetPointNum(int num) {
            m_count = num;
            _propertyChanged(this, NSS(PointCount));
            setupPath();
        }
        void SetLength(float w) {
            m_length = w;
            _propertyChanged(this, NSS(PathLength));
            setupPath();
        }

        PropertyChangedEventHandler _propertyChanged;

        NS_IMPLEMENT_INLINE_REFLECTION(DataBindingVM, BaseComponent)
        {
            NsMeta<TypeId>("NoesisTutorial.DataBindingVM");
            NsImpl<INotifyPropertyChanged>();
            NsProp("PointCount", &DataBindingVM::GetPointNum, &DataBindingVM::SetPointNum);
            NsProp("PathLength", &DataBindingVM::GetLength, &DataBindingVM::SetLength);
            NsProp("Pitch", &DataBindingVM::m_pitch);
            NsProp("PathData", &DataBindingVM::m_pathData);
        }
    };

    Ptr<BaseComponent> CreateContext_DataBinding() {
        return MakePtr<DataBindingVM>();
    }

    NOESIS_COMP_REGISTRATION(DataBinding);
    NOESIS_COMP_REGISTRATION(DataBindingVM);
}

DataBinding.cpp (3,807 bytes)   
DataBinding.xaml (1,353 bytes)   
<UserControl x:Class="NoesisTutorial.DataBinding"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:NoesisTutorial"
             mc:Ignorable="d" 
             FontFamily="Meiryo UI" 
             d:DataContext="{d:DesignInstance {x:Type local:DataBindingVM}, IsDesignTimeCreatable=True}"
             d:DesignHeight="300" d:DesignWidth="400">
    <Grid Background="White">
        <StackPanel Orientation="Vertical">
            <TextBlock Foreground="Black" Text="{Binding PointCount, StringFormat=Point Count: {0}}"/>
            <Slider Minimum="100" Maximum="2000" Value="{Binding PointCount}"/>

            <TextBlock Foreground="Black" Text="{Binding PathLength, StringFormat=Length: {0}}"/>
            <Slider Minimum="10" Maximum="1000" Value="{Binding PathLength}"/>

            <TextBlock Foreground="Black" Text="{Binding Pitch, StringFormat=Pitch: {0}}"/>
            <Canvas>
                <Path Data="{Binding PathData}" Stroke="Red" />
            </Canvas>
        </StackPanel>
    </Grid>
</UserControl>
DataBinding.xaml (1,353 bytes)   
PathRenderingSlow.PNG (7,991 bytes)   
PathRenderingSlow.PNG (7,991 bytes)   
PlatformWindows

Relationships

related to 0001863 resolvedjsantos New Tessellator 

Activities

nikobarli

nikobarli

2019-02-27 07:47

reporter   ~0005484

I ran ETW to find the hotspot.

HotSpot.PNG (58,163 bytes)   
HotSpot.PNG (58,163 bytes)   
jsantos

jsantos

2019-03-01 13:21

manager   ~0005487

The tessellator is going nuts at that resolution. I will have a look at it later. Meanwhile could you limit the pitch length?

nikobarli

nikobarli

2019-03-02 02:45

reporter   ~0005490

We are still away from release date, so I think we can wait for the fix.

nikobarli

nikobarli

2020-09-04 06:33

reporter   ~0006614

Hi Jesus,

Is there any update on this ? We deferred implementing a feature to the next version due to this.
Is is possible to have this fix in Noesis 3.0.x ?

jsantos

jsantos

2020-09-04 17:11

manager   ~0006615

Hi Niko,

No updates yet sorry about it. Yes, I want to have this fixed in 3.0.X

Do you think it is possible to pack a minimal application reproducing the issue?

Thanks!

nikobarli

nikobarli

2020-09-07 14:42

reporter   ~0006617

Hi Jesus,

I attached a patch for your HelloWorld demo program (Noesis version 2.x).
Please adjust the slider to make the pitch lower than 0.5 to reproduce the problem.

NoesisPathSlow.patch (24,151 bytes)   
Index: Packages/Samples/HelloWorld/Data/MainWindow.xaml
===================================================================
--- Packages/Samples/HelloWorld/Data/MainWindow.xaml	(revision 146550)
+++ Packages/Samples/HelloWorld/Data/MainWindow.xaml	(working copy)
@@ -7,209 +7,18 @@
         mc:Ignorable="d"
         Background="#FF124C7A"
         Title="NoesisGUI - Hello, World!">
+  <Grid Background="White">
+    <StackPanel Orientation="Vertical">
+      <TextBlock Foreground="Black" Text="{Binding PointCount, StringFormat=Point Count: {0}}"/>
+      <Slider Minimum="100" Maximum="2000" Value="{Binding PointCount}"/>
 
-    <Window.Resources>
-        <Storyboard x:Key="Intro">
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="Word">
-                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="276.8">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <CubicEase EasingMode="EaseInOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="GUI">
-                <EasingColorKeyFrame KeyTime="0" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:0.5" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:0.8" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:1.2" Value="#FF2AA6E2"/>
-            </ColorAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="Logo">
-                <EasingDoubleKeyFrame KeyTime="0" Value="-4"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
-            </DoubleAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="Logo">
-                <EasingDoubleKeyFrame KeyTime="0" Value="-180"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <ExponentialEase EasingMode="EaseInOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="Logo">
-                <EasingDoubleKeyFrame KeyTime="0" Value="0.5"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <BackEase EasingMode="EaseOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="Logo">
-                <EasingDoubleKeyFrame KeyTime="0" Value="0.5"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <BackEase EasingMode="EaseOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Line1">
-                <EasingColorKeyFrame KeyTime="0" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:0.3" Value="#FF2AA6E2"/>
-            </ColorAnimationUsingKeyFrames>
-            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Line2">
-                <EasingColorKeyFrame KeyTime="0" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:0.1" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:0.4" Value="#FF2AA6E2"/>
-            </ColorAnimationUsingKeyFrames>
-            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Line3">
-                <EasingColorKeyFrame KeyTime="0" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:0.2" Value="#002AA6E2"/>
-                <EasingColorKeyFrame KeyTime="0:0:0.5" Value="#FF2AA6E2"/>
-            </ColorAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="GUI">
-                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="1.1"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="1">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <ExponentialEase EasingMode="EaseInOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="GUI">
-                <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="1.1"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="1">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <ExponentialEase EasingMode="EaseInOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="Hello">
-                <EasingColorKeyFrame KeyTime="0" Value="Transparent"/>
-                <EasingColorKeyFrame KeyTime="0:0:1" Value="Transparent"/>
-                <EasingColorKeyFrame KeyTime="0:0:1.3" Value="White">
-                    <EasingColorKeyFrame.EasingFunction>
-                        <SineEase EasingMode="EaseInOut"/>
-                    </EasingColorKeyFrame.EasingFunction>
-                </EasingColorKeyFrame>
-            </ColorAnimationUsingKeyFrames>
-            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="World">
-                <EasingColorKeyFrame KeyTime="0" Value="Transparent"/>
-                <EasingColorKeyFrame KeyTime="0:0:1.2" Value="Transparent"/>
-                <EasingColorKeyFrame KeyTime="0:0:1.5" Value="White">
-                    <EasingColorKeyFrame.EasingFunction>
-                        <SineEase EasingMode="EaseInOut"/>
-                    </EasingColorKeyFrame.EasingFunction>
-                </EasingColorKeyFrame>
-            </ColorAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="Hello">
-                <EasingDoubleKeyFrame KeyTime="0" Value="-40"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-40"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.3" Value="0">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <SineEase EasingMode="EaseInOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="World">
-                <EasingDoubleKeyFrame KeyTime="0" Value="-40"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="-40"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="0">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <SineEase EasingMode="EaseInOut"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)" Storyboard.TargetName="Hello">
-                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="20"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.3" Value="0">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <BackEase EasingMode="EaseIn"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)" Storyboard.TargetName="World">
-                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="20"/>
-                <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="0">
-                    <EasingDoubleKeyFrame.EasingFunction>
-                        <BackEase EasingMode="EaseIn"/>
-                    </EasingDoubleKeyFrame.EasingFunction>
-                </EasingDoubleKeyFrame>
-            </DoubleAnimationUsingKeyFrames>
-        </Storyboard>
-    </Window.Resources>
-    <Window.Triggers>
-        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
-            <BeginStoryboard Storyboard="{StaticResource Intro}"/>
-        </EventTrigger>
-    </Window.Triggers>
-    <Grid>
-        <Viewbox>
-            <Grid Width="325.8" Margin="24">
-                <Grid HorizontalAlignment="Center">
-                    <Grid.ColumnDefinitions>
-                        <ColumnDefinition Width="Auto"/>
-                        <ColumnDefinition Width="Auto"/>
-                    </Grid.ColumnDefinitions>
-                    <Grid.RowDefinitions>
-                        <RowDefinition/>
-                        <RowDefinition/>
-                    </Grid.RowDefinitions>
-                    <Grid x:Name="Logo" Grid.Column="0" RenderTransformOrigin="0.5,0.5" Width="49">
-                        <Grid.RenderTransform>
-                            <TransformGroup>
-                                <ScaleTransform/>
-                                <SkewTransform/>
-                                <RotateTransform/>
-                                <TranslateTransform/>
-                            </TransformGroup>
-                        </Grid.RenderTransform>
-                        <Path x:Name="Line1" Data="M6.1,16 L13.7,5.7 32,8 35.7,16.7 39.4,11.9 35.5,3 11.2,0 0,15.2 3.8,24.1 9.5,24.8 6.1,16 z" Fill="#FF2AA6E2" VerticalAlignment="Center" Height="24.8" Margin="0,5.5,9.6,16.5"/>
-                        <Path x:Name="Line2" Data="M15.5,6 L20.6,17.8 9.5,32.6 0,31.4 2.4,37 12.1,38.1 26.8,18.5 19.2,1.2 9.7,0 6.2,4.6 15.5,6.1 z" Fill="#FF2AA6E2" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Height="38.1" Margin="22.2,0,0,8.7"/>
-                        <Path x:Name="Line3" Data="M26,26.8 L13.3,25.4 6.1,8.4 6,8.4 11.8,0.8 5.7,0 0,7.8 9.5,30.3 28.4,32.5 34.1,24.8 31.9,19.4 z" Fill="#FF2AA6E2" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Height="32.5" Margin="9.3,14.3,5.6,0"/>
-                    </Grid>
-                    <Grid x:Name="Word" Grid.Column="1" Width="276.8">
-                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
-                            <Path x:Name="Noesis" Data="M26.0999999999999,16.9L25.8,16.9C25.2,16.9 24.5999999999999,16.6999999999999 24.0999999999999,16.4 23.5999999999999,16.1 23.0999999999999,15.6999999999999 22.6999999999998,15.1999999999999L12.0999999999999,2.99999999999989C11.1999999999998,1.99999999999989 10.1999999999998,1.19999999999993 9.19999999999982,0.799999999999841 8.19999999999982,0.299999999999841 6.99999999999977,0.0999999999997954 5.49999999999977,0.0999999999997954L-2.27373675443232E-13,0.0999999999997954 -2.27373675443232E-13,21.9999999999998 5.19999999999982,21.9999999999998 5.19999999999982,5.19999999999982 5.49999999999977,5.19999999999982C6.09999999999968,5.19999999999982 6.69999999999982,5.39999999999986 7.19999999999982,5.69999999999982 7.79999999999973,5.99999999999977 8.19999999999982,6.39999999999986 8.59999999999991,6.89999999999986L19,18.9999999999999C19.9000000000001,20.0999999999999 20.9000000000001,20.8999999999999 21.9000000000001,21.3999999999999 23,21.8999999999999 24.2,22.0999999999999 25.8000000000002,22.0999999999999L31.3000000000002,22.0999999999999 31.3000000000002,-1.13686837721616E-13 26.1000000000001,-1.13686837721616E-13 26.0999999999999,16.9z M59.3,0L42.3999999999999,0C36.8999999999999,0,34.0999999999999,2.29999999999995,34.0999999999999,7L34.0999999999999,15C34.0999999999999,19.6,36.8999999999999,22,42.3999999999999,22L59.3,22C64.8,22,67.5999999999999,19.7,67.5999999999999,15L67.5999999999999,7C67.5999999999999,2.39999999999998,64.8,0,59.3,0z M62.2,15C62.2,16.2,61.2,16.9,59.3,16.9L42.3999999999999,16.9C40.4999999999998,16.9,39.4999999999998,16.3,39.4999999999998,15L39.4999999999998,7C39.4999999999998,5.70000000000005,40.4999999999998,5.10000000000002,42.3999999999999,5.10000000000002L59.3,5.10000000000002C61.2,5.10000000000002,62.2,5.70000000000005,62.2,7L62.2,15z M75.7,15.7999999999997L75.7,13.5999999999999 100.9,13.5999999999999 100.9,8.49999999999989 75.7,8.49999999999989 75.7,6.29999999999984C75.7,5.5999999999998,76.1000000000001,5.19999999999982,76.9000000000001,5.19999999999982L101,5.19999999999982 101,-2.27373675443232E-13 76.9000000000001,-2.27373675443232E-13C72.5,-2.27373675443232E-13,70.3000000000002,1.79999999999973,70.3000000000002,5.29999999999973L70.3000000000002,16.4999999999998C70.3000000000002,20.0999999999998,72.5000000000002,21.8999999999998,76.9000000000001,21.8999999999998L101.1,21.8999999999998 101.1,16.7999999999997 76.9000000000001,16.7999999999997C76.1000000000001,16.8999999999998,75.7,16.4999999999998,75.7,15.7999999999997z M128.5,8.39999999999998L110.2,8.39999999999998C109.4,8.39999999999998,108.9,8.10000000000002,108.9,7.60000000000002L108.9,5.89999999999998C108.9,5.39999999999998,109.3,5.10000000000002,110.2,5.10000000000002L134.4,5.10000000000002 134.4,0 110.2,0C105.8,0,103.6,1.79999999999995,103.6,5.29999999999995L103.6,8.79999999999995C103.6,11.9,105.8,13.5,110.2,13.5L128.5,13.5C129.3,13.5,129.7,13.8,129.7,14.3L129.7,16.0999999999999C129.7,16.5999999999999,129.3,16.8999999999999,128.5,16.8999999999999L104.3,16.8999999999999 104.3,21.9999999999999 128.5,21.9999999999999C132.9,21.9999999999999,135.1,20.1999999999999,135.1,16.6999999999999L135.1,13.6999999999999C135.1,10.1999999999999,132.9,8.39999999999998,128.5,8.39999999999998z M137.8,0L143.2,0 143.2,21.9 137.8,21.9z M170.8,8.39999999999998L152.5,8.39999999999998C151.7,8.39999999999998,151.2,8.10000000000002,151.2,7.60000000000002L151.2,5.89999999999998C151.2,5.39999999999998,151.6,5.10000000000002,152.5,5.10000000000002L176.7,5.10000000000002 176.7,0 152.5,0C148.1,0,145.9,1.79999999999995,145.9,5.29999999999995L145.9,8.79999999999995C145.9,11.9,148.1,13.5,152.5,13.5L170.8,13.5C171.6,13.5,172,13.8,172,14.3L172,16.0999999999999C172,16.5999999999999,171.6,16.8999999999999,170.8,16.8999999999999L146.6,16.8999999999999 146.6,21.9999999999999 170.8,21.9999999999999C175.2,21.9999999999999,177.4,20.1999999999999,177.4,16.6999999999999L177.4,13.6999999999999C177.3,10.1999999999999,175.1,8.39999999999998,170.8,8.39999999999998z" Fill="White" VerticalAlignment="Center" Margin="12,0,0,0"/>
-                            <Path x:Name="GUI" Data="M61.9000244140625,16.1C61.9000244140625,16.6,61.5000244140624,16.9,60.7000244140625,16.9L41.5000244140624,16.9C40.7000244140625,16.9,40.2000244140625,16.6,40.2000244140625,16.1L40.2000244140625,0.100000000000023 34.8000244140624,0.100000000000023 34.8000244140624,16.7C34.8000244140624,20.3000000000001,37.0000244140624,22.1,41.4000244140623,22.1L60.6000244140623,22.1C65.0000244140624,22.1,67.2000244140622,20.3000000000001,67.2000244140622,16.8000000000001L67.2000244140622,1.13686837721616E-13 61.8000244140621,1.13686837721616E-13 61.8000244140621,16.1000000000001z M70.0000244140624,0L75.4000244140625,0 75.4000244140625,21.9 70.0000244140624,21.9z M20.1000244140623,8.60000000000002L20.1000244140623,14 26.8000244140624,14 26.8000244140624,16.9 6.60002441406232,16.9C5.80002441406236,16.9,5.30002441406236,16.5,5.30002441406236,15.8L5.30002441406236,6.19999999999993C5.30002441406236,5.49999999999989,5.70002441406245,5.09999999999991,6.60002441406232,5.09999999999991L31.6000244140623,5.09999999999991 31.6000244140623,-1.13686837721616E-13 6.60002441406232,-1.13686837721616E-13C2.20002441406223,-1.13686837721616E-13,2.44140624090505E-05,1.79999999999984,2.44140624090505E-05,5.29999999999984L2.44140624090505E-05,16.4999999999999C2.44140624090505E-05,20.0999999999999,2.20002441406245,21.8999999999999,6.60002441406232,21.8999999999999L32.2000244140622,21.8999999999999 32.2000244140622,8.49999999999989 20.1000244140623,8.49999999999989z" Fill="#FF2AA6E2" VerticalAlignment="Center" Margin="12,0,0,0" RenderTransformOrigin="1,0.5">
-                                <Path.RenderTransform>
-                                    <TransformGroup>
-                                        <ScaleTransform/>
-                                        <SkewTransform/>
-                                        <RotateTransform/>
-                                        <TranslateTransform/>
-                                    </TransformGroup>
-                                </Path.RenderTransform>
-                            </Path>
-                        </StackPanel>
-                    </Grid>
-                    <StackPanel x:Name="HelloWorld" Grid.Row="1" Grid.ColumnSpan="2" Margin="0,15,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
-                        <TextBlock x:Name="Hello" Text="Hello," FontSize="20" Foreground="White" RenderTransformOrigin="0.5,0.5">
-                            <TextBlock.RenderTransform>
-                                <TransformGroup>
-                                    <ScaleTransform/>
-                                    <SkewTransform/>
-                                    <RotateTransform/>
-                                    <TranslateTransform/>
-                                </TransformGroup>
-                            </TextBlock.RenderTransform>
-                        </TextBlock>
-                        <TextBlock x:Name="World" Text="World!" FontSize="20" Foreground="White" Margin="5,0,0,0" RenderTransformOrigin="0.5,0.5">
-                            <TextBlock.RenderTransform>
-                                <TransformGroup>
-                                    <ScaleTransform/>
-                                    <SkewTransform/>
-                                    <RotateTransform/>
-                                    <TranslateTransform/>
-                                </TransformGroup>
-                            </TextBlock.RenderTransform>
-                        </TextBlock>
-                    </StackPanel>
-                </Grid>
-            </Grid>
-        </Viewbox>
-    </Grid>
+      <TextBlock Foreground="Black" Text="{Binding PathLength, StringFormat=Length: {0}}"/>
+      <Slider Minimum="10" Maximum="1000" Value="{Binding PathLength}"/>
+
+      <TextBlock Foreground="Black" Text="{Binding Pitch, StringFormat=Pitch: {0}}"/>
+      <Canvas>
+        <Path Data="{Binding PathData}" Stroke="Red" />
+      </Canvas>
+    </StackPanel>
+  </Grid>
 </Window>
Index: Packages/Samples/HelloWorld/Src/Main.cpp
===================================================================
--- Packages/Samples/HelloWorld/Src/Main.cpp	(revision 146550)
+++ Packages/Samples/HelloWorld/Src/Main.cpp	(working copy)
@@ -14,6 +14,11 @@
 #include <NsApp/Application.h>
 #include <NsApp/Window.h>
 
+#include <NsGui/IntegrationAPI.h>
+#include <NsGui/StreamGeometry.h>
+#include <NsGui/StreamGeometryContext.h>
+#include <NsApp/NotifyPropertyChangedBase.h>
+
 #include "App.xaml.bin.h"
 #include "MainWindow.xaml.bin.h"
 
@@ -24,7 +29,66 @@
 
 namespace HelloWorld
 {
+    class DataBindingVM : public NoesisApp::NotifyPropertyChangedBase
+    {
+    public:
+        NS_IMPLEMENT_INTERFACE_FIXUP
 
+    public:
+        DataBindingVM()
+        {
+            setupPath();
+        }
+
+        void setupPath()
+        {
+            float yBase = 50;
+            m_pitch = (float)m_length / (float)m_count;
+
+            m_pathData = MakePtr<StreamGeometry>();
+            StreamGeometryContext context = m_pathData->Open();
+            context.BeginFigure(Point(0, yBase), false);
+
+            for (int i = 0; i < m_count; i++) {
+                float x = i * m_pitch;
+                float y = yBase + (((i % 2) == 0) ? 10 : -10);
+                context.LineTo(Point(x, y));
+            }
+            context.Close();
+
+            OnPropertyChanged("Pitch");
+            OnPropertyChanged("PathData");
+        }
+
+    private:
+        Ptr<StreamGeometry> m_pathData;
+        int m_count = 600;
+        float m_length = 600;
+        float m_pitch = .0f;
+
+        int GetPointNum() const { return m_count; }
+        float GetLength() const { return m_length; }
+
+        void SetPointNum(int num) {
+            m_count = num;
+            OnPropertyChanged("PointCount");
+            setupPath();
+        }
+        void SetLength(float w) {
+            m_length = w;
+            OnPropertyChanged("PathLength");
+            setupPath();
+        }
+
+        NS_IMPLEMENT_INLINE_REFLECTION(DataBindingVM, NotifyPropertyChangedBase)
+        {
+            NsProp("PointCount", &DataBindingVM::GetPointNum, &DataBindingVM::SetPointNum);
+            NsProp("PathLength", &DataBindingVM::GetLength, &DataBindingVM::SetLength);
+            NsProp("Pitch", &DataBindingVM::m_pitch);
+            NsProp("PathData", &DataBindingVM::m_pathData);
+        }
+    };
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 class App final: public Application
 {
@@ -37,6 +101,24 @@
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 class MainWindow final: public Window
 {
+public:
+    MainWindow::MainWindow()
+    {
+        Initialized() += MakeDelegate(this, &MainWindow::OnInitialized);
+        InitializeComponent();
+    }
+
+private:
+    void MainWindow::InitializeComponent()
+    {
+        GUI::LoadComponent(this, "MainWindow.xaml");
+    }
+
+    void MainWindow::OnInitialized(BaseComponent*, const EventArgs&)
+    {
+        SetDataContext(MakePtr<DataBindingVM>());
+    }
+
     NS_IMPLEMENT_INLINE_REFLECTION(MainWindow, Window)
     {
         NsMeta<TypeId>("HelloWorld.MainWindow");
NoesisPathSlow.patch (24,151 bytes)   
jsantos

jsantos

2020-12-01 18:20

manager   ~0006851

Hi Niko, I am already working on this, the internal tessellator is being optimized. I will keep you posted.

jsantos

jsantos

2020-12-21 13:25

manager   ~0006910

Last edited: 2020-12-21 13:27

Hi Niko, we have a new tessellator, it is around 10x faster that the current one. I have been trying your scenario today and although it is a lot faster it is still inefficient. The main reason is that when pitch goes under 0.5 the lines (stroked lines) start to auto-intersect and generate a lot of extra points. There are ways to improve this in the tessellator, but it is going to add more overhead to normal cases so I don't think that's a good idea.

There are different solutions to solve this very efficiently. First, in 3.1 we are improving the OnRender virtual call to be very fast. So, once we have that in that 3.1 we recommend moving your code to OnRender and draw all the lines you need there.

While you are in 3.0, I recommend the following:

  • Use MeshGeometry class to manually generate vertices and indices for your path. That way, we avoid the tessellator and the stroker. This solution is also very fast but a bit cumbersome in comparison with OnRender.
  • Probably under a pitch of 0.5 you want to render a solid quad, beacuse at that point you barely see the lines and they generate a lot of aliasing.

Please, let me know your thoughts. The new tessellation is being integrated into /trunk/ this week.

jsantos

jsantos

2020-12-21 13:41

manager   ~0006911

Last edited: 2020-12-21 13:42

I also was able to slightly improve the efficiency of your code by generating individual lines instead of connected lines. This generates less geometry as the join is avoided.


void setupPath()
{
float yBase = 50;
m_pitch = (float)m_length / (float)m_count;

m_pathData = MakePtr<StreamGeometry>();
StreamGeometryContext context = m_pathData->Open();

Point last = Point(0, yBase);

for (int i = 0; i < m_count; i++) {
    float x = i * m_pitch;
    float y = yBase + (((i % 2) == 0) ? 10 : -10);

    context.BeginFigure(last, false);
    context.LineTo(Point(x, y));
    last = Point(x, y);
}
context.Close();

OnPropertyChanged("Pitch");
OnPropertyChanged("PathData");

}

nikobarli

nikobarli

2020-12-23 01:00

reporter   ~0006915

Hi Jesus,

Thank you for the update.

We confirm that the workaround for 3.0 using MeshGeometry is feasible for us.
So I think you can go forward with your plan.

Issue History

Date Modified Username Field Change
2019-02-27 07:23 nikobarli New Issue
2019-02-27 07:23 nikobarli File Added: DataBinding.cpp
2019-02-27 07:23 nikobarli File Added: DataBinding.xaml
2019-02-27 07:23 nikobarli File Added: PathRenderingSlow.PNG
2019-02-27 07:47 nikobarli File Added: HotSpot.PNG
2019-02-27 07:47 nikobarli Note Added: 0005484
2019-03-01 13:21 jsantos Note Added: 0005487
2019-03-01 13:21 jsantos Assigned To => jsantos
2019-03-01 13:21 jsantos Status new => feedback
2019-03-02 02:45 nikobarli Note Added: 0005490
2019-03-02 02:45 nikobarli Status feedback => assigned
2020-09-04 06:33 nikobarli Note Added: 0006614
2020-09-04 17:10 jsantos Target Version => 3.0
2020-09-04 17:10 jsantos Description Updated
2020-09-04 17:11 jsantos Note Added: 0006615
2020-09-04 17:11 jsantos Status assigned => feedback
2020-09-07 14:42 nikobarli File Added: NoesisPathSlow.patch
2020-09-07 14:42 nikobarli Note Added: 0006617
2020-09-07 14:42 nikobarli Status feedback => assigned
2020-09-09 13:07 jsantos Target Version 3.0 => 3.0.6
2020-09-25 14:00 jsantos Target Version 3.0.6 => 3.0.7
2020-10-28 11:08 jsantos Target Version 3.0.7 => 3.0.8
2020-12-01 18:20 jsantos Note Added: 0006851
2020-12-03 13:12 jsantos Target Version 3.0.8 => 3.0.9
2020-12-21 13:25 jsantos Note Added: 0006910
2020-12-21 13:25 jsantos Status assigned => feedback
2020-12-21 13:27 jsantos Note Edited: 0006910
2020-12-21 13:41 jsantos Note Added: 0006911
2020-12-21 13:41 jsantos Note Edited: 0006911
2020-12-21 13:42 jsantos Note Edited: 0006911
2020-12-21 20:24 jsantos Relationship added related to 0001863
2020-12-23 01:00 nikobarli Note Added: 0006915
2020-12-23 01:00 nikobarli Status feedback => assigned
2020-12-24 12:58 jsantos Target Version 3.0.9 =>