Perché l'uso di penne con i modelli del precipitare causare enorme (!) Il degrado delle prestazioni nel disegno 2D WPF personalizzato?
Domanda
La speranza chiunque può far luce su questo in modo da poter utilizzare le penne con i modelli del precipitare?
Sto scrivendo un grafico scorrevole (un Panel
all'interno ScrollViewer
che implementa IScrollInfo
) in WPF utilizzando DrawingVisual
di DataContext.Draw
X . Ho diverse migliaia di DrawingVisual
s che vengono lo scrolling utilizzando TranslateTransform
sul Panel
che li ospita. Ho implementato una griglia posizionando un Panel
su di esso e disegnare semplici linee orizzontali da un bordo all'altro usando DataContext.DrawLine(pen, new Point(0, y), new Point(widthOfPanel, y));
// (nota: queste linee sono sempre statici, non si muovono mai).
Le prestazioni di scorrimento è assolutamente folle (cioè DrawingVisual di sono attratti immediatamente e lo scorrimento è immediato). Ma se utilizzo Pen
che utilizza modelli di trattino (vedi sotto per esempio) per disegnare le linee della griglia, poi scorre è molto a scatti e le prestazioni sembra essere stata diminuita di un fattore 100 (stimato). Qualcuno può spiegare perché ciò accade e come posso risolvere questo?
Esempio di penna con motivo di tratteggio:
<Pen x:Key="PenUsingDashPatterns" Brush="Black" Thickness="1">
<Pen.DashStyle >
<DashStyle Dashes="3, 3" />
</Pen.DashStyle>
</Pen>
Soluzione
Sono le penne ottenere congelati? Congelamento oggetti di disegno aiuta le prestazioni molto.
È possibile impostare un gestore di Loaded ed eseguire il debug per vedere se le penne sono congelati. In caso contrario, chiamare il tasto Pen.Freeze () manualmente su di loro.
Si noti che il congelamento fa anche le penne di sola lettura ... si sarà in grado di modificarli dopo averli congelare.
Altri suggerimenti
Ecco una possibile soluzione - se si sta solo disegno o da linee orizzontali e verticali / si potrebbe provare a creare il tuo Pen
con un DrawingBrush
modello di controllo come ad esempio:
<Pen x:Key="PenUsingDashPatterns" Thickness="1">
<Pen.Brush>
<DrawingBrush TileMode="Tile"
Viewport="0 0 6 6" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0 0 3 3"/>
<RectangleGeometry Rect="3 3 3 3"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Pen.Brush>
</Pen>
In alternativa, è possibile utilizzare vari pennelli per verical e linee orizzontali, o, eventualmente, un ImageBrush
per migliorare le prestazioni.
Si dovrebbe usare perforatore a scavare più a fondo il problema di prestazioni. Ecco un link al sito di MSDN parlando di vari WPF Performance Tools . Perforatore sarebbe probabilmente lo strumento che vi aiuterà di più, specialmente nel determinare se le linee sono in fase di elaborazione con il renderer software (che sarebbe il più grande fattore nel dare tali prestazioni cattivo).
Se il problema è che sono in fase di elaborazione nel software, potrebbe essere necessario scrivere il proprio ShaderEffect , ma che probabilmente ottenere difficile veloce a meno che non si ha familiarità con HLSL.
Molto probabilmente questo è perché questa particolare operazione pareggio non è qualcosa che può essere delegato alla scheda video, che costringerebbero la composizione in memoria e di copiarlo sul video alla scheda video.