【问题标题】:What are the best practices for multithreading with Direct2D & DXGI (D3D interop)?使用 Direct2D 和 DXGI(D3D 互操作)进行多线程处理的最佳实践是什么?
【发布时间】:2014-01-25 06:32:50
【问题描述】:

理想情况下,我希望有多个工作线程能够渲染到屏幕外渲染目标,然后将渲染的内容“传输”到屏幕上的目标。使用 hwnd 渲染目标,这似乎不是问题(msdn 有一个例子)。

当屏幕渲染目标基于 DXGI 交换链时,我不太确定该怎么做。据我所知,每个窗口只能有一个交换链。因此,我只能有一个基于交换链的渲染目标。这意味着屏幕上的渲染只能通过那个单一的渲染目标来完成。

如果我的上述假设是正确的,那么处理多线程渲染的最佳方法是什么?我需要序列化对屏幕目标的访问吗?工作线程应该共享一个多线程 d2d 工厂吗?如果有适当的锁定机制,屏幕目标的 BeginDraw/EndDraw/Present 是否可以在工作线程(即未创建屏幕目标的线程)上执行?

我将不胜感激任何建议。 谢谢。

【问题讨论】:

    标签: direct2d


    【解决方案1】:

    我现在正在处理同样的问题!根据我在 MSDN 上的阅读,最好的方法是:

    我还没有一个可靠工作的多线程 Direct2D 函数集,即使遵循这个,所以到目前为止我所知道的就是这些 - 我还不知道肯定存在的其他警告等。

    一些有用的关键位:

    您可以创建多线程 Direct2D 工厂实例。您可以使用 并共享一个多线程工厂及其所有资源 不是一个线程,而是访问这些资源(通过 Direct2D 调用) 由 Direct2D 序列化,因此不会发生访问冲突。如果你的应用 仅调用 Direct2D API,此类保护由 Direct2D 以最小的开销实现粒度级别。

    ID2D1Factory* m_D2DFactory;
    
    // Create a Direct2D factory.
    HRESULT hr = D2D1CreateFactory(
        D2D1_FACTORY_TYPE_MULTI_THREADED,
        &m_D2DFactory
    );
    

    还有一个非常重要的警告:

    多线程注意事项

    当您在应用程序中使用 DXGI 时 多线程,你需要小心避免造成死锁, 其中两个不同的线程正在等待对方完成。 有两种情况会发生这种情况。

    • 渲染线程是 不是消息泵线程。
    • 执行 DXGI API 的线程不是 创建窗口的同一线程。

    小心你永远不会 使用时让消息泵线程在渲染线程上等待 全屏交换链。例如,调用 IDXGISwapChain1::Present1(来自渲染线程)可能会导致 渲染线程等待消息泵线程。当模式改变时 发生,如果 Present1 调用 ::SetWindowPos() 这种情况是可能的 或 ::SetWindowStyle() 并且这些方法中的任何一个调用 ::发信息()。在这种情况下,如果消息泵线程有 保护它的临界区或者如果渲染线程被阻塞,那么 两个线程会死锁。

    【讨论】:

      【解决方案2】:

      对于屏幕外渲染目标,您可以创建单独的 D2DFactories 并将其附加到使用 CreateWicBitmapRenderTarget 或 CreateDxgiSurfaceRenderTarget 创建的各个屏幕外渲染目标。在将其传输到屏幕目标时,您必须等待所有线程完成,然后将每个屏幕外 RT 逐个传输到屏幕 RT。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-04
        • 2012-03-22
        • 1970-01-01
        • 1970-01-01
        • 2010-10-01
        • 2020-06-14
        相关资源
        最近更新 更多