Alexays / Waybar

Highly customizable Wayland bar for Sway and Wlroots based compositors. :v: :tada:
MIT License
6.54k stars 704 forks source link

CPU Usage when battery animation is active #669

Closed muniter closed 9 months ago

muniter commented 4 years ago

When battery animation is active (default battery module), there's quite a constant increased usage of cpu resources. Waybar and Sway both jump to 7% and 9% respectively and stay there. If i remove the battery animation, They both go down to 0.7%!!! So a really big difference!

Waybar Version: v0.9.0 Sway Version: v1.4 Laptop Specs: i5-7200U CPU @ 2.50GHz

apiraino commented 2 years ago

Some notes after investigating this.

Removing the CSS code for the blinking effect reduces the CPU footprint (though not completely):

@keyframes blink {
  to {
    background-color: #ffffff;
    color: black;
  }
}

#battery {
  animation-name: blink;
  animation-duration: 0.5s;
  animation-timing-function: linear;
  /* This will keep the CPU load high */
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

It looks like the responsibility is on the transform CSS3 attribute. There are CSS tricks to neutralize the CPU usage of this attribute but although supported by GTK this attribute is not accepted in a Waybar CSS file. The rotate Waybar attribute seems to be ineffective at neutralizing the CPU usage.

EDIT: updated my code snippet to underline that the issue is specifically the animation-iteration-count property. It is implemented by the CSS engine of the browser, so I think Waybar cannot do much about it? :man_shrugging:

maaarghk commented 9 months ago

@Alexays is there an FPS limiter? I've just noticed the same thing causing my GPU usage to show in nvtop between 60 and 80% whenever the charger icon is pulsing. I've had to disable it, I don't want to be a bigger climate criminal than taylor swift.

apiraino commented 9 months ago

speaking of criminals, I've rectified my previous comment to underline that the culprit is probably the browser implementation of animation-iteration-count when set to infinite.

chntllh commented 9 months ago

@apiraino Thank you for pointing this out.

After going down the rabbit hole yesterday, I found something very interesting, the animation-timing-function: linear;. This function is responsible for updating the animation, when using linear, it causes high cpu usage.

Therefore, we can use steps() MDN Example can be:

animation: generic-animation 1.5s steps(12) infinite;

In the above example, the animation can have only 12 steps in the 1.5 seconds duration, this will reduce the cpu usage for my device.

Kindly check and inform if this reduces cpu usage.

Alexays commented 9 months ago

Ohh interesting @chntllh Can you open a PR to update the base config with this change? :)

chntllh commented 9 months ago

@Alexays yes! It might take some time as I am very new at this. I will add a section in the Styling section about animations. And also, I am currently trying to adjust the animations for my system.

Alexays commented 9 months ago

Fixed with new sample configuration by @chntllh on master!

apiraino commented 8 months ago

@chntllh thanks for investigating, very interesting. I could get around testing only now.

I think the core of the issue are state changes. More state changes -> more rendering work -> more CPU usage. My observation is that this also depend on the duration between state changes. A short duration, even with very few steps of animation will also impact the rendering work. An example taking this to the extreme:

#battery {
    ...
    animation-duration: 0s;
    animation-timing-function: steps(2);
    ....
}

Increasing the value of animation-duration to (example) 10s will visibly reduce CPU work.

I took the liberty of adding this info to the CPU usage paragraph of the Styling wiki. Let me know what you think!

chntllh commented 8 months ago

@apiraino Yes, this aligns with my initial testing. The update on wiki looks good.

Animations seem to be cpu dependent, or to be precise gtk based animations. Are there other ways to implement hardware accelerated animations in gtk?

apiraino commented 8 months ago

@chntllh thanks for the rectifying my wording (I have no great context about CSS voodoo magic :smile: ). And by the way I'm linking here for reference a Stack Overflow answer supporting your suggestion about using steps() to reduce CU usage.

About implementing hardware acceleration to improve perf.: it's tricky but I think with a bit of legwork it can be achieved using the transform: translateZ(0) property. Here is an example generated by the MDN AI assistant (sorry for using ChatGPT but CSS is not my thing!). Feel free to investigate further if you are inclined to do so!

(and apologies to @Alexays for hijacking this issue with unrelated comments, please let us know if we should move the discussion elsewhere)