It is currently August 20th, 2019, 7:47 pm

Shadow quite cpu-intensive under certain circumstances

Get help with installing and using Rainmeter.
User avatar
ikarus1969
Posts: 334
Joined: February 28th, 2011, 3:20 pm
Location: Vienna, Austria

Shadow quite cpu-intensive under certain circumstances

ikarus1969 » July 13th, 2016, 6:14 pm

Hi again!

i guess the new feature "InlineSetting=Shadow..." can be quite cpu-intensive.

After replacing "StringEffect=Border" with the new "InlineSetting=Shadow..." in some of my larger skins (=many string-meters with "Shadow") i noticed a quite large cpu-usage.
I won't expect anyone reading such a large skin written by someone else, so i tried to create a small skin where this high cpu-usage can be reproduced.

Below is a skin with just string meters which have all the same style with InlineSetting=Shadow...".
The more String-meters are there and the larger the font-size the higher the cpu-usage.
Having all the 24 string-meters active i can notice a very high cpu-usage the higher i set the font-size. Setting the size from 24 to 60 results in a cpu-usage from around 15% up to 70%.
If i comment 59 meters and have only 1 single meter left with "Shadow" and size 60 results in only 10% cpu usage.
No "Shadow" setting at all gives me around 3% cpu usage.

My questions are:
  1. does anyone else notice that behavior?
  2. is it recommended to use "Shadow" only with not too much meters with not too high font-sizes?

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
OnWakeAction=[!Refresh]
DynamicWindowSize=1

; Styles
; ------
[Style_Shadow_YN]
InlineSetting=Face | Arial
InlineSetting2=Size | 60
InlineSetting3=Color | 4080C0FF
InlineSetting4=Shadow | 1 | 1 | 1.0 | 002040FF
AntiAlias=1
DynamicVariables=1

[Meter_BG]
Meter=IMAGE
X=#WORKAREAX#
Y=#WORKAREAY#
W=280
H=200
SolidColor=FFFFFFFF
DynamicVariables=1

; ========== ========== ========== ==========
[Meter_1]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #1"
X=[Meter_BG:X]
Y=[Meter_BG:Y]

[Meter_2]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #2"
X=0r
Y=0R

[Meter_3]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #3"
X=0r
Y=0R

[Meter_4]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #4"
X=0r
Y=0R

[Meter_5]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #5"
X=0r
Y=0R

[Meter_6]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #6"
X=0r
Y=0R

[Meter_7]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #7"
X=0r
Y=0R

[Meter_8]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #8"
X=0r
Y=0R

; -----------------------------
[Meter_9]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #9"
X=([Meter_1:X] + [Meter_1:W] + 20)
Y=[Meter_BG:Y]

[Meter_10]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #10"
X=0r
Y=0R

[Meter_11]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #11"
X=0r
Y=0R

[Meter_12]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #12"
X=0r
Y=0R

[Meter_13]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #13"
X=0r
Y=0R

[Meter_14]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #14"
X=0r
Y=0R

[Meter_15]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #15"
X=0r
Y=0R

[Meter_16]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #16"
X=0r
Y=0R

; -----------------------------
[Meter_17]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #17"
X=([Meter_10:X] + [Meter_10:W] + 20)
Y=[Meter_BG:Y]

[Meter_18]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #18"
X=0r
Y=0R

[Meter_19]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #19"
X=0r
Y=0R

[Meter_20]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #20"
X=0r
Y=0R

[Meter_21]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #21"
X=0r
Y=0R

[Meter_22]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #22"
X=0r
Y=0R

[Meter_23]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #23"
X=0r
Y=0R

[Meter_24]
Meter=STRING
MeterStyle=Style_Shadow_YN
Text="Test #24"
X=0r
Y=0R
User avatar
eclectic-tech
Rainmeter Sage
Posts: 3486
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Shadow quite cpu-intensive under certain circumstances

eclectic-tech » July 13th, 2016, 11:09 pm

F.Y.I. I get the same CPU loads.

In your demo skin, I tried eliminating DynamicVariables=1, and set every 9th meter to X=20R and Y=#WorkAreaY#, but that had no effect on the CPU load, still loading CPU ~75% with fontsize @ 60. :-(

I for one seldom use fonts that large, in that many meters, so this may be an unrealistic situation, but still one that deserves attention.
User avatar
jsmorley
Developer
Posts: 19362
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Shadow quite cpu-intensive under certain circumstances

jsmorley » July 13th, 2016, 11:24 pm

We are aware that this functionality can rapidly "add up" to a lot of CPU usage if you use it extensively. We are still looking into what the triggers are, and what can be done to improve it. Hopefully we can soon at least say "don't do this with it" or better yet, "we fixed some stuff".
User avatar
Brian
Developer
Posts: 1889
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: Shadow quite cpu-intensive under certain circumstances

Brian » July 14th, 2016, 3:28 am

There are 5 main things that will increase CPU usage with using inline shadows. I tried to place these in descending order of magnitude, but there will be differences given the amount of inline options and local computer processing power.
  1. Inline coloring. The more inline coloring you use on a string, the more CPU will be used to draw the shadow. This is a product of the method used to draw the shadow in the first place (see below). Inline gradient coloring will increase the CPU even more because of the method of coloring for that particular option.
  2. Number of pattern's found. This should be obvious since the more 'things' you find in the string, the more processing is needed with turning the colors invisible and back to visible (see below). Having a shadow under the entire text will be less CPU intensive than a shadow under 'some' of the text. Results will vary amoung different computers.
  3. Length of string. This should be obvious as well. If you shadow only part of string, the CPU usage will increase because you still need to colorize the rest of the string. So more text, means more coloring.
  4. Size of the font. Normally we aren't going to draw a lot of text on the screen at a large font size, so this wouldn't be the biggest factor in high CPU usage. It will depend on the font, but if the text takes up a large portion of the screen, it will take D2D a little more time to do all the calculations and draw the shadow before drawing the actual text.
  5. Number of meters and skins that use inline shadows. Obviously the more meters, the more CPU usage. Of course, multiple skins using these options will also impact the CPU usage.
So how does inline shadowing work?
Unfortunately there is not an easy way to place a shadow under text with DirectWrite/D2D. Believe it or not, drawing a shadow under the entire text is easier and less CPU intensive than drawing a shadow under only part of a string. So to achieve a shadow effect on only part of a string we have to iterate through the entire string and turn the color of every character that is not part of the pattern, invisible. This is done again if there is another inline shadow option on the same meter - however in between each inline shadow option we have to reset the other inline coloring options (like gradients) back to normal so that the next shadow option will see the text as it should be and not invisible from the previous inline shadow option. So the more inline shadow options on the same meter, the longer it takes to go through all the steps. Once all the shadow options are done, then the string can be drawn like normal. All that is done on every draw for this one meter. If more meters have inline shadow options, this whole process is done for that meter as well.

So how can I reduce CPU usage using this option?
  1. Control how and when the meter updates. UpdateDivider=-1 can be useful in this situation...but you may need to use !UpdateMeter and !Redraw when you do want the meter to update.
  2. Use FontColor instead of inline coloring if possible. Normally I would suggest to use the newer stuff, but in this particular case, the FontColor will most likely help in reducing CPU usage.
  3. Use FontSize instead of inline sizing. Again, reducing the inline load will help.
  4. Try to keep it simple and not display a shadow under a novel's worth of text. :)

So, where to go from here?
Since this option can dramatically increase CPU usage, just be careful not to overload your skins with this - at least until we can improve the performance. Hopefully performance will improve before we release this out of beta.

-Brian
User avatar
ikarus1969
Posts: 334
Joined: February 28th, 2011, 3:20 pm
Location: Vienna, Austria

Re: Shadow quite cpu-intensive under certain circumstances

ikarus1969 » July 14th, 2016, 3:52 am

Thank you for all the explanations! I will be careful if and when i really "need" want inline-shadow and use it only on skins with only few string-meters.
I keep my fingers crossed that you can find some tweaking for it; in the meantime i'm happy with it as it is now.
Some of my smaller skins really benefit much from inline-shadow!
User avatar
jsmorley
Developer
Posts: 19362
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Shadow quite cpu-intensive under certain circumstances

jsmorley » July 14th, 2016, 12:28 pm

The first suggestion that Brian has:
Control how and when the meter updates.
Is key to having this behave as efficiently as possible. If you can set UpdateDivider=-1 on the meter(s) and use [!UpdateMeter SomeMeter][!Redraw] in OnChangeAction options on measures that drive the values used by the meter(s), you can get orders of magnitude better CPU performance, particularly when mixing Shadow with Color and / or Gradient options.

While we don't want to overstate the case with the Shadow inline option, as in most cases it will perform well and not be any more of a burden than any other string formatting, it is true that it takes just a tiny bit of additional resources to do its work, and if you go crazy with it, it can add up to some alarming CPU usage.