从我读过的here看来,大多数Windows GDI功能似乎都在加速。例如,对BitBlt
或AlphaBlend
的调用会使用硬件加速(如果可用)。它还提到窗口的内容仅保存在视频内存中。现在这对于窗口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);
然后调用以获取位
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的article。
编辑#2:我想实际的问题是:我是否在方法1或2中正确进行内存DC创建以获得硬件加速的GDI操作?对我来说这一切似乎都很快,而且两者都是方法也提供相同的速度,所以没有办法检查它......
答案 0 :(得分:4)
未在设备上创建内存DC。它们旨在将GDI输出放入内存中。
来自MSDN上的Memory Device Contexts:
使应用程序能够将输出放在内存中而不是发送 它是一个实际的设备,使用特殊的设备上下文来进行位图 操作称为内存设备上下文。内存DC启用 系统将一部分内存视为虚拟设备。
如果您需要硬件加速的2D图形,则应考虑使用Direct2D。