MFC Support for Direct2D – Part 8: Lost Render Target

As stated in the Direct2D documentation, the graphics device might become unavailable. If the device is lost, the render target also becomes invalid, along with any device-dependent resources that were associated with the device. That happens infrequently (e.g. if the user removes the display adapter), but once something bad can happen, a good programmer must handle it, except case he/she likes to see happy QA-tester faces. 🙂

Handling render target loss when using raw Direct2D interfaces

Direct2D signals a lost device by returning the error code D2DERR_RECREATE_TARGET from the ID2D1RenderTarget::EndDraw method. This case we have to release the render target and all its associated device-dependent resources (bitmaps, brushes and so on) in order to be further re-created. Here is a simplified example:

In a real program it’s a lot of work to do (discard, then re-create the render target and resources) but fortunately, the programmer’s life becomes much easier if he/she is using MFC.

Handling render target loss when using MFC

MFC does the work for you: if CRenderTarget::EndDraw function returns D2DERR_RECREATE_TARGET, the framework calls CRenderTarget::ReCreate which discards the render target, then re-creates all its associated resources. Additionally, it sends AFX_WM_RECREATED2DRESOURCES registered message. So usually, we have nothing to do in this case. At most we can handle AFX_WM_RECREATED2DRESOURCES, for example, in order to write what happened in the application’s log.

A little CD2DBitmapBrush issue

Doing tests on Direct2D resources re-creation, I have discovered a little issue in CD2DBitmapBrush MFC class. It always re-creates the bitmap brush using D2D1_EXTEND_MODE_CLAMP. Usually, we use a bitmap brush to fill an area by repeating its content (i.e. having D2D1_EXTEND_MODE_WRAP extend mode) so I fix it by overriding CD2DBitmapBrush::ReCreate, as shown below.

Demo project

The demo project is a simple MFC application which uses a Direct2D bitmap brush to fill the window’s background. In case the render target was previously lost and re-created, it also displays a message. Because the render target loss is quite hard to be reproduced, for testing purpose, you can hit the Test/Re-create render target menu item.

Lost Render Target demo

Lost Render Target demo

Download: Lost Render Target Demo (164)

Resources

Leave a Reply