Note that there are some explanatory texts on larger screens.

plurals
  1. POIs TDirect2DCanvas slow or am I doing something wrong?
    primarykey
    data
    text
    <p>While looking for alternatives to replace GDI, I was trying to test Delphi's 2010 <em>TDirect2DCanvas</em> performance in Windows 7.</p> <p>I tested it by drawing a huge polyline using Direct2D and the result was absurdly slow, even with 500 times less data than the amount I've ran the same test using GDI (and I didn't even use a bitmap as backbuffer in GDI, I just drew to the form canvas directly).</p> <p>So I guess either:<br> <strong>a)</strong> Direct2D is slower than GDI;<br> <strong>b)</strong> TDirect2DCanvas is slow;<br> <strong>c)</strong> I'm doing something wrong<br> and hopefully it's c).</p> <p>The test code I wrote is:</p> <pre><code>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. </code></pre> <p>Also, I'm really willing to draw long polylines in real code, as a system I'm working on need to draw plenty of ~2500 points polylines (at least 10K of them).</p> <h2><strong><em>Updated (2010-11-06)</em></strong></h2> <p>I've found out earlier that Direct2D doesn't seem to like polylines, it draws faster if you use a lot of single lines (2 points polylines).</p> <p>Thanks to <a href="https://stackoverflow.com/questions/4055456/is-tdirect2dcanvas-slow-or-am-i-doing-something-wrong/4108046#4108046">Chris Bensen</a> I found out the slowness was with large polylines <em>while using anti-aliasing</em>. So I disabled anti-aliasing as Chris suggested and performance went from ~6000ms to ~3500ms for drawing 50k lines.</p> <p>Things could still be improved because Direct2D just doesn't handle well polylines <em>while using anti-aliasing</em>. With anti-aliasing disabled it's just the opposite.</p> <p>Now the time for drawing with Direct2D the 50k lines, if I draw the large polyline without anti-aliasing, is ~50ms. Nice, eh!</p> <p>The thing is that <strong>GDI is still faster than Direct2D</strong> if I draw to a bitmap and after it's done I BitBlt the result back to the form, it paints <strong>at ~35ms</strong>, and with the same graphics quality. And, Direct2D also seems to be using a backbuffer already (it just draws when <code>EndDraw()</code> is called).</p> <p><strong>So, can this be improved somehow to make using Direct2D worth speed-wise?</strong></p> <p>Here's the updated code:</p> <pre><code>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; </code></pre> <p>By the way, even if I use <a href="https://stackoverflow.com/questions/4055456/is-tdirect2dcanvas-slow-or-am-i-doing-something-wrong/4108046#4108046">Chris</a>' suggestion of creating the geometry beforehand the speed is about the same speed as GDI, but still not faster.</p> <p>My computer is running Direct3D and OpenGL apps normally and here's dxDiag output: <a href="http://mydxdiag.pastebin.com/mfagLWnZ" rel="nofollow noreferrer">http://mydxdiag.pastebin.com/mfagLWnZ</a></p> <p>I'll be glad if anyone can explain me why is this slowness. Sample code is much appreciated.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload