2010-03-06 4 views
8

J'ai des problèmes avec les performances de dessin WPF. Il y a beaucoup de petits objets EllipseGeometry (1024 ellipses, par exemple), qui sont ajoutés à trois GeometryGroups distincts avec des pinceaux de premier plan différents. Après, je rends tout cela sur un simple contrôle Image. Code:Performances de dessin WPF avec un grand nombre de géométries

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

Il fonctionne très bien, mais prend trop de temps -> 0.5s sur Core 2 Quad,> 2 s sur Pentium 4. J'ai besoin < 0.1s partout. Toutes les ellipses, comment vous pouvez voir, sont égales. L'arrière-plan du contrôle, où est mon DisplayImage, est solide (noir, par exemple), donc nous pouvons utiliser ce fait. J'ai essayé d'utiliser 1024 éléments Ellipse au lieu de Image avec EllipseGeometries, et cela fonctionnait beaucoup plus vite (~ 0.5s), mais pas assez. Comment l'accélérer?

Cordialement, Oleg Eremeev

post-scriptum Désolé pour mon anglais.

+6

Pas besoin de vous excuser pour votre anglais. –

+0

Avez-vous essayé d'utiliser WPF Performance Suit pour savoir ce qui prend le plus de temps? – levanovd

+0

Merci, levanovd, mais je sais, que mon code est incorrect, c'est assez. Je demande à propos d'approche très différente. –

Répondre

4

J'ai quitté mon ancienne méthode de rendu, mais la création de nouveaux EllipseGeometry objet chaque fois était mauvaise idée, donc j'optimisé de cette façon:

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

Pour x = 128 et y = 8 cela fonctionne très vite, même sur les systèmes Pentium III.

1

Même si je suis un peu en retard: This post de Charles Petzold a beaucoup aidé dans un scénario similaire.

+0

Merci pour la réponse, je peux l'utiliser dans un autre projet à l'avenir. Ma vraie solution fonctionne bien, alors je pense que je la laisse telle quelle. –