从我读到的here看来,大多数Windows GDI函数都被加速了。因此,例如,调用
BitBlt()
或 AlphaBlend()
使用硬件加速(如果可用)。它还提到窗口的内容仅保存在视频内存中。现在,对于window DC来说这一切都很好,但是我如何使用驻留在显卡内存中的内存DC?一旦我们完成了如何直接访问像素,我认为这将涉及 1. 临时将数据复制到系统内存 2. 更改像素数据 3. 复制回视频内存。
我尝试了两种方法,都分配系统内存,正如我在任务管理器中看到的那样......
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);
然后调用获取bits
GetBitmapBits(...)
根据各种评论,这确实应该在视频内存中创建兼容的位图,但为什么我仍然可以看到系统内存的增加(即使我不调用
GetBitmapBits()
)?
CreateDIBSection()
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 的文章。
编辑#2:我想实际的问题是:我在方法1或2中正确创建内存DC以获得硬件加速GDI操作吗?对我来说这一切似乎都很快,并且两种方法也提供相同的速度,所以没有办法检查它......
内存 DC 不是在设备上创建的。它们旨在将 GDI 输出放入内存中。
来自 MSDN 上的内存设备上下文:
Direct2D使应用程序能够将输出放置在内存中而不是发送 它到实际设备,使用位图的特殊设备上下文 称为“内存设备上下文”的操作。内存 DC 使 系统将一部分内存视为虚拟设备。
如果您想要硬件加速 2D 图形,您应该考虑使用