Quantcast
Channel: Direct2D | codexpert blog
Viewing all articles
Browse latest Browse all 29

MFC Support for Direct2D – Part 3: Multithreading

$
0
0

As shown in previous articles, we can enable MFC Direct2D support for a window by a call of CWnd::EnableD2DSupport.
Example:

int CSlideShowWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    // Enable MFC Direct2D support
    EnableD2DSupport();
    // ...

    return 0;
}

So far so good as long as all windows which use Direct2D are running in the same thread (usually the application main thread). But let’s say we have more than one window with intensive rendering (e.g. some images slide show). In this case we would like to create each window in a separate thread. But this could cause the drawing to freeze or even application to crash. So, what should we do?

Create multi-threaded Direct2D factory

If step into MFC code starting with CWnd::EnableD2DSupport, we can notice the following:

  1. check if Direct2D and DirectWrite (kept in a global object of type _AFX_D2D_STATE) are already created;
  2. if not, call _AFX_D2D_STATE::InitD2D with default parameters D2D1_FACTORY_TYPE_SINGLE_THREADED and DWRITE_FACTORY_TYPE_SHARED.

Now, lets see the comments from D2D1_FACTORY_TYPE enumeration.

typedef enum D2D1_FACTORY_TYPE
{
    //
    // The resulting factory and derived resources may only be invoked serially.
    // Reference counts on resources are interlocked, however, resource and render
    // target state is not protected from multi-threaded access.
    //
    D2D1_FACTORY_TYPE_SINGLE_THREADED = 0,

    //
    // The resulting factory may be invoked from multiple threads. Returned resources
    // use interlocked reference counting and their state is protected.
    //
    D2D1_FACTORY_TYPE_MULTI_THREADED = 1,
    D2D1_FACTORY_TYPE_FORCE_DWORD = 0xffffffff

} D2D1_FACTORY_TYPE;

Also, let’s see what MSDN documentation states:

  • D2D1_FACTORY_TYPE_SINGLE_THREADED
    No synchronization is provided for accessing or writing to the factory or the objects it creates. If the factory or the objects are called from multiple threads, it is up to the application to provide access locking.

  • D2D1_FACTORY_TYPE_MULTI_THREADED
    Direct2D provides synchronization for accessing and writing to the factory and the objects it creates, enabling safe access from multiple threads.

Making the synchronization is not so handy so we have to find a way to create a Direct2D factory that uses multi-threaded model. Fortunately, that’s very easy by a single call of CWinApp::EnableD2DSupport.

BOOL CDemoApp::InitInstance()
{
    // NOTE: Just for testing purpose, comment the below line of code
    //       then open more than one slide-show windows which are running 
    //       in different threads. See what happens.
    VERIFY(EnableD2DSupport(D2D1_FACTORY_TYPE_MULTI_THREADED));
    // ...

    return FALSE;
}

That’s all. Hurray!

Demo application

Download: MFC Direct2D Multithreading Demo.zip (9)

The demo application can create multiple windows that perform image slideshow with Direct2D, each one in its own thread. Just push the button then select a folder containing image files.

MFC Direct2D Multithreading - Demo

MFC Direct2D Multithreading – Demo

 

Resources and related articles


Viewing all articles
Browse latest Browse all 29

Trending Articles