Saturday, 25 January 2014

A unit to enable Direct2D in FireMonkey where possible

A few days ago I posted about FireMonkey's choice of canvas classes, where it would choose to render via GDI+ instead of via Direct2D.  There were two fixes: one (untested and possibly dangerous) enabled hardware rendering on DirectX9-class hardware, but required editing the FireMonkey source; the second (known safe and tested) enables optimised software rendering via WARP when DirectX10 hardware support is not available.  This last isn't as good when you have DX9 hardware, but it doesn't required editing any FireMonkey source and WARP renders surprisingly fast - it's certainly good enough for 2D/HD applications.

This code is now available as a unit you can include in your FireMonkey apps.  It is ifdef-ed so it will only function on Windows when compiled with XE4 and XE5. (Thanks to commenter Skamradt in the original post for suggesting this.) That means you can include and use it when compiling for OSX or Android without having to worry about it not compiling on those platforms, and that it will also only apply for known IDE / RTL versions that require this patch.  I have only briefly tested it on XE4 (where it works) and XE2 (where of course it doesn't, but compiles anyway.)  Suggestions / changes are welcome.

To use it, add the unit to your .dpr file and then add a call to TryUseDirect2D before Application.Initialize, like so:
program Project1;

  Unit1 in 'Unit1.pas' {Form1},
  FMXDirect2DFix in 'FMXDirect2DFix\FMXDirect2DFix.pas';

{$R *.res}

  FMXDirect2DFix.TryUseDirect2D; // <-- The key method

  Application.CreateForm(TForm1, Form1);

The code is currently checked in to the source of my DWS MandelbrotExplorer app - the rest of the code of which is in a halfway state, so no point looking at it right now :)

  • You can find the unit here.
  • It's MPL licensed, so useable in both commercial and open-source software.
  • It makes a big speed difference for FireMonkey apps on my Windows 7, non-DirectX-10-hardware.  It should make a noticeable difference for anyone on a recently patched (with the Platform Update) Vista or 7 without DirectX10 hardware, which includes those running Windows in a virtual machine like Fusion.


  1. Does Delphi XE3 not have the same issues as XE4 and 5 or does it simply not support Direct2D for Firemonkey?

    I do remember there is a Direct2DCanvas for Delphi XE3...

    1. I am not sure about XE3, since I haven't got it installed. Eugene Kryukov, the FMX architect, wrote in a blog post that DirectX1 support (with WARP) was added in XE3.

      From that I would /guess/ XE3 has the same issue.

      You can see what canvas class your app is using by accessing a TCanvas somewhere - eg an OnPaint handler - and examining Canvas.ClassName. If it's a GDI+ canvas on a machine that should be able to use DX, then you probably are experiencing the issue.