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 BitBlt
or AlphaBlend
uses 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 BitBlt
would 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 BeginBufferedPaint
and 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.
编辑:我也尝试过使用BeginBufferedPaint
and来创建内存 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。