Ich entwickle eine Dotnet 4.0-Anwendung auf Win7, die Mapping durchführen muss. Als Mapping-Anwendung gibt es Mistladungen von hochauflösenden Antialiasing-Polygonen aus. Es unterstützt derzeit zwei Arten von Rendering-Ausgabe, GDI + und Direct2D.Warum ist meine Direct2D Zeichnungsleistung so schrecklich?
Ich bin besorgt, weil die GDI + -Ausgabe um einen Faktor 3 schneller ist als die Direct2D.
Beide Renderer verwenden AA. Ich weiß, dass ich es in Direct2D abschalten kann, was den Durchsatz etwas verbessert (bis zu einem Faktor 2 schlechter als GDI +). Aber das ist keine Lösung, denn ich kann AA auch in GDI + ausschalten und dort noch bessere Leistung erzielen. Für diesen Benchmark ist mein Rendering-Code trivial. Ich hoffe, ich habe einen schrecklichen Fehler gemacht, dass jemand auf mich hinweisen kann, der die Situation verbessern wird.
_renderTarget.BeginDraw();
// Paint background.
RectF rf = new RectF(0.0f, 0.0f, renderTargetSize.Width, renderTargetSize.Height);
_renderTarget.FillRectangle(rf, _backgroundBrush);
// Draw polygons
foreach (GisTypes.Polygon polygon in _polygons)
{
using (PathGeometry path = _factory.CreatePathGeometry())
{
using (GeometrySink sink = path.Open())
{
sink.SetFillMode(Microsoft.WindowsAPICodePack.DirectX.Direct2D1
.FillMode.Alternate);
Point2F[] points = Array.ConvertAll(polygon.Points,
x => new Point2F((float)x.X, (float)x.Y));
sink.BeginFigure(points[0], FigureBegin.Filled);
for (int i = 1; i < points.Length; ++i)
{
sink.AddLine(points[i]);
}
sink.EndFigure(FigureEnd.Closed);
sink.Close();
}
using (TransformedGeometry transformedPath = _factory.CreateTransformedGeometry(
path, WorldToPage))
{
_renderTarget.FillGeometry(transformedPath, _fillBrush);
_renderTarget.DrawGeometry(transformedPath, _borderBrush, 1.0f);
}
}
}
_renderTarget.EndDraw();
In diesem Beispielcode verwende ich einen Pfad und eine Zahl pro Polygon. Der Grund dafür ist, dass es die Implementierung von GDI + genauer widerspiegelt und in der tatsächlichen Anwendung anstelle des Beispielcodes das Rendern der ausgewählten Polyons vereinfacht. Ich weiß, dass ich einen einzigen Pfad und mehrere Zahlen verwenden kann, und ich habe es auf diese Weise versucht, es ist marginal schneller, aber nicht genug, um eine Auswirkung auf das allgemeine Problem zu haben.
Ich verwende auch eine TransformedGeometry, anstatt die Transformation auf das RenderTarget zu setzen. Der Grund dafür ist, dass, obwohl ich möchte, dass die Geometrie transformiert wird, ich nicht möchte, dass der Umriss transformiert wird, weil der Skalierungsfaktor dazu führen würde, dass er vollständig verschwindet.
In den bestimmten Beispieldaten, die ich verwende, gibt es nur ein paar hundert Polygone, aber jedes Polygon kann mehrere tausend Punkte haben, also glaube ich nicht, dass die Zuweisung von mehreren PathGeometry und TransformedGeometry während des Renderings das Problem ist , (da es nicht viele von ihnen gibt, und ich habe es bereits mit nur einer PathGeometry und TransformedGeometry versucht und der Unterschied war marginal).
Ich fragte mich, ob ich nicht zu einem Offscreen RenderTarget Rendern und das Ergebnis auf dem Bildschirm RenderTarget blitzen sollte, aber ich habe den MSDN-Artikel zur Verbesserung der Direct2D-Leistung gelesen und es nicht als eine Optimierung erwähnt.
Wer hat irgendwelche Ideen?
Sie sollten nur zeichnen, was in Sicht ist. Wenn Sie Geometrien filtern, die zuerst angezeigt werden und dann nur diese anzeigen, können Sie den Code nicht ermitteln. – CodeAngry
Alles ist in Sicht sowohl für D2D als auch für GDI + und jede weitere Optimierung, die ich vornehmen könnte, könnte gleichermaßen auf D2D und GDI + angewendet werden, was nicht erklären würde, warum die D2D-Leistung im Vergleich zu GDI + so schlecht ist. – Neutrino
Ich bin am selben Punkt (Ich füge Unterstützung für das Rendern mit Direct2D hinzu) und ich glaube, dass Offscreen-Rendering helfen sollte (ich denke, dass es in diesem Thema nicht erwähnt wird, weil sie dynamische Szene statt statisch annehmen). Ist es Ihnen gelungen, dieses Problem irgendwie zu lösen? – Victoria