CreateCompatibleBitmap 和 CreateDIBSection(内存 DC)
我尝试了两种方法,都分配系统内存,正如我在任务管理器中看到的那样...
CreateCompatibleBitmap()
HDC hDC = GetDC(NULL); m_hDC = CreateCompatibleDC(hDC); m_hBmp = CreateCompatibleBitmap(hDC, cx, cy); ReleaseDC(NULL, hDC); m_hOldBmp = (HBITMAP)选择对象(m_hDC, m_hBmp);
然后调用获取位
GetBitmapBits(...)
根据各种评论,这确实应该在视频内存中创建兼容的位图,但为什么我仍然可以看到系统内存增加(即使我不调用
GetBitmapBits()
)?< /p>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; // 自顶向下 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)选择对象(m_hDC, m_hBmp);
在这种情况下,我们立即收到指向位的指针(
m_pBits
),因此很明显这些位驻留在系统内存中......
或者它是一个副本两种方法都保存在系统内存中吗?但是,如果我更改系统内存中的位,对 BitBlt() 的调用仍然需要再次从系统内存中检查/复制......恕我直言,这不是非常优化的。
编辑:我还尝试使用 BeginBufferedPaint()
和 GetBufferedPaintBits()
创建内存 DC。它也分配系统内存,因此在这方面,我认为它只是上述方法的包装器,但缓存了 DC,因此下一次调用不一定需要重新创建内存 DC。请参阅 Raymond Chen 的文章。
编辑 #2:我想实际的问题是:我是否在方法 1 或 2 中正确创建了内存 DC,以获得硬件加速的 GDI 操作? 对我来说,这一切似乎都很快,并且两种方法都提供了速度也相同,所以没有办法检查它......
From what I've read here it 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 DC that 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.
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...
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.
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.
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
内存 DC 不是在设备上创建的。它们旨在将 GDI 输出放入内存中。
来自 MSDN 上的内存设备上下文:
如果您想要硬件加速 2d 图形,您应该考虑使用 Direct2D。
Memory DCs are not created on a device. They are designed to put GDI output into memory.
From Memory Device Contexts on MSDN:
If you want hardware accelerated 2d graphics, you should consider using Direct2D.