【问题标题】:Why does GDI become unresponsive when I draw a large number (~10k) of simple primitives?为什么当我绘制大量(~10k)简单图元时 GDI 变得无响应?
【发布时间】:2016-05-17 02:29:18
【问题描述】:

我有一个具有经典 Doc/View 架构的 MFC 应用程序。作为性能测试,我实现了非常简单的绘制过程,绘制弧并将这些弧存储在该应用程序的文档中。

struct CArc
{
    CRect rectClient;
};

问题是,一旦我达到 10k 个这些非常简单的原语,程序就会变得无响应。这对于 GDI 和这么多的原语是正常的还是我做错了什么?

void CUndo_RedoView::OnDraw(CDC* pDC)
{
    pDoc_ = GetDocument();
    ASSERT_VALID(pDoc_);
    if (!pDoc_)
        return;
    for (const auto& x : pDoc_->arcs_)//arcs_ is a vector<CArc>
    {
        pDC->Arc(x.rectClient,
            CPoint(x.rectClient.right, x.rectClient.CenterPoint().y),
            CPoint(x.rectClient.CenterPoint().x, x.rectClient.right));
    }
    // TODO: add draw code for native data here

}

【问题讨论】:

  • 是的,每次重绘视图时,您都尝试绘制 10,000 条弧线。由于重绘经常发生,每次做这么多的工作很可能会导致减速。您可能会考虑双缓冲,这涉及将对象绘制到屏幕外位图,然后在您的 OnDraw 事件中简单地将屏幕外位图传输到屏幕。
  • 我在您发布的代码中看不到任何错误或资源泄漏。该应用程序有 10,000 个 GDI 限制,但在此代码中您没有创建单个 GDI 对象。
  • @CodyGray 嗨,谢谢伙计,我相信这是我需要做的。我会让你知道它是怎么回事!最好的问候!
  • 如果你提前知道要打多少个电话,或许可以使用msdn.microsoft.com/en-us/library/windows/desktop/…"SetGdiBatchLimit"来加快绘图速度。

标签: c++ winapi mfc gdi


【解决方案1】:

GDI 很慢。

首选方法是使用内存中的 DC,例如 MFC 的 CMemDC (https://msdn.microsoft.com/en-us/library/cc308997(v=vs.90).aspx),仅在实际修改图像时才渲染图像,然后在下一次 OnPaint 调用中 BitBlt 缓存图像

如果您仍然遇到性能问题,请考虑使用 GDI+ 或 DirectX

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 2021-07-28
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多