Por que o uso de canetas com padrões de traço causar enorme (!) A degradação do desempenho em WPF costume desenho 2D?

StackOverflow https://stackoverflow.com/questions/537950

  •  22-08-2019
  •  | 
  •  

Pergunta

Hope qualquer um pode lançar luz sobre isso para que eu possa usar canetas com padrões de traço?

Eu estou escrevendo um gráfico de rolagem (a Panel dentro ScrollViewer que implementos IScrollInfo) em WPF usando DrawingVisual de DataContext.Draw X . Eu tenho vários milhares de DrawingVisuals que são enroladas usando TranslateTransform na Panel que os hospeda. Eu implementei uma grade, colocando um Panel em cima dela e desenhar linhas horizontais simples de uma ponta para a outra usando DataContext.DrawLine(pen, new Point(0, y), new Point(widthOfPanel, y)); // (nota: estas linhas são sempre estáticos, eles nunca se mover).

O desempenho de rolagem é absolutamente insano (isto é, DrawingVisual de são atraídos instantaneamente e rolagem é instantânea). Mas se eu usar um Pen que os padrões de usos traço (veja abaixo, por exemplo) para desenhar as linhas de grade, em seguida, a rolagem é muito jerky eo desempenho parece ter sido reduzida por um fator de 100 (uma estimativa). Alguém pode explicar por que isso acontece e como posso resolver isso?

Exemplo de Pen com padrão de traço:

<Pen x:Key="PenUsingDashPatterns" Brush="Black" Thickness="1">
   <Pen.DashStyle >
      <DashStyle Dashes="3, 3" />
   </Pen.DashStyle>
</Pen>
Foi útil?

Solução

são os canetas ser congelado? Congelar objetos de desenho ajuda desempenho muito.

Você pode configurar um manipulador Loaded e debug para ver se suas canetas são congelados. Se não, chame o botão Pen.Freeze () manualmente sobre eles.

Note que congelamento também torna as canetas somente leitura ... você não será capaz de modificá-los depois de congelá-los.

Outras dicas

Aqui está uma solução possível - se você está apenas desenhando linhas horizontais e / ou verticais, você pode tentar criar seu Pen com um DrawingBrush padrão axadrezado tais como:

  <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>   

Como alternativa, você poderia usar escovas diferentes para linhas verical e horizontais, ou, possivelmente, um ImageBrush para um melhor desempenho.

Você deve usar o perfurador a aprofundar o problema de desempenho. Aqui está um link para o site MSDN falando sobre várias ferramentas WPF desempenho . Perfurador seria provavelmente a ferramenta que irá ajudá-lo a mais, especialmente para determinar se as linhas estão sendo traçadas usando o renderizador de software (o que seria o maior fator em dar-lhe tal desempenho ruim).

Se o problema é que eles estão sendo desenhado em software, você pode ter que escrever o seu próprio ShaderEffect , mas que provavelmente vai ficar rápido complicado a menos que você está familiarizado com HLSL.

Provavelmente isso é porque esta operação empate em particular não é algo que pode ser delegada à placa de vídeo, o que forçaria composição na memória e blitting para a placa de vídeo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top