Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
I have performance problem with my DrawingVisualHost. I'm writing an application which processing MusicXML files and draws music score (using loaded information) on Canvas.

Simple Canvas structure below:

Main Canvas (acts like page usually size of A4 paper of sheet),
+ Canvas for each line of music scores (up to 6-8),
+ Custom panel to arrange items(notes,rests generally any music item)
+ Each music element item is Canvas with DrawingVisualHost as children
+ DrawingVisualHost contains usually one-two drawingVisuals

The problem is when I'm moving mouse cursor inside area of Main Canvas on every cursor move I'm getting very large amount of calls to every DrawingVisualHost GetVisualChild(int index) method which cause very high CPU usage with large collections

This is my DrawingVisualHost code:
C#
 public class DrawingVisualHost : FrameworkElement
 {
     private List<Visual> visuals;

     public DrawingVisualHost()
     {
         visuals = new List<Visual>();
         IsHitTestVisible = true;
     }
     protected override Visual GetVisualChild(int index)
     {
         return visuals[index];
     }
     protected override int VisualChildrenCount
     {
         get
         {
             return visuals.Count;
         }
     }
     public void AddVisual(Visual visual)
     {
         visuals.Add(visual);
         AddVisualChild(visual);
     }
}


What I have tried:

I've spent two days trying to understand what is going on here, code looks ok, no exceptions, no Hit testing, no MouseEvents attached to any Canvas... nothing.

When I placed breakpoint inside this method and I moved cursor on Main Canvas area. Call stack shows only:
MusicXMLScore.exe!MusicXMLScore.Helpers.DrawingVisualHost.GetVisualChild(int index = 1) Line 25
and
C#
[External code]

with External code filter off:
C#
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)	
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsOuterSpace(bool renderBounds)
PresentationCore.dll!System.Windows.Media.Visual.CalculateSubgraphBoundsInnerSpace(bool renderBounds = false)
PresentationCore.dll!System.Windows.Media.Visual.VisualDescendantBounds.get()
PresentationCore.dll!System.Windows.Media.Visual.TrySimpleTransformToAncestor(System.Windows.Media.Visual ancestor = {MusicXMLScore.MainWindow}, bool inverse = true, out System.Windows.Media.GeneralTransform generalTransform = null, out System.Windows.Media.Matrix simpleTransform = {System.Windows.Media.Matrix})
PresentationCore.dll!System.Windows.Input.InputElement.TranslatePoint(System.Windows.Point pt, System.Windows.DependencyObject from, System.Windows.DependencyObject to, out bool translated = false)
PresentationCore.dll!System.Windows.Input.InputElement.TranslatePoint(System.Windows.Point pt, System.Windows.DependencyObject from, System.Windows.DependencyObject to)
PresentationCore.dll!System.Windows.Input.MouseDevice.PreNotifyInput(object sender, System.Windows.Input.NotifyInputEventArgs e = {System.Windows.Input.NotifyInputEventArgs})
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea()
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input)
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport)
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel)
PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd = {System.IntPtr}, MS.Internal.Interop.WindowMessage msg = WM_MOUSEFIRST, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}, ref bool handled = false)
PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd = {System.IntPtr}, int msg = 512, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}, ref bool handled = false)
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd = {System.IntPtr}, int msg = 512, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr}, ref bool handled = false)
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler = null)
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd = {System.IntPtr}, int msg = 512, System.IntPtr wParam = {System.IntPtr}, System.IntPtr lParam = {System.IntPtr})
[Native to Managed Transition]	
[Managed to Native Transition]	
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame = {System.Windows.Threading.DispatcherFrame})
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame)
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore)
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window)
PresentationFramework.dll!System.Windows.Application.Run(System.Windows.Window window)
PresentationFramework.dll!System.Windows.Application.Run()
MusicXMLScore.exe!MusicXMLScore.App.Main()
[Native to Managed Transition]	
[Managed to Native Transition]	
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args)
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()
Posted
Updated 7-Apr-17 12:09pm
v2

1 solution

Ok, after last hours of digging I think I found cause. I don't know why, but when I disabled DropShadow Effect attached to Items Control which binds to collection of Pages(Main Canvases) the problem seems to be solved.
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <ItemsControl x:Name="PagesCollection" Margin="0,5,0,5" ItemsSource="{Binding PagesCollection}">
        <!--<ItemsControl.Effect>
            <DropShadowEffect Color="Gray" BlurRadius="5" ShadowDepth="5"/>
        </ItemsControl.Effect>-->
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <helpers:SimpleWrapPanel Margin="10"></helpers:SimpleWrapPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</ScrollViewer>

So, now I have other issue, where or how to add shadow to every Canvas of PagesCollection ?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900