C++ CreateCompatibleBitmap 和 CreateDIBSection(内存 DC)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7502588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CreateCompatibleBitmap and CreateDIBSection (Memory DC's)
提问by demorge
from what I've read hereit seems that most of the Windows GDI functions are accelerated. So for instance a call to BitBltor AlphaBlenduses hardware acceleration if available. It also mentions that the contents of a window are kept only in video memory. Now this is all good and true for a window DC, but how can I use a memory DCthat resides in video card memory? And once we've accomplished that how to obtain direct access to the pixels, I think that would involve 1. temporary copying the data to system memory 2. alter the pixel data 3. copy back to video memory.
从我在这里读到的内容看来,大多数 Windows GDI 功能都得到了加速。因此,例如调用BitBlt或AlphaBlend使用硬件加速(如果可用)。它还提到窗口的内容仅保存在视频内存中。现在这对于窗口 DC来说都是好的和正确的,但是我如何使用驻留在视频卡内存中的内存 DC?一旦我们完成了如何获得对像素的直接访问,我认为这将涉及 1. 临时将数据复制到系统内存 2. 更改像素数据 3. 复制回视频内存。
I've tried two approaches, both allocate system memory as I can see in the task manager...
我尝试了两种方法,都分配系统内存,正如我在任务管理器中看到的那样......
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);and then call to obtain the bits
GetBitmapBits(...)according to various comments this should indeed create the compatible bitmap in video memory, but why can I still see an increase in system memory (even when I don't call
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);in this case we receive the pointer to the bits immediately (
m_pBits) so it's obvious that these reside in system memory...
创建兼容位图
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)?创建DIB节
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),因此很明显这些位驻留在系统内存中...
Or is it a copy that is kept in system memory for both methods? But if I change the bits in system memory a call to BitBltwould still have to check/copy from system memory again... not very optimized IMHO.
还是两种方法都保存在系统内存中的副本?但是,如果我更改系统内存中的位,则调用BitBlt仍然必须再次从系统内存中检查/复制......不是非常优化恕我直言。
EDIT: I've also tried creating memory DC's by using the BeginBufferedPaintand GetBufferedPaintBits. It allocates system memory as well, so in that respect I suppose it's just a wrapper for the above methods but caches the DC's so a next call doesn't necessarily has to recreate a memory DC. See Raymond Chen's article.
编辑:我也尝试过使用BeginBufferedPaintand来创建内存 DC GetBufferedPaintBits。它也分配系统内存,因此在这方面我认为它只是上述方法的包装器,但缓存了 DC,因此下一次调用不一定要重新创建内存 DC。参见 Raymond Chen 的文章。
EDIT #2: I guess the actual question is: Am I doing the memory DC creation correct in method 1 or 2 to get hardware accelerated GDI operations?To me it all seems fast, and both methods provide the same speed too, so there's not really a way to check it...
编辑#2:我想实际的问题是:我是否在方法 1 或 2 中正确地进行内存 DC 创建以获得硬件加速的 GDI 操作?对我来说,这一切似乎都很快,而且两种方法也提供相同的速度,所以没有真正的方法来检查它......
采纳答案by MSN
Memory DCs are not created on a device. They are designed to put GDI output into memory.
内存 DC 不在设备上创建。它们旨在将 GDI 输出放入内存。
From Memory Device Contextson MSDN:
来自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.
要使应用程序能够将输出放在内存中而不是将其发送到实际设备,请使用称为内存设备上下文的特殊设备上下文进行位图操作。内存 DC 使系统能够将一部分内存视为虚拟设备。
If you want hardware accelerated 2d graphics, you should consider using Direct2D.
如果你想要硬件加速的 2d 图形,你应该考虑使用Direct2D。

