在寻找替代 GDI 的替代品时,我试图测试 Delphi 的 2010TDirect2D画布Windows 7 中的性能。
我通过使用 Direct2D 绘制一条巨大的折线来测试它,结果速度慢得离谱,即使数据量比我使用 GDI 运行相同测试的数据量少 500 倍(而且我什至没有使用位图作为 GDI 中的后缓冲区,我只是直接在表单画布上绘制)。
所以我猜:
a)Direct2D 比 GDI 慢;
b)TDirect2DCanvas 速度慢;
c)我做错了什么
希望是 c)。
我写的测试代码是:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Direct2D, D2D1;
type
TForm2 = class(TForm)
private
{ Private declarations }
FD2DCanvas: TDirect2DCanvas;
FData: array[0..50000] of TPoint;
public
procedure CreateWnd; override;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses utils;
{$R *.dfm}
procedure TForm2.CreateWnd;
var
i: Integer;
begin
inherited;
FD2DCanvas := TDirect2DCanvas.Create(Handle);
for i := 0 to High(FData) do begin
FData[i].X := Random(Self.ClientWidth div 2);
FData[i].Y := Random(Self.ClientHeight);
end;
end;
procedure TForm2.WMPaint(var Message: TWMPaint);
var
PaintStruct: TPaintStruct;
begin
BeginPaint(Handle, PaintStruct);
try
FD2DCanvas.BeginDraw;
try
FD2DCanvas.Polyline(FData);
finally
FD2DCanvas.EndDraw;
end;
finally
EndPaint(Handle, PaintStruct);
end;
end;
procedure TForm2.WMSize(var Message: TWMSize);
begin
if Assigned(FD2DCanvas) then begin
ID2D1HwndRenderTarget(FD2DCanvas.RenderTarget).Resize(D2D1SizeU(ClientWidth, ClientHeight));
end;
end;
end.
另外,我真的很愿意在实际代码中绘制长折线,因为我正在开发的系统需要绘制大量约 2500 点的折线(至少其中 10K 条)。
更新 (2010-11-06)
我之前发现 Direct2D 似乎不喜欢折线,如果您使用大量单线(2 点折线),它会绘制得更快。
谢谢克里斯·本森 https://stackoverflow.com/questions/4055456/is-tdirect2dcanvas-slow-or-am-i-doing-something-wrong/4108046#4108046我发现速度慢是因为大折线使用抗锯齿时。因此,我按照 Chris 的建议禁用了抗锯齿功能,绘制 50k 条线时,性能从约 6000 毫秒提高到约 3500 毫秒。
事情仍然可以改进,因为 Direct2D 不能很好地处理折线使用抗锯齿时。禁用抗锯齿后,情况正好相反。
现在,如果我在没有抗锯齿的情况下绘制大折线,则使用 Direct2D 绘制 50k 条线的时间约为 50 毫秒。不错,嗯!
事情是这样的GDI 仍然比 Direct2D 更快如果我绘制位图,完成后我将结果 BitBlt 返回到表单,它会绘制at ~35ms,并且具有相同的图形质量。而且,Direct2D 似乎也已经使用了后备缓冲区(它只是在以下情况下绘制)EndDraw()
叫做)。
那么,能否以某种方式对此进行改进,以提高使用 Direct2D 的速度呢?
这是更新后的代码:
type
TArray = array[0..1] of TPoint;
PArray = ^TArray;
procedure TForm2.WMPaint(var Message: TWMPaint);
var
PaintStruct: TPaintStruct;
begin
FD2DCanvas.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
BeginPaint(Handle, PaintStruct);
try
FD2DCanvas.BeginDraw;
try
FD2DCanvas.Pen.Color := clRed;
FD2DCanvas.Polyline(FData);
finally
FD2DCanvas.EndDraw;
end;
finally
EndPaint(Handle, PaintStruct);
end;
end;
顺便说一句,即使我使用Chris https://stackoverflow.com/questions/4055456/is-tdirect2dcanvas-slow-or-am-i-doing-something-wrong/4108046#4108046' 建议预先创建几何体,速度与 GDI 的速度大致相同,但仍然不会更快。
我的计算机正常运行 Direct3D 和 OpenGL 应用程序,这是 dxDiag 输出:http://mydxdiag.pastebin.com/mfagLWnZ http://mydxdiag.pastebin.com/mfagLWnZ
如果有人能向我解释为什么这么慢,我会很高兴。示例代码非常感谢。