【问题标题】:GDI objects leaks using Direct 2D GdiInteropRenderTarget使用 Direct2d Gdi 互操作渲染目标的 GDI 对象泄漏
【发布时间】:2012-10-15 19:08:50
【问题描述】:

我正在尝试在兼容的渲染目标上同时使用 Gdi 和 Direct 2D 渲染位图。 我使用 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE 选项创建兼容目标,然后执行以下操作:

HDC hdc=NULL;
ID2D1GdiInteropRenderTarget *gdiTarget=NULL;
target->QueryInterface(__uuidof(ID2D1GdiInteropRenderTarget), (void**)&gdiTarget);
target.BeginDraw();
HRESULT hr=gdiTarget->GetDC(D2D1_DC_INITIALIZE_MODE_CLEAR, &hdc);
if(SUCCEEDED(hr))
{
    /* Gdi drawing code(hdc)*/

gdiTarget->ReleaseDC(NULL);
}
/* Direct2D drawing code
target->EndDraw();
gdiTarget->Release();

但似乎出了点问题,因为每次我调用此渲染方法时,都会出现许多 GDI 对象泄漏。我也尝试这样做:

HDC hdc=NULL;
ID2D1GdiInteropRenderTarget *gdiTarget=NULL;
target->QueryInterface(__uuidof(ID2D1GdiInteropRenderTarget), (void**)&gdiTarget);
target.BeginDraw();
HRESULT hr=gdiTarget->GetDC(D2D1_DC_INITIALIZE_MODE_CLEAR, &hdc);
if(SUCCEEDED(hr))
gdiTarget->ReleaseDC(NULL);
target->EndDraw();
gdiTarget->Release();

我也有泄漏。 我也尝试在由 ID2D1GdiInteropRenderTarget 创建的 HDC 上使用 DeleteDC() 或 ReleaseDC() 但没有成功。

有什么建议吗? 提前致谢!

【问题讨论】:

    标签: interop gdi memory-leaks direct2d


    【解决方案1】:

    如果渲染目标使用加速,那么结果将不会非常高效。您应该强烈考虑在 D2D 中进行本机渲染。 原因是您会产生从 GPU 转移到系统的成本。我已经将很多绘图代码移植到本机 D2D。有一些 api 您可能需要 GDI(xor 等),但通常即使是那些也应该尝试另一种方法。

    我不确定您为什么会出现泄漏,但您希望遵循此处的指南: http://msdn.microsoft.com/en-us/library/windows/desktop/dd370971(v=vs.85).aspx

    我不推荐使用 dc 渲染目标,它比使用 GDI+ 慢。 如果需要几次调用,请使用概述的第二种方法。
    此外,您还需要处理可能在 D2D 中生效的任何剪辑/图层。

    最后,您需要调用 EndDraw 之前释放 GDI 接口。

    【讨论】:

      【解决方案2】:

      我发现了问题。它是一个未释放的 d2dBitmap,有时会导致内存泄漏,当我尝试释放 ID2D1GdiInteropRenderTarget 时,它会导致 Gdi 对象泄漏。

      HDC hdc=NULL;
      ID2D1GdiInteropRenderTarget *gdiTarget=NULL;
      compatibleTarget->QueryInterface(__uuidof(ID2D1GdiInteropRenderTarget),(void**)&gdiTarget);
      compatibleTarget.BeginDraw();
      HRESULT hr=gdiTarget->GetDC(D2D1_DC_INITIALIZE_MODE_CLEAR, &hdc);
      if(SUCCEEDED(hr))
      {
          /* Gdi drawing code(hdc)*/
      
      gdiTarget->ReleaseDC(NULL);
      }
      /* Direct2D drawing code
      compatibleTarget->EndDraw();
      gdiTarget->Release();
      ID2D1Bitmap *bitmap=NULL;
      compatibleTarget->GetBitmap(&bitmap);
      target->BeginDraw();
      target->DrawBitmap(bitmap);
      target->EndDraw();
      compatibleTarget->Release();    // I thought this only enough
      bitmap->Release();              // This solved the problem
      

      我仍然对哪种类型的目标更适合使用(DC 或 Hwnd)有点困惑,因为我发现不同的性能取决于我是否使用 Gpu。 特别是我发现了以下问题:

      • 如果我使用 DCRenderTarget 我不能使用硬件加速(或默认),因为我继续违反内存的受保护区域。如果我使用 HwndRenderTarget,则不会发生这种情况。
      • 如果我使用 HwndRenderTarget,通常一切都很好,但我失去了对窗口的关注,它无法识别 KeyPressed 消息,而且,如果我使用 Gpu,性能下降很多,并且很大程度上取决于活动目标(如果我使用软件加速则不会发生这种情况)。

      有没有人遇到过同样的问题? 你能推荐一些关于它的东西吗?

      【讨论】:

        猜你喜欢
        • 2021-06-20
        • 2012-01-08
        • 2012-05-15
        • 2011-06-04
        • 2015-10-06
        • 2014-02-10
        • 2013-06-10
        • 2010-10-03
        • 2012-10-28
        相关资源
        最近更新 更多