Lag spikes in Fedora 36 KDE

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Lag spikes in Fedora 36 KDE

Post by pgimeno »

pyxledev wrote: Wed Sep 21, 2022 6:48 pm Aw man, I thought the garbage collector could take care of this
It will eventually, but Lua is not aware of the size of the objects created on the C++ side, so it will accumulate many, probably thousands of them before collecting garbage, and when they are big (and fonts are), that's a problem.

Andlac028 wrote: Wed Sep 21, 2022 6:55 pmas it also involves wasting CPU time, just by creating a ton of new identical fonts
And also when releasing them, which is one potential reason for the spikes (when the GC clears a lot at a time).
User avatar
BrotSagtMist
Party member
Posts: 604
Joined: Fri Aug 06, 2021 10:30 pm

Re: Lag spikes in Fedora 36 KDE

Post by BrotSagtMist »

I does not.
I have a textbox here with free zooming and font choosing options.
It can easily eat a few gigs of ram.
Automatic GC will most likely never take care of it, or at least i was never been able to trigger it. Oh and since the amount of data is proportional to the size it explains why scaling up makes it so bad. It was never good to begin with tho, you just not noticed before.
Data creating function should never been used in the main loops anyway, the wiki even warns about that.

Keeping a cache table for fonts and images would be a good workaround here. Or just do as Andlac028 says which is the fastest way.

NOW its time to wonder why you get different results on different OSes or with sudo. That is pretty interesting.
Is fedora just more resource hungry? Does it give root a better niceness?
After fixing the data caching, can you give it a spin again and see if there remains a difference?
obey
User avatar
pyxledev
Prole
Posts: 23
Joined: Tue Jul 26, 2022 2:19 pm
Contact:

Re: Lag spikes in Fedora 36 KDE

Post by pyxledev »

Andlac028 wrote: Wed Sep 21, 2022 6:51 pm
pyxledev wrote: Wed Sep 21, 2022 6:44 pm Is there a way to change the font size during loop? It's one of the main factors I used setNewFont().
In your case, you are mainly using constant size font, so just create more fonts on start with different sizes, like

Code: Select all

FONT_MINECRAFTIA_14 = love.graphics.newFont("fonts/Minecraftia-Regular.ttf", 14)
FONT_MINECRAFTIA_22 = love.graphics.newFont("fonts/Minecraftia-Regular.ttf", 22)
FONT_MINECRAFTIA_24 = love.graphics.newFont("fonts/Minecraftia-Regular.ttf", 24)

-- and then use
love.graphics.setFont(FONT_MINECRAFTIA_14)
-- instead of 
love.graphics.setNewFont("fonts/Minecraftia-Regular.ttf", 14)
The only chase when you are using dynamic font size is in damageNumber, but there you can just create some fonts with different sizes and set the appropriate font based on the size.

It is way better to create 50 fonts with different sizes on start, than new font every frame (that is 60 fonts per second with 60 FPS) like:

Code: Select all

FONTS_MINECRAFTIA = {}

-- create fonts with sizes from 10px to 50px
for size = 10, 50 do
  FONTS_MINECRAFTIA[size] = love.graphics.newFont("fonts/Minecraftia-Regular.ttf", size)
end

-- and then use
love.graphics.setFont(FONTS_MINECRAFTIA[some_computed_font_size])
I'll consider that, but there should be a better way to fix this. Maybe love.graphics.scale() will do the job? (İ'll have to find a way to center the text tho)
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Lag spikes in Fedora 36 KDE

Post by pgimeno »

It's also possible to implement memoization.

Code: Select all

local fontPool = {}

function setFont(fontname, size)
  local key = fontname .. "\0" .. size
  local font = fontPool[key]
  if font then
    love.graphics.setFont(font)
  else
    font = love.graphics.setNewFont(fontname, size)
    fontPool[key] = font
  end
  return font
end
User avatar
pyxledev
Prole
Posts: 23
Joined: Tue Jul 26, 2022 2:19 pm
Contact:

Re: Lag spikes in Fedora 36 KDE

Post by pyxledev »

pgimeno wrote: Thu Sep 22, 2022 9:51 am It's also possible to implement memoization.

Code: Select all

local fontPool = {}

function setFont(fontname, size)
  local key = fontname .. "\0" .. size
  local font = fontPool[key]
  if font then
    love.graphics.setFont(font)
  else
    font = love.graphics.setNewFont(fontname, size)
    fontPool[key] = font
  end
  return font
end
Thanks! I still couldn't find a proper way to change font size during loop so it looks like I'll be using this function.
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: Lag spikes in Fedora 36 KDE

Post by milon »

pyxledev wrote: Sat Sep 24, 2022 12:34 pm Thanks! I still couldn't find a proper way to change font size during loop ...
In Love, you can't change font size the way you do in a word processor. Font size is a part of every font Love uses and must be defined when creating the font (or else size 12pt is assumed). If you want to "change the size" you must load/reference another font. You create different font sizes by creating multiple fonts with the same name but different sizes. And, of course, store those fonts in memory! Don't re-create them in any love callback (sub)function, as you already know. ;)
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Lag spikes in Fedora 36 KDE

Post by pgimeno »

pgimeno wrote: Wed Sep 21, 2022 7:11 pm
pyxledev wrote: Wed Sep 21, 2022 6:48 pm Aw man, I thought the garbage collector could take care of this
It will eventually,
BrotSagtMist wrote: Wed Sep 21, 2022 10:17 pm I does not.
I have a textbox here with free zooming and font choosing options.
It can easily eat a few gigs of ram.
Automatic GC will most likely never take care of it, or at least i was never been able to trigger it.
It will eventually, if it has a chance before the process runs out of memory.

Proof:

Code: Select all

local i = 1
repeat
  love.graphics.newFont(6)
  if i % 500 == 0 then
    print(collectgarbage("count"))
  end
  i = i + 1
until false
Example output:

Code: Select all

706.130859375
792.630859375
903.130859375
965.630859375
913.486328125
914.189453125
976.689453125
1039.189453125
1101.689453125
583.939453125
646.439453125
708.939453125
771.439453125
834.330078125
896.830078125
959.330078125
1021.830078125
1252.517578125
1315.017578125
1377.517578125
1440.017578125
1502.517578125
766.205078125
828.705078125
891.205078125
953.705078125
1016.205078125
1078.705078125
1141.205078125
1203.705078125
1266.205078125
1328.705078125
1391.205078125
1453.705078125
1491.142578125
1553.642578125
1616.142578125
1678.642578125
1741.142578125
1803.642578125
1866.142578125
1928.642578125
1991.142578125
2053.642578125
1383.580078125
827.205078125
889.705078125
664.205078125
726.705078125
885.205078125
947.705078125
1010.205078125
1072.705078125
1327.205078125
1389.705078125
1452.205078125
1471.892578125
1534.392578125
1596.892578125
1659.392578125
1721.892578125
1784.392578125
1846.892578125
1909.392578125
1312.955078125
814.580078125
877.080078125
939.580078125
1002.080078125
1064.580078125
1127.080078125
997.580078125
1060.080078125
1314.580078125
1377.080078125
1439.580078125
1462.580078125
1525.080078125
1587.580078125
1650.080078125
1712.580078125
1775.080078125
1837.580078125
1900.080078125
1962.580078125
780.580078125
843.080078125
905.580078125
968.080078125
1030.580078125
1093.080078125
963.580078125
1026.080078125
1280.580078125
1343.080078125
1405.580078125
1427.955078125
1490.455078125
1552.955078125
1615.455078125
1677.955078125
1740.455078125
1802.955078125
1865.455078125
1927.955078125
1320.455078125
813.080078125
875.580078125
938.080078125
1000.580078125
1063.080078125
933.580078125
996.080078125
1058.580078125
1313.080078125
1375.580078125
...
These values are in KB, so it maxes out at around 2 MB. However, these are the Lua-side userdata pointers; the actual C++-side font data is not accounted for in that size.

The fonts created by that test program are small, so they use little memory and Lua has a chance to collect garbage before the size grows to a dimension that doesn't fit in the available memory. If they are big, of course Lua will not notice that RAM usage is disproportionate and that cleanup is necessary.

I may be wrong, but I believe that's the main reason why Object:release was introduced. What it does is free the C++-side memory while leaving the Lua-side object intact.

Of course there's another way which would be to invoke the garbage collector manually in the loop.

Anyway, the cleanest solution if the same fonts are going to be used again and again, is memoization.
User avatar
BrotSagtMist
Party member
Posts: 604
Joined: Fri Aug 06, 2021 10:30 pm

Re: Lag spikes in Fedora 36 KDE

Post by BrotSagtMist »

Yet it filled gigabytes here. ¯\_(ツ)_/¯
My code was basically just
function love.resize(X, Y) love.graphics.setFont( love.graphics.newFont(FSelection, Y * Fsize ) ) end
And wiggling the window around for some time lead to some resource issues.

How would one use font:release on fonts seeing that there is not even a handle exposed in this construct?
obey
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: Lag spikes in Fedora 36 KDE

Post by pgimeno »

BrotSagtMist wrote: Sat Oct 01, 2022 12:41 pm Yet it filled gigabytes here. ¯\_(ツ)_/¯
My code was basically just
function love.resize(X, Y) love.graphics.setFont( love.graphics.newFont(FSelection, Y * Fsize ) ) end
And wiggling the window around for some time lead to some resource issues.

How would one use font:release on fonts seeing that there is not even a handle exposed in this construct?

Code: Select all

-- at the top of main.lua:
  defaultFont = love.graphics.getFont()

-- in love.resize():
function love.resize(X, Y)
  local oldFont = love.graphics.getFont()
  love.graphics.setFont(defaultFont)
  if oldFont ~= defaultFont then
    oldFont:release()
  end
  love.graphics.setNewFont(FSelection, Y * Fsize)
end
User avatar
pyxledev
Prole
Posts: 23
Joined: Tue Jul 26, 2022 2:19 pm
Contact:

Re: Lag spikes in Fedora 36 KDE

Post by pyxledev »

BrotSagtMist wrote: Wed Sep 21, 2022 10:17 pm I does not.
I have a textbox here with free zooming and font choosing options.
It can easily eat a few gigs of ram.
Automatic GC will most likely never take care of it, or at least i was never been able to trigger it. Oh and since the amount of data is proportional to the size it explains why scaling up makes it so bad. It was never good to begin with tho, you just not noticed before.
Data creating function should never been used in the main loops anyway, the wiki even warns about that.

Keeping a cache table for fonts and images would be a good workaround here. Or just do as Andlac028 says which is the fastest way.

NOW its time to wonder why you get different results on different OSes or with sudo. That is pretty interesting.
Is fedora just more resource hungry? Does it give root a better niceness?
After fixing the data caching, can you give it a spin again and see if there remains a difference?
I've been remaking the UI from scratch for a while now and it definitely did fix the issue. But im still curious about the distro and super user part. Recently tested the memory leak with windows 10 and it worked just as good as ZorinOS. It could be about the desktop environment too, its important to note that I use the kde spin of Fedora 36.
Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests