3

互換性のあるレンダリングターゲットでGdiとDirect2Dの両方を使用してビットマップをレンダリングしようとしています。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()も試してみましたが、成功しません。

なにか提案を?前もって感謝します!

4

2 に答える 2

2

レンダリングターゲットがアクセラレーションを使用している場合、結果はあまりパフォーマンスが高くなりません。D2Dでネイティブにレンダリングすることを強く検討する必要があります。その理由は、GPUからシステムへの転送にコストがかかるためです。多くの描画コードをネイティブD2Dに移植しました。GDI(xorなど)が必要になる可能性のあるAPIがいくつかありますが、通常、それらのAPIでも別のアプローチを試す必要があります。

リークが発生する理由はわかりませんが、次のガイドラインに従う必要があります: http://msdn.microsoft.com/en-us/library/windows/desktop/dd370971( v=vs.85 ).aspx

GDI+を使用するよりも遅いdcレンダーターゲットを使用することはお勧めしません。必要な数回の呼び出しの代わりに、概説されている2番目の方法を使用します。
また、D2Dで有効になっている可能性のあるクリッピング/レイヤーを処理する必要があります。

最後に、 EndDrawを呼び出すにGDIインターフェイスを解放する必要があります。

于 2012-10-25T15:31:22.913 に答える
1

問題が見つかりました。リリースされていない 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

Gpu を使用するかどうかによってパフォーマンスが異なることがわかったため、どちらのタイプのターゲット (DC または Hwnd) を使用するのが適しているかについて、まだ少し混乱しています。特に、次の問題が見つかりました。

  • DCRenderTarget を使用すると、ハードウェア アクセラレーション (またはデフォルト) を使用できません。これは、メモリの保護領域の違反が続いているためです。HwndRenderTarget を使用すると、これは発生しません。
  • HwndRenderTarget を使用すると、通常はすべて問題ありませんが、KeyPressed メッセージを認識しないウィンドウにフォーカスが失われます。また、Gpu を使用すると、パフォーマンスが大幅に低下し、アクティブなターゲットの数に大きく依存します (ソフトウェアアクセラレーションを使用すると発生しません)。

誰かが同じ問題に遭遇しましたか? それについて何かお勧めできますか?

于 2012-11-05T11:06:57.983 に答える