View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001415 | NoesisGUI | C++ SDK | public | 2019-02-27 07:23 | 2020-12-24 12:58 |
Reporter | nikobarli | Assigned To | jsantos | ||
Priority | normal | Severity | block | Reproducibility | always |
Status | assigned | Resolution | open | ||
Product Version | 2.2.0b6 | ||||
Summary | 0001415: 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. | ||||
Tags | No tags attached. | ||||
Platform | Windows | ||||
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.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> |
|
I ran ETW to find the hotspot. |
|
The tessellator is going nuts at that resolution. I will have a look at it later. Meanwhile could you limit the pitch length? | |
We are still away from release date, so I think we can wait for the fix. | |
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 ? |
|
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! |
|
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"); |
|
Hi Niko, I am already working on this, the internal tessellator is being optimized. I will keep you posted. | |
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. |
|
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"); } |
|
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. |
|
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 => |