WM_PAINT 返回 0 导致 cpu 使用率 2%
Posted
技术标签:
【中文标题】WM_PAINT 返回 0 导致 cpu 使用率 2%【英文标题】:WM_PAINT return 0 causing cpu usage 2% 【发布时间】:2018-03-10 12:33:09 【问题描述】:我的 WM_Paint 有问题
如果我让它返回 0/1,即使程序被最小化,我的 cpu 也会保持在 1% 左右。
我的绘图窗口正在使用 OpenGL
如果我从 WM_PAINT 中断,它会在调整大小时导致绘图问题
case WM_PAINT:
application->paint_window();
return 0;
window = std::make_unique<platform::window>(
L"Main window",
CW_USEDEFAULT, CW_USEDEFAULT,
1200, 600,
WS_OVERLAPPEDWINDOW /*| WS_CLIPSIBLINGS | WS_CLIPCHILDREN*/, 0,
CS_OWNDC,
this, process_message
);
while (::GetMessage(&msg, 0, 0, 0) > 0)
if (!::TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
::TranslateMessage(&msg);
::DispatchMessage(&msg);
编辑: 如果我在 WM_PAINT 中删除我的函数调用,我的 cpu 会上升到 15%。 如果我什么都不做,为什么它会这么高。
【问题讨论】:
只有 2%?这取决于你制作的程序类型,要么什么都没有,要么很少。 在窗口最小化并且不应该做任何事情时大约 2%,但由于某种原因仍然收到 WM_PAINT 消息 有一个非常简单的解决方案:当窗口最小化时不要绘画:)。在您的WM_PAINT
处理程序中,检查窗口是否已最小化,在这种情况下不要绘制。
如果您没有在 WM_PAINT 事件处理程序中调用 Begin/EndPaint(),那么操作系统会认为窗口没有被绘制。所以它再次生成 WM_PAINT。您的 UI 线程将燃烧 100% 核心。所以在 6 核的机器上看到 15% 是正常的。如何调用你的函数可以降低它并不明显,但它可能做正确的事情。如果您不知道为什么您的程序需要太多 cpu,请使用分析器。顺便说一句。
听起来您在paint_window()
中有一个阻塞调用,等待GPU 完成渲染,从而限制了您调用GetMessage
的频率,最终限制了WM_PAINT
的调用频率消息到达。不过,如果没有看到该代码,这只是猜测。
【参考方案1】:
如the WM_PAINT message 中所述:
当窗口的更改改变了客户区的内容时,系统会将此消息发送到窗口过程。
系统保留一个内部更新区域来确定窗口的任何部分是否需要绘制。应用程序负责验证它已绘制到的区域(通过调用 BeginPaint、ValidateRect 或 ValidateRgn)。
未能验证不再需要更新的区域将使系统重新生成WM_PAINT
消息。这会导致您观察到的资源消耗。
【讨论】:
即使我在 opengl 上下文中绘图? @ciyaso:窗口子系统不知道您的 OpenGL 上下文。它将保持自己的无效区域概念,这可能与您的 OpenGL 上下文无关。如果您不希望窗口子系统继续生成WM_PAINT
消息,则必须遵守其规则,并验证无效区域。
@ciyaso:不过这很常见。使用窗口子系统进行可见性测试和更新管理,甚至使用 OpenGL 应用程序。您必须将窗口的更新区域转换为 OpenGL 场景,并将其传递给渲染引擎。它仍然需要您然后清除窗口系统看到的无效区域。这完全取决于应用程序的特性,这是否有用。以上是关于WM_PAINT 返回 0 导致 cpu 使用率 2%的主要内容,如果未能解决你的问题,请参考以下文章