1. ホーム
  2. c++

[解決済み] CreateCompatibleBitmapおよびCreateDIBSection(メモリDCの場合)

2022-02-09 23:02:15

質問

読んだ限りでは こちら Windows の GDI 関数のほとんどは高速化されているようです。そのため、たとえば BitBlt または AlphaBlend は、ハードウェアアクセラレーションが利用可能な場合に使用します。また、ウィンドウのコンテンツはビデオメモリにのみ保持されることにも言及しています。さて、これはすべて良いことであり ウィンドウDC しかし、どのように メモリDC ビデオカードのメモリに存在するものですか?また、それを達成した後、ピクセルへの直接アクセスを得るには、1.データをシステムメモリに一時的にコピーする 2.ピクセルデータを変更する 3.ビデオメモリにコピーバックする、ということになるかと思います。

2つのアプローチを試しましたが、どちらもタスクマネージャーで確認できるようにシステムメモリを割り当てました...

  1. CreateCompatibleBitmap

    HDC hDC = GetDC(NULL);
    m_hDC = CreateCompatibleDC(hDC);
    m_hBmp = CreateCompatibleBitmap(hDC, cx, cy);
    ReleaseDC(NULL, hDC);
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp);
    
    

    を呼び出し、ビットを取得します。

    GetBitmapBits(...)
    
    

    様々なコメントによると、これは確かにビデオメモリに互換性のあるビットマップを作成するはずですが、なぜ私はまだシステムメモリの増加を見ることができます(私が呼び出さなかった場合であっても GetBitmapBits )?

  2. DIBSectionの作成

    HDC hDC = GetDC(NULL);
    m_hDC = CreateCompatibleDC(hDC);
    
    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = cx;
    bmi.bmiHeader.biHeight = -cy; // top-down
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    m_hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, NULL);
    
    ReleaseDC(NULL, hDC);
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp);
    
    

    この場合、すぐにビットへのポインタを受け取ります ( m_pBits ということは、これらはシステムメモリに存在することは明らかです。

それとも、両方のメソッドでシステムメモリに保持されるのはコピーなのでしょうか?しかし、もし私がシステム・メモリ内のビットを変更したら、そのビットは BitBlt の場合、再びシステムメモリからチェック/コピーする必要があります...あまり最適化されていないIMHO。

EDIT: メモリDCを作るのに BeginBufferedPaintGetBufferedPaintBits . システムメモリも確保するので、その点では上記のメソッドのラッパーに過ぎないが、DCをキャッシュしているので、次の呼び出しで必ずしもメモリDCを再作成する必要はないだろう。Raymond Chen の 記事 .

EDIT #2:実際の問題は、そうなんでしょうね。 ハードウェアアクセラレーションによるGDI操作を得るために、私は方法1または2でメモリDCの作成を正しく行っていますか? 私にはすべて高速に見えますし、どちらの方法でも同じ速度が得られるので、それを確認する方法がないのです......。

解決方法は?

メモリDCはデバイス上に作成されるものではありません。GDI出力をメモリに格納するためのものです。

から メモリデバイスコンテキスト をMSDNで公開しています。

アプリケーションで出力をメモリ上に配置するには 実際のデバイスに転送するには、ビットマップ用の特別なデバイスコンテキストを使用します。 という操作を行うことができます。 メモリデバイスコンテキスト . メモリDCは システムは、メモリの一部を仮想デバイスとして扱えるようにします。

ハードウェアアクセラレーションによる2Dグラフィックスが必要な場合は Direct2D .