2010-03-06 14 views
8

Tengo problemas con el rendimiento de dibujo de WPF. Hay muchos pequeños objetos EllipseGeometry (1024 elipses, por ejemplo), que se agregan a tres GeometryGroups separados con diferentes pinceles de primer plano. Después, lo renderizo todo con un simple control de imagen. Código:Rendimiento de dibujo de WPF con un gran número de geometrías

DrawingGroup tmpDrawing = new DrawingGroup(); 
GeometryGroup onGroup = new GeometryGroup(); 
GeometryGroup offGroup = new GeometryGroup(); 
GeometryGroup disabledGroup = new GeometryGroup(); 

for (int x = 0; x < DisplayWidth; ++x) 
{ 
    for (int y = 0; y < DisplayHeight; ++y) 
    { 
     if (States[x, y] == true) onGroup.Children.Add(new EllipseGeometry(new Rect((double)x * EDGE, (double)y * EDGE, EDGE, EDGE))); 
     else if (States[x, y] == false) offGroup.Children.Add(new EllipseGeometry(new Rect((double)x * EDGE, (double)y * EDGE, EDGE, EDGE))); 
     else disabledGroup.Children.Add(new EllipseGeometry(new Rect((double)x * EDGE, (double)y * EDGE, EDGE, EDGE))); 
    } 
} 

tmpDrawing.Children.Add(new GeometryDrawing(OnBrush, null, onGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(OffBrush, null, offGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(DisabledBrush, null, disabledGroup)); 
DisplayImage.Source = new DrawingImage(tmpDrawing); 

Funciona bien, pero lleva demasiado tiempo -> 0,5 s en el Core 2 Quad,> 2s en Pentium 4. Necesito < 0.1s todas partes. Todas las elipsis, como puedes ver, son iguales. El fondo de control, donde está mi DisplayImage, es sólido (negro, por ejemplo), así que podemos usar este hecho. Traté de usar 1024 elementos Elipse en lugar de Imagen con EllipseGeometries, y estaba trabajando mucho más rápido (~ 0.5s), pero no lo suficiente. ¿Cómo acelerarlo?

Saludos, Oleg EREMEEV

P. S. Lo siento por mi ingles.

+6

No hay necesidad de disculparse por su inglés. –

+0

¿Ha intentado utilizar WPF Performance Suit para descubrir qué le lleva la mayor parte del tiempo? – levanovd

+0

Gracias, levanovd, pero sé que mi código es incorrecto, es suficiente. Estoy preguntando acerca de un enfoque muy diferente. –

Respuesta

4

Salí de mi método de representación de edad, pero la creación de nuevos EllipseGeometry objeto cada vez era mala idea, por lo que optimiza de esta manera:

for (int x = 0; x < newWidth; ++x) 
{ 
    for (int y = 0; y < newHeight; ++y) 
    { 
     States[x, y] = null; 
     OnEllipses[x, y] = new EllipseGeometry(new Rect((double)x * EDGE + 0.5f, (double)y * EDGE + 0.5f, EDGE - 1f, EDGE - 1f)); 
     OffEllipses[x, y] = new EllipseGeometry(new Rect((double)x * EDGE + 0.5f, (double)y * EDGE + 0.5f, EDGE - 1f, EDGE - 1f)); 
     DisabledEllipses[x, y] = new EllipseGeometry(new Rect((double)x * EDGE + 0.5f, (double)y * EDGE + 0.5f, EDGE - 1f, EDGE - 1f)); 
    } 
} 

// . . . 

DrawingGroup tmpDrawing = new DrawingGroup(); 
GeometryGroup onGroup = new GeometryGroup(); 
GeometryGroup offGroup = new GeometryGroup(); 
GeometryGroup disabledGroup = new GeometryGroup(); 

for (int x = 0; x < DisplayWidth; ++x) 
{ 
    for (int y = 0; y < DisplayHeight; ++y) 
    { 
     if (States[x, y] == true) onGroup.Children.Add(OnEllipses[x, y]); 
     else if (States[x, y] == false) offGroup.Children.Add(OffEllipses[x, y]); 
     else disabledGroup.Children.Add(DisabledEllipses[x, y]); 
    } 
} 

tmpDrawing.Children.Add(new GeometryDrawing(OnBrush, null, onGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(OffBrush, null, offGroup)); 
tmpDrawing.Children.Add(new GeometryDrawing(DisabledBrush, null, disabledGroup)); 
DisplayImage.Source = new DrawingImage(tmpDrawing); 

Para x = 128 ey = 8 funciona muy rápido, incluso en sistemas Pentium III.

1

Incluso si llego un poco tarde: This publicado por Charles Petzold ayudó mucho en un escenario similar.

+0

Gracias por responder, puedo usarlo en otro proyecto en el futuro. Mi verdadera solución funciona bien, así que creo que la dejo tal como está. –

Cuestiones relacionadas