Direct2D在主窗口中呈现,但不在子窗口中呈现

时间:2014-01-06 04:25:34

标签: debugging winapi direct2d

我正在学习如何使用Direct2D和DirectWrite。我编写了一个示例应用程序,它使用这些库直接在主(顶级)窗口中呈现内容。它工作正常。

现在我正在尝试在另一个应用程序中重写子窗口的绘制代码。原始代码使用GDI并且工作正常。但当我将其转换为使用Direct2D时,根本没有任何内容(子窗口显示为黑色)。

我已将绘画代码简化为客户区的简单填充。

LRESULT PlotWnd::OnPaint(UINT, WPARAM, LPARAM, BOOL &) {
    ATL::CComPtr<ID2D1Factory> pD2DFactory;
    HRESULT hr = ::D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
    assert(SUCCEEDED(hr));
    ATL::CComPtr<ID2D1HwndRenderTarget> pRT;
    RECT rc;
    GetClientRect(&rc);
    D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
    hr = pD2DFactory->CreateHwndRenderTarget(
        D2D1::RenderTargetProperties(/* D2D1_RENDER_TARGET_TYPE_SOFTWARE */),
        D2D1::HwndRenderTargetProperties(m_hWnd, size), &pRT);
    assert(SUCCEEDED(hr));

    pRT->BeginDraw();
    pRT->Clear(D2D1::ColorF(D2D1::ColorF::Beige));
    hr = pRT->EndDraw();
    assert(SUCCEEDED(hr));
    ValidateRect(nullptr);

    return 0;
}

所有Direct2D调用都以S_OK成功,所以我对在哪里寻找问题感到茫然。在这一点上,我在工作实验和这个程序之间可以看到的唯一显着差异是,在这一个中,我只在一个子窗口中使用Direct2D。

所以我的问题是:在子窗口中使用Direct2D时是否存在我遗漏的问题?有关进一步调试的提示吗?

更新:我已删除静态以避免混淆。我正在使用每种颜料完全设置并拆除Direct2D。只有一个油漆调用,具有实际大小。

如果我切换到软件渲染(在渲染目标属性中使用D2D1_RENDER_TARGET_TYPE_SOFTWARE),问题就会消失 - 我按预期得到米色填充。

这让我怀疑我的图形驱动程序已经过时了。但我现在已经更新了我的图形驱动程序,它仍然以同样的方式失败。当软件渲染按预期工作时,还有什么可能导致硬件渲染失败?

更新2 :我仍在尝试重现这是一个小型,自包含的示例。与此同时,我注意到只需启动Spy ++就会有时导致窗口实际渲染到屏幕上(一次)。

3 个答案:

答案 0 :(得分:2)

嗯,对于初学者,你应该在应用程序启动时创建工厂,并使用窗口(HWND)创建渲染目标。这些不应该是“临时”对象,只有在您的OnPaint(WM_PAINT)正在执行时才会存在。

答案 1 :(得分:0)

除了Rick建议将HWNDRenderTarget转换为永久对象之外,我建议调用BeginPaint() - EndPaint()(或者创建一个自动执行的CPaintDC对象),即使你没有不要使用PAINTSTRUCT。请参阅MainWindow::OnPaint here

如果这没有帮助,您可以随时启用Direct2D Debug Layer以获取更多调试信息。

答案 2 :(得分:0)

除了使用软件渲染之外,我还没有其他解决方案。我相当肯定它是一个图形驱动程序错误,特别是竞争条件。

证据:

  • 大约十分之一,它描绘得很好,所以这个问题经常发生,但间歇性,提示时间问题。
  • 问题仅在启动应用程序后第一次绘制时发生。 (是的,那时窗口的大小是正确的。)后来的重绘工作正常。幸运的是,我的应用程序每隔几分钟重新绘制一次窗口,因此在启动它之后它只会保持黑色几分钟。这表明应用程序启动时出现了问题。
  • 我还没能用一个小程序重现,所以问题可能对应用程序初始化所需的时间很敏感。也许驱动程序会进行一些异步初始化,并不总是及时完成处理初始绘制命令。
  • 我尝试过使用不同显卡的其他计算机上没有发生过这种情况。
  • 使用软件渲染时,绘画每次都能完美呈现。这表明该错误不在我的代码中。

反证据:

  • 过去一年的几轮驱动程序更新对行为没有任何影响。

我将此作为&#34;回答&#34;因为其他一些人已经看到类似的症状,并问我是否找到了答案。我仍然愿意阅读其他想法,并会提出好的答案。