从我读到的 here似乎大多数 Windows GDI 功能都被加速了。因此,例如对 BitBlt
或 AlphaBlend
的调用使用硬件加速(如果可用)。它还提到窗口的内容仅保存在视频内存中。现在,对于 window DC 来说这一切都很好,但我如何才能使用驻留在显卡内存中的 memory DC?一旦我们完成了如何获得对像素的直接访问,我认为这将涉及 1. 将数据临时复制到系统内存 2. 更改像素数据 3. 复制回视频内存。
我尝试了两种方法,都可以在任务管理器中看到分配系统内存...
创建兼容位图
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
)?创建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
的调用仍然需要再次从系统内存中检查/复制...恕我直言,不是很优化。
编辑:我还尝试使用 BeginBufferedPaint
和 GetBufferedPaintBits
创建内存 DC。它也分配系统内存,所以在这方面我认为它只是上述方法的包装器,但缓存了 DC,因此下一次调用不一定要重新创建内存 DC。见 Raymond Chen 的 article .
编辑 #2:我想实际的问题是:我是否在方法 1 或 2 中正确创建内存 DC 以获得硬件加速的 GDI 操作? 对我来说,这一切似乎都很快,而且两者都方法也提供相同的速度,所以没有真正的方法来检查它......
最佳答案
内存 DC 不在设备上创建。它们旨在将 GDI 输出放入内存中。
来自 Memory Device Contexts在 MSDN 上:
To enable applications to place output in memory rather than sending it to an actual device, use a special device context for bitmap operations called a memory device context. A memory DC enables the system to treat a portion of memory as a virtual device.
如果您想要硬件加速的 2d 图形,您应该考虑使用 Direct2D .
关于c++ - CreateCompatibleBitmap 和 CreateDIBSection(内存 DC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7502588/