The WinWindowOcclusionCalc thread uses a visible amount of CPU time
Categories
(Core :: Widget: Win32, defect, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox-esr91 | --- | unaffected |
firefox94 | --- | unaffected |
firefox95 | --- | unaffected |
firefox96 | --- | disabled |
firefox97 | --- | disabled |
firefox98 | --- | wontfix |
firefox99 | --- | wontfix |
firefox100 | --- | wontfix |
People
(Reporter: florian, Unassigned)
References
(Blocks 2 open bugs, Regression)
Details
(Keywords: power, regression, Whiteboard: [win:power])
When looking at the parent process in about:processes, I see the WinWindowOcclusionCalc thread using about 1% of a CPU core when moving the mouse around above the Firefox window, and about 2% of a CPU core when moving another window.
Here is a profile of it: https://share.firefox.dev/3FF41SL
Updated•3 years ago
|
Updated•3 years ago
|
Comment 1•3 years ago
|
||
Set release status flags based on info from the regressing bug 1732736
Comment 2•3 years ago
•
|
||
mouse move and moving another window cause EVENT_OBJECT_LOCATIONCHANGE event. When event is for mouse move, event handling is ended soon.
event is for moving another window, EVENT_OBJECT_LOCATIONCHANGE triggers ScheduleOcclusionCalculationIfNeeded() and then ComputeNativeWindowOcclusionStatus().
EVENT_OBJECT_LOCATIONCHANGE is requested to a process that has occluding windows
- https://searchfox.org/mozilla-central/rev/65d4d3399afa79c8de5a0cc11752d2ba7c31edc1/widget/windows/WinWindowOcclusionTracker.cpp#1023
- https://searchfox.org/mozilla-central/rev/65d4d3399afa79c8de5a0cc11752d2ba7c31edc1/widget/windows/WinWindowOcclusionTracker.cpp#1060
- https://searchfox.org/mozilla-central/rev/65d4d3399afa79c8de5a0cc11752d2ba7c31edc1/widget/windows/WinWindowOcclusionTracker.cpp#1097
Its implementation is same to chromium.
- https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/native_window_occlusion_tracker_win.cc;l=671
- https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/native_window_occlusion_tracker_win.cc;l=711
- https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/native_window_occlusion_tracker_win.cc;l=745
Reporter | ||
Comment 3•3 years ago
|
||
Thanks. From your comment and what I could see in the profile, it seems the CPU time is not used by our code reacting to the events, but rather by the overhead of the operating system sending us these events. In the profile, most of the time is spent in NtUserGetQueueStatus
, PeekMessageW
, NtUserKillTimer
.
So questions about ways to potentially reduce this overhead:
- is there another thread where we are already receiving these events that could be used to get these events and forward only the interesting ones to the WinWindowOcclusionCalc thread?
- my understanding is that detecting window occlusion is meant to save power by avoiding graphics operations in windows that are guaranteed to be invisible. Could we run the occlusion detection code only when we would otherwise be doing expensive graphics operations? Maybe that would mean when vsync is enabled.
Updated•3 years ago
|
Updated•3 years ago
|
Comment 4•3 years ago
|
||
The severity field is not set for this bug.
:jimm, could you have a look please?
For more information, please visit auto_nag documentation.
Updated•3 years ago
|
Comment 5•3 years ago
|
||
NI for comment 3 that was probably unset by accident.
Updated•3 years ago
|
Comment 6•3 years ago
|
||
Sotaro, should this bug block shipping occlusion culling? Do we know if Chrome has the same overhead?
Updated•3 years ago
|
Comment 7•3 years ago
•
|
||
(In reply to Jeff Muizelaar [:jrmuizel] from comment #6)
Sotaro, should this bug block shipping occlusion culling? Do we know if Chrome has the same overhead?
From source code, chrome also should have same overhead. Then this bug does not block shipping, I think.
- Firefox WindowOcclusionTracker
- chromium WindowOcclusionTracker
Comment 8•3 years ago
•
|
||
In current implementation, global event hook is unregistered when all Firefox windows are minimized.
One thing we can do for reducing power usage is adding more situations that global event hook is unregistered.
Updated•3 years ago
|
Reporter | ||
Comment 9•3 years ago
|
||
Following Jeff's suggestion, I captured etw profiles of both Firefox and Chrome. In both cases I had the browser window on the left half of the screen, and the Windows Task Manager on the right half of the screen. I moved the mouse above the Task Manager window during the profile.
Both browsers used non-0 CPU while the mouse was moving above the other window, unless all their windows were minimized. So it's quite possible that we perform similar to Chrome here, but I still think we can and should do better.
Firefox profile: https://share.firefox.dev/3IJKRN1
Chrome profile: https://share.firefox.dev/3g2Ogub (no idea of which thread is relevant)
Sotaro, following what you suggested in comment 8 and my question in comment 3, could we unregister the global event hook when vsync is not enabled?
Comment 10•3 years ago
|
||
Thanks for getting the profiles Florian. One thing I noticed is that Chrome seems to have a more efficient event loop for this thread.
In Chrome it's basically just calling RealMsgWaitForMultipleObjectsEx
and PeekMessageW
where as in Firefox we have calls to KillTimer and GetQueueStatus. These functions account for about 26% of the time on this thread: https://share.firefox.dev/3Gd8trE
Sotaro, is it possible to use a simpler event loop for this thread?
It seems like that, and unregistering when vsync is not enabled should go a decent way in moving this overhead to below the noise threshold.
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Updated•8 months ago
|
Description
•