【问题标题】:Multithreading in Direct2DDirect2D 中的多线程
【发布时间】:2014-06-05 09:37:55
【问题描述】:

我正在尝试创建一个简单的 D2D 游戏引擎(至少它必须能够在窗口中显示和移动图像),一切顺利,直到我决定切换到多线程版本。我阅读了this MSDN 文章,它建议使用来自多个线程的一个多线程工厂。但是this文章声称拥有多个单线程工厂会更有效(虽然文章描述了服务器端渲染场景,但我的情况原理相同,我错了吗?)。当我尝试使用单线程一工厂的方法时,所有图像都显示和移动,但是闪烁很可怕。在我的 WM_PAINT 处理程序中,我试图做这样的事情:

for (CSingleThreadEngine *pElSingleThreadEngine : m_SingleThreadEngines) //each CSingleThreadEngine instance has its own D2D factory and an image collection
    pElSingleThreadEngine->Draw();

而 pElSingleThreadEngine->Draw() 是这样绘制的:

m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
for (CGameImage *pImage : m_GameImages)
{
    if (FAILED(pImage->Draw()))
        throw runtime_error("An object cannot be drawn");
}
m_pRenderTarget->EndDraw();

我认为这里的错误在于只有一个窗口有多个 ID2D1HwndRenderTarget 实例,因为如果我在单独的窗口中绘制每个线程,它就可以正常工作。但我只想在一个窗口中绘制,我无法避免为此目的使用多个 ID2D1HwndRenderTarget 实例。所以我的问题是:

  1. 创建多线程 Direct2D 应用程序的最佳实践是什么?
  2. 如果我使用的方法是正确的,我做错了什么以及如何解决?

任何帮助将不胜感激。

【问题讨论】:

标签: c++ windows multithreading direct2d


【解决方案1】:

我看不出您为什么对单个窗口使用多个 HWND 渲染目标的原因。您是否尝试过为每个线程创建屏幕外位图并将其绘制到单个 HWND 渲染目标?

【讨论】:

  • 这个想法来得早一点,但有些对象只需要在创建它们的线程中使用它们。所以我现在正在修复错误并重构程序。如果我成功了,我一定会接受你的回答。:)
  • 谢谢,屏幕外位图方法似乎确实有效。)除了当我尝试绘制数千张图像时,我最终得到 E_OUTOFMEMORY HRESULT(尽管还有很多可用的 RAM 剩余)。但是闪烁的问题已经消失了。)
  • 内存和视频内存是有区别的。当您创建一个 direct2d 位图 (Id2d1Bitmap) 时,它会加载到视频 RAM 中,直到您释放接口并释放资源。另一方面,如果您通过 WIC api 加载图像,它会存储在 ram 中。我不知道你的方案是什么。
  • 我目前创建 WIC 位图,然后使用 CreateBitmapFromWicBitmap 获取 ID2D1Bitmap。奇怪的是,如果我得到 E_OUTOFMEMORY 然后再次调用 CreateBitmapFromWicBitmap,它会成功。所以我决定写类似 `while (!m_pD2DBitmap) m_pSingleThreadEngine->m_pRenderTarget->CreateBitmapFromWicBitmap(...);` 我想知道这种行为的确切原因...
  • 不知道是什么原因导致你的内存溢出。您可以使用GPU-Z 之类的软件来监控您分配的内存量,并最终找出它在什么时候被填满。使用后你会公开你的位图吗?
猜你喜欢
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 2018-06-20
  • 1970-01-01
  • 2012-06-01
  • 1970-01-01
  • 2021-11-18
相关资源
最近更新 更多