Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intensive CPU/GPU usage when displaying animated content in the editor scene #39758

Open
itsjavi opened this issue Jun 22, 2020 · 83 comments
Open

Comments

@itsjavi
Copy link

itsjavi commented Jun 22, 2020

Godot version:

  • 3.2.1.stable.official
  • 3.2.2.rc3

OS/device including version:

  • OS: macOS Catalina 10.15.5
  • Hardware:
    • macbook Pro 13' 2015 + Intel Iris Graphics 6100 + 8 GB RAM + i5 Dual Core
    • macbook Pro 13' 2018 + Intel Iris Plus Graphics 655 + 16 GB RAM + i5 Quad Core

Issue description:
When using AnimatedTexture(s) the editor seems to put a lot of load in the CPU, whose fans start to work intensively (they can become very loud in both macs).
As you can see in the following GIF, the CPU usage is around 20% and GPU ~35% even if the IDE is idle:

Jun-22-2020 19-00-46

I don't know if this is a CPU or GPU issue. You can also see that the Idle Wake-ups are higher than normal (I don't know if that's some indicator for this issue). Only when the node having the animations is hidden, the hardware load starts to normalize.

This is maybe related to #30115 , but I am not sure, that's why I created this ticket.

Steps to reproduce:

  • Create a new project (2D, GLES3)
  • Create a new AnimatedTexture with some frames, assigning images to them.
  • Use it in a new TileSet resource (not sure if this is related or not), as single tile.
  • Draw some tiles in a new TileMap node, using the animated tile you created.
  • Wait some minutes with the IDE playing the animations of your animated tiles // or continue working with the IDE and the scene having the animations.

This issue only affects the IDE. The game itself doesn't seem to have this problem when running.

Minimal reproduction project:

godot-issue-39758.zip

PS: Would be nice and convenient to be able to stop playing animated textures (or animations in general) in the IDE. A button or a checkbox in the menu or in the IDE settings.

@lawnjelly
Copy link
Member

PS: Would be nice and convenient to be able to stop playing animated textures in the IDE. A button or a checkbox in the menu.

Agree with this (may have mentioned it before in another issue in fact). And not just animated textures, all the features that request frame updates (shaders using time, bones animations etc). Would be very helpful on lower power machines. As it is, I have to manually close tabs in order to prevent this runaway CPU usage.

@Calinou
Copy link
Member

Calinou commented Jun 23, 2020

@lawnjelly This was implemented in #31070, but it needs to be redone for the current master branch as it wasn't merged.

@itsjavi
Copy link
Author

itsjavi commented Jun 23, 2020

@Calinou cool, I think this option would be enough for now, since this only affects the IDE. It seems not a problem for the compiled game itself.

@itsjavi
Copy link
Author

itsjavi commented Jul 31, 2020

Issue still present in 3.2.3 RC3

Multitasking becomes difficult when the IDE has a +35% CPU usage because of this.

CPU fans are running at full speed all the time until the Animated sprites are hidden.

Tried on a macbook PRO 2018 (Intel graphics)

@ghost
Copy link

ghost commented Aug 9, 2020

Hi,

Can you please post detailed instructions on creating the "AnimatedTexture", I do not see it when adding new nodes. Would love to test to see if I can reproduce this bug on v3.22.

Thanks.

@Calinou
Copy link
Member

Calinou commented Aug 9, 2020

@knadoor An AnimatedTexture is a resource, not a node. You can create one by choosing New AnimatedTexture after clicking on the dropdown arrow next to a Sprite's Texture property.

@ghost
Copy link

ghost commented Aug 11, 2020

Untitled
I tried to replicate this but could not - I did notice an uptick in my laptops fans but CPU utilization is not bad.
Perhaps if you create a video that would help.

@lawnjelly
Copy link
Member

Just to clarify, is this issue caused by only animated texture, or does anything that causes editor updates cause it? If you place e.g. an animated model in the 3d window of the IDE?

@itsjavi
Copy link
Author

itsjavi commented Aug 11, 2020

In the description there is a minimal project zip file to reproduce it. Also, pls check the screenshot in the issue description (it's a GIF). GPU goes up to 35% with that project.

@lawnjelly I don't know if there are other use cases or features causing this problem, but I suspect that it has to do with anything related to previewing animated content.

@knadoor I see that you are using Windows and that's maybe why you cannot reproduce it. The issue I reported is for macOS using Intel integrated graphics cards. So I guess this happens in less-capable GPUs.

@itsjavi itsjavi changed the title Intensive CPU usage on editor when playing AnimatedTexture(s) Intensive CPU usage on editor when displaying AnimatedTexture(s) in the scene Aug 11, 2020
@lawnjelly
Copy link
Member

@lawnjelly I don't know if there are other use cases or features causing this problem, but I suspect that it has to do with anything related to previewing animated content.

In that case it is possible it could be a duplicate of #17584. This has been an ongoing issue on some Macs with slow rendering. None of the rendering guys tend to use Macs or have hardware that exhibits the problem, so it's been a bit difficult to investigate.

@itsjavi itsjavi changed the title Intensive CPU usage on editor when displaying AnimatedTexture(s) in the scene Intensive CPU/GPU usage on editor when displaying AnimatedTexture(s) in the scene Aug 11, 2020
@itsjavi
Copy link
Author

itsjavi commented Aug 11, 2020

I see
@lawnjelly should I close this issue then?

anyway I could help testing. I keep doing it in every RC release.
I have a MBP 2015 (Intel Graphics), MBP 2018 (Intel Graphics) and an iMac 2019 with a Radeon 5700 XT, where I don't have this issue, so it seems related to Intel graphics.

@lawnjelly
Copy link
Member

I see
@lawnjelly should I close this issue then?

anyway I could help testing.
I have a MBP 2015 (Intel Graphics), MBP 2018 (Intel Graphics) and an iMac 2019 with a Radeon 5700 XT, where I don't have this issue, so it seems related to Intel graphics.

You may well be right about it being Intel related. 👍

If you are able to confirm that it is anything animated (try a shader using time, or an animated character maybe) that causes IDE updates which triggers slowness for you then we could close this one, as it would seem likely to be the same (and even the closed issue will be visible and linked now so that will help us with hardware specs). If other animations don't cause the same problem then it will suggest it is a different issue and it should remain separate.

@ViktorEvil
Copy link
Contributor

can confirm this is a problem with animated sprites and in one small project I get the same screaming fans and 40% CPU usage in a scene with a few Particle2D nodes. I came here to see if anybody else was affected by this issue of if my MacBook Air 2015 was getting too old to be used with Godot

using Godot 3.2.2
macOS 10.15.6

@Calinou
Copy link
Member

Calinou commented Aug 15, 2020

This was confirmed by someone on Windows. Apparently, disabling V-Sync and setting the FPS cap in the Project Settings to 60 decreases the CPU usage a lot.

Can someone try to run a debug build in a profiler to know where most of the CPU usage is coming from?

@lullabyist
Copy link

lullabyist commented Aug 20, 2020

Unfortunately not Intel related, and not limited to AnimatedTexture(s) either.

On my MBP 2015 with the discrete Radeon R9 M370X, Godot's update spinner spinning means 100 (that's right) percent GPU processor load. This can be caused by anything that updates the editor continuously, and most egregiously: An idle animation on my 3D character. Which means if I have my animation tree enabled, I have godot using 100% of my GPU. If I use a ClippedCamera, 100%.

About a minute of GPU load with constant spinning (with the Animation Tree on), versus a minute without:
Screenshot 2020-08-20 at 09 46 40

This is not tied to anything specific. It is simply how Godot updates on my machine, unfortunately.
If I enable "Update continuously" in the Editor settings, I see the same behaviour, 100%.

I fear that this may be indicative of a larger issue on the Mac side than just what is found in this thread. Should I create a new issue for this?

I really would like to help fix this, in whichever way I can, since Godot is basically unusable for me otherwise. While my programming is nowhere enough, I can build and test any branch that needs it.

@Calinou
Copy link
Member

Calinou commented Aug 20, 2020

@molevision Rendering the editor at an hiDPI scale is much more demanding than at a loDPI scale. That said, you can enable Half Resolution in the Perspective/Orthogonal menu at the top-left corner of the 3D viewport to decrease the GPU load. (GPU load will still be higher than on an actual loDPI display due to 2D elements being rendered at a higher resolution and all that.)

On top of that, you can also increase Low Processor Mode Sleep Usec in the Project Settings to make the editor redraw less often. 100000 is the highest you can go (effectively 10 FPS), but a value like 33333 (30 FPS) is probably more reasonable. Note that this value applies only if Update Continuously is not enabled.

The only way I see to fix this is to add a button that pauses various simulations in the editor: godotengine/godot-proposals#942

There's a pull request that attempted to add this, but it needs to be salvaged: #31070

@lullabyist
Copy link

@Calinou Thank you for the help, I tried the steps you mentioned (LoDPI and 33333 low processor mode sleep usec) but even then I get about 80% constant load, if the editor updates continuously. Even with my game running with low processor mode disabled I get less load on the GPU, about 30-40%.

Could I be assured this is expected behaviour with Godot's update system? Surely, a new project with only an empty Particles node shouldn't be completely maxing out the GPU load?

Regardless, the pause button seems like a really good solution for the time being. Maybe calling it something else (like "freeze") would help prevent confusion with the pause scene button right above it.

@Calinou
Copy link
Member

Calinou commented Aug 20, 2020

Could I be assured this is expected behaviour with Godot's update system? Surely, a new project with only an empty Particles node shouldn't be completely maxing out the GPU load?

If anything causes the editor to redraw continuously, then the entire editor must draw 60 times a second (or more on high refresh rate monitors). There is no notion of partial redraws in most game engines, since most games will always cause the whole screen to update in one way or another during gameplay.

@lullabyist
Copy link

lullabyist commented Aug 20, 2020

I did a little more digging and ran Godot with the same settings I had earlier, at HiDPI, except forcing it to use my integrated Intel (Iris Pro) card, and performance was dramatically better, only ~40% GPU used with both the game and the editor running, and focus on the continuously updating editor. The editor's framerate was a little slower but the game's was identical. So unlike everyone else on the thread, the load on the Intel chipset on my 2015 MBP is half than that on my discrete AMD card. I'll run tests with a Vulkan build to see if anything has changed with Metal.

Regardless, until we can reconcile this, salvaging #31070 would be a lifesaver.

@naithar
Copy link
Contributor

naithar commented Aug 28, 2020

CPU usage of MRP in Instruments app. Hopefully it'll help.

Animated tiles enabled (tested for 5 seconds):
gles3-cpu-animated
gles3-cpu-animated-2

Trace:

  23  8077.0  godot (9615) :0
  22 libdyld.dylib 8077.0  0x7fff70cc5cc8
  21 godot 8077.0  main src/platform/osx/godot_main_osx.mm:71
  20 godot 8077.0  OS_OSX::run() src/platform/osx/os_osx.mm:3153
  19 godot 7920.0  Main::iteration() src/main/main.cpp:2118
  18 godot 7622.0  VisualServerWrapMT::draw(bool, double) src/servers/visual/visual_server_wrap_mt.cpp:102
  17 godot 7621.0  VisualServerRaster::draw(bool, double) /Users/naithar/Projects/godot_xcode/src/servers/visual/visual_server_raster.cpp:108
  16 godot 6897.0  VisualServerViewport::draw_viewports() src/servers/visual/visual_server_viewport.cpp:344
  15 godot 6826.0  VisualServerViewport::_draw_viewport(VisualServerViewport::Viewport*, ARVRInterface::Eyes) src/servers/visual/visual_server_viewport.cpp:241
  14 godot 6801.0  VisualServerCanvas::render_canvas(VisualServerCanvas::Canvas*, Transform2D const&, RasterizerCanvas::Light*, RasterizerCanvas::Light*, Rect2 const&, int) src/servers/visual/visual_server_canvas.cpp:270
  13 godot 6223.0  RasterizerCanvasGLES3::canvas_render_items(RasterizerCanvas::Item*, int, Color const&, RasterizerCanvas::Light*, Transform2D const&) src/drivers/gles3/rasterizer_canvas_gles3.cpp:1708
  12 godot 5939.0  RasterizerCanvasGLES3::_canvas_item_render_commands(RasterizerCanvas::Item*, RasterizerCanvas::Item*, bool&) src/drivers/gles3/rasterizer_canvas_gles3.cpp:871
  11 godot 1174.0  RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) src/drivers/gles3/rasterizer_canvas_gles3.cpp:607

Animated tiles disabled (tested for 10 seconds):
gles3-cpu-nonanimated

@lawnjelly
Copy link
Member

@naithar that is interesting to look at. Can the profiler display how many times each function is called too?

One possibility is that the whole render is being done far more times than expected (e.g. if the scene was being rendered 400 times per second or something), so it would be nice to discount that.

I'm assuming the figures given are time within function and children, percentage of time within function and children, and time within function excluding children. In which case none of the functions shown seem to be hogging the time on the CPU, so on first impressions it seems to be bottlenecked by the GPU or driver.

@naithar
Copy link
Contributor

naithar commented Aug 28, 2020

Found some ugly way to count the amount of times function got called via breakpoint list (which almost killed my mac 😆 ). Both test was running for 2 minutes.
Not sure if they are anywhere correct, but that's what I got.

Running with animation disabled:

Summary:
1.1 Main::iteration - max hit count = 5293
2.1 VisualServerViewport::draw_viewports() - max hit count = 13
3.1 VisualServerCanvas::render_canvas - max hit count = 26
4.1 RasterizerCanvasGLES3::canvas_render_items - max hit count = 26
5.1 RasterizerCanvasGLES3::_draw_gui_primitive - max hit count = 1756
6.1 RasterizerCanvasGLES3::_canvas_item_render_commands - max hit count = 959

Long log
1: file = 'src/main/main.cpp', line = 2031, exact_match = 0, locations = 1, resolved = 1, hit count = 5293

  1.1: where = godot`Main::iteration() + 25 at main.cpp:2036:11, address = 0x0000000100054ef9, resolved, hit count = 5293 

2: file = 'src/servers/visual/visual_server_viewport.cpp', line = 267, exact_match = 0, locations = 1, resolved = 1, hit count = 13

  2.1: where = godot`VisualServerViewport::draw_viewports() + 44 at visual_server_viewport.cpp:270:21, address = 0x0000000102fc295c, resolved, hit count = 13 

3: file = 'src/servers/visual/visual_server_canvas.cpp', line = 227, exact_match = 0, locations = 1, resolved = 1, hit count = 25

  3.1: where = godot`VisualServerCanvas::render_canvas(VisualServerCanvas::Canvas*, Transform2D const&, RasterizerCanvas::Light*, RasterizerCanvas::Light*, Rect2 const&, int) + 87 at visual_server_canvas.cpp:229:2, address = 0x0000000102f73957, resolved, hit count = 25 

4: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 1417, exact_match = 0, locations = 1, resolved = 1, hit count = 25

  4.1: where = godot`RasterizerCanvasGLES3::canvas_render_items(RasterizerCanvas::Item*, int, Color const&, RasterizerCanvas::Light*, Transform2D const&) + 45 at rasterizer_canvas_gles3.cpp:1419:8, address = 0x0000000100f66e8d, resolved, hit count = 25 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

3: file = 'src/servers/visual/visual_server_canvas.cpp', line = 227, exact_match = 0, locations = 1, resolved = 1, hit count = 26

  3.1: where = godot`VisualServerCanvas::render_canvas(VisualServerCanvas::Canvas*, Transform2D const&, RasterizerCanvas::Light*, RasterizerCanvas::Light*, Rect2 const&, int) + 87 at visual_server_canvas.cpp:229:2, address = 0x0000000102f73957, resolved, hit count = 26 

4: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 1417, exact_match = 0, locations = 1, resolved = 1, hit count = 26

  4.1: where = godot`RasterizerCanvasGLES3::canvas_render_items(RasterizerCanvas::Item*, int, Color const&, RasterizerCanvas::Light*, Transform2D const&) + 45 at rasterizer_canvas_gles3.cpp:1419:8, address = 0x0000000100f66e8d, resolved, hit count = 26 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1752

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1752 

6: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 700, exact_match = 0, locations = 1, resolved = 1, hit count = 959

  6.1: where = godot`RasterizerCanvasGLES3::_canvas_item_render_commands(RasterizerCanvas::Item*, RasterizerCanvas::Item*, bool&) + 60 at rasterizer_canvas_gles3.cpp:702:11, address = 0x0000000100f6973c, resolved, hit count = 959 

6: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 700, exact_match = 0, locations = 1, resolved = 1, hit count = 959

  6.1: where = godot`RasterizerCanvasGLES3::_canvas_item_render_commands(RasterizerCanvas::Item*, RasterizerCanvas::Item*, bool&) + 60 at rasterizer_canvas_gles3.cpp:702:11, address = 0x0000000100f6973c, resolved, hit count = 959 

6: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 700, exact_match = 0, locations = 1, resolved = 1, hit count = 959

  6.1: where = godot`RasterizerCanvasGLES3::_canvas_item_render_commands(RasterizerCanvas::Item*, RasterizerCanvas::Item*, bool&) + 60 at rasterizer_canvas_gles3.cpp:702:11, address = 0x0000000100f6973c, resolved, hit count = 959 

6: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 700, exact_match = 0, locations = 1, resolved = 1, hit count = 959

  6.1: where = godot`RasterizerCanvasGLES3::_canvas_item_render_commands(RasterizerCanvas::Item*, RasterizerCanvas::Item*, bool&) + 60 at rasterizer_canvas_gles3.cpp:702:11, address = 0x0000000100f6973c, resolved, hit count = 959 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1756

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1756 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 1756

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 1756 

Running with animation enabled:

Summary:
1.1 Main::iteration - max hit count = 33
2.1 VisualServerViewport::draw_viewports() - max hit count = 33
3.1 VisualServerCanvas::render_canvas - max hit count = 66
4.1 RasterizerCanvasGLES3::canvas_render_items - max hit count = 99
5.1 RasterizerCanvasGLES3::_draw_gui_primitive - max hit count = 4672
6.1 RasterizerCanvasGLES3::_canvas_item_render_commands - max hit count = 2506

Long log
6: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 700, exact_match = 0, locations = 1, resolved = 1, hit count = 2506

  6.1: where = godot`RasterizerCanvasGLES3::_canvas_item_render_commands(RasterizerCanvas::Item*, RasterizerCanvas::Item*, bool&) + 60 at rasterizer_canvas_gles3.cpp:702:11, address = 0x0000000100f6973c, resolved, hit count = 2506 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

1: file = 'src/main/main.cpp', line = 2031, exact_match = 0, locations = 1, resolved = 1, hit count = 33

  1.1: where = godot`Main::iteration() + 25 at main.cpp:2036:11, address = 0x0000000100054ef9, resolved, hit count = 33 

2: file = 'src/servers/visual/visual_server_viewport.cpp', line = 267, exact_match = 0, locations = 1, resolved = 1, hit count = 33

  2.1: where = godot`VisualServerViewport::draw_viewports() + 44 at visual_server_viewport.cpp:270:21, address = 0x0000000102fc295c, resolved, hit count = 33 

3: file = 'src/servers/visual/visual_server_canvas.cpp', line = 227, exact_match = 0, locations = 1, resolved = 1, hit count = 65

  3.1: where = godot`VisualServerCanvas::render_canvas(VisualServerCanvas::Canvas*, Transform2D const&, RasterizerCanvas::Light*, RasterizerCanvas::Light*, Rect2 const&, int) + 87 at visual_server_canvas.cpp:229:2, address = 0x0000000102f73957, resolved, hit count = 65 

4: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 1417, exact_match = 0, locations = 1, resolved = 1, hit count = 97

  4.1: where = godot`RasterizerCanvasGLES3::canvas_render_items(RasterizerCanvas::Item*, int, Color const&, RasterizerCanvas::Light*, Transform2D const&) + 45 at rasterizer_canvas_gles3.cpp:1419:8, address = 0x0000000100f66e8d, resolved, hit count = 97 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

4: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 1417, exact_match = 0, locations = 1, resolved = 1, hit count = 98

  4.1: where = godot`RasterizerCanvasGLES3::canvas_render_items(RasterizerCanvas::Item*, int, Color const&, RasterizerCanvas::Light*, Transform2D const&) + 45 at rasterizer_canvas_gles3.cpp:1419:8, address = 0x0000000100f66e8d, resolved, hit count = 98 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

3: file = 'src/servers/visual/visual_server_canvas.cpp', line = 227, exact_match = 0, locations = 1, resolved = 1, hit count = 66

  3.1: where = godot`VisualServerCanvas::render_canvas(VisualServerCanvas::Canvas*, Transform2D const&, RasterizerCanvas::Light*, RasterizerCanvas::Light*, Rect2 const&, int) + 87 at visual_server_canvas.cpp:229:2, address = 0x0000000102f73957, resolved, hit count = 66 

4: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 1417, exact_match = 0, locations = 1, resolved = 1, hit count = 99

  4.1: where = godot`RasterizerCanvasGLES3::canvas_render_items(RasterizerCanvas::Item*, int, Color const&, RasterizerCanvas::Light*, Transform2D const&) + 45 at rasterizer_canvas_gles3.cpp:1419:8, address = 0x0000000100f66e8d, resolved, hit count = 99 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

5: file = 'src/drivers/gles3/rasterizer_canvas_gles3.cpp', line = 551, exact_match = 0, locations = 1, resolved = 1, hit count = 4672

  5.1: where = godot`RasterizerCanvasGLES3::_draw_gui_primitive(int, Vector2 const*, Color const*, Vector2 const*) + 66 at rasterizer_canvas_gles3.cpp:557:6, address = 0x0000000100f66a52, resolved, hit count = 4672 

@lawnjelly
Copy link
Member

lawnjelly commented Aug 28, 2020

I'm used to profilers giving a call count as part of the data, maybe the method the mac profiler uses is making this difficult.

Those types of numbers should be no problem, it should be doing e.g. those types of numbers no problem in a second, rather than 2 mins! The profiler can slow things down, so this could be anomalous results given that it seems the bottleneck seems not to be in Godot CPU code. So we may not be getting a true picture of the ratio of calls without the slowdown from the profiler.

Having said all that I can't see anything immediately obvious as being problematic godot CPU side, so it does look this is something we are doing that either the driver or GPU doesn't like.

Have you guys tried all this in GLES2 with batching? Do you get the same slowdown?

As I have mentioned in the other thread, the way I would probably investigate this is as follows:

  1. Start with an empty project
  2. Gradually add features (sprites, animated textures etc) one by one until you find a particular thing that is causing a dramatic slowdown

If it is animated textures particularly, it could be doing something like reading the texture back from the GPU, however no one has been able to provide information as to whether it is a particular thing that is causing it (or if it doesn't occur with only using certain features), so there is not much to go on. Of course it could be just using reference rasterizer in which case everything would be slow and the CPU would be maxed out in the driver I guess.

Also noteworthy is that the driver isn't appearing in the profile at all. It would be nice to know whether it appears (maybe off the screen towards the bottom) and that will confirm it's not bottlenecked by CPU driver stuff (although it could still be e.g. waiting for info back from GPU).

It could also be some high level thing in terms of the frame buffers that this platform doesn't like. Which would be incredibly difficult to debug remotely.

@setanarut
Copy link
Contributor

Does this happen on all platforms by the way or just on macOS?

This happens on all platforms, but it's more noticeable on macOS because of hiDPI monitors (causing higher GPU load) and suboptimal OpenGL rendering due to macOS graphics drivers.

As I mentioned above, forcing low DPI and/or capping FPS to a low value will help improve battery life. There isn't much else that can be done.

"open in low resolution mode" is gone in macOs Monterey, Apple is no longer supporting "low resolution mode".

@bruvzg
Copy link
Member

bruvzg commented Feb 1, 2022

"open in low resolution mode" is gone in macOs Monterey, Apple is no longer supporting "low resolution mode".

It is removed from the UI, but there are multiple options to force it:

  • You can modify Info.plist in the .app bundle, and set NSHighResolutionCapable to false.
  • Or pass -AppleMagnifiedMode Yes as a command line argument, when running from terminal.
  • Or set the defaults for app, by using defaults write org.godotengine.godot AppleMagnifiedMode -bool Yes command.

@setanarut
Copy link
Contributor

Thanks it worked.

@FarbrorMartin
Copy link

Will this issue be resolved in Godot 4?

I'm working on a 2D project where I use animated textures in tilemaps, and also some animated sprites and with level open in the editor the GPU usage is really high, even when not using the editor.

Actually I get 50% GPU load by simply showing a single 32x32 AnimatedTexture running at 8 fps in the inspector. The sprite is nothing special and should really not tax the GPU.
image

If I open an ordinary sprite my GPU usage drops to 2%.

This is my GPU graph when displaying the AnimatedTexture in the inspector. Left side is with an ordinary sprite displayed.
image

The CPU load also increases, but not on all cores, so the overall effect is less.

This is a practical problem for me (and for others I assume) and I really hope it can be resolved. The high GPU load really drains the battery and makes the laptop too hot to have sitting on the lap.

I've read some comments from people who can't replicate the issue. But make sure you check the GPU usage, and not just the CPU. The fans starting is a sign that something is running hot.

This is Godot 3.4.2 on a laptop running Windows 10. Intel integrated graphics UHD 620.

@lawnjelly
Copy link
Member

lawnjelly commented Jun 11, 2022

I'm working on a 2D project where I use animated textures in tilemaps, and also some animated sprites and with level open in the editor the GPU usage is really high, even when not using the editor.

#39758 (comment)

Download 3.5 latest version, go to editor settings, select interface/editor/show_update_spinner. Click the update spinner animated icon in the top right, and select "update vital changes". This should stop the updating (unless there is something I have missed in the PR) - it is designed for laptops and low power machines.

I have also noticed that rarely some editor addons still manage to cause continous updating, but that is down to the design of the addon I suspect.

@FarbrorMartin
Copy link

FarbrorMartin commented Jun 11, 2022

Thanks for you quick reply!
Unfortunately, enabling Update vital changes did not help with the issue.

I did a little test and set the Animated Texture to 0 FPS, and it still causes the same GPU load. The update spinner is constantly spinning when the Animated Texture is displayed in the viewport or in the inspector.
Even at 0 FPS, and with the setting "Update vital changes", displaying the Animated Texture makes the GPU jump up to 65%
image

Edit:
The GPU load is the same if I check "Pause", so obviously some process is doing unnecessary work.

@lawnjelly
Copy link
Member

If you can create an MRP I can probably fix this.

@FarbrorMartin
Copy link

What is an MRP?

@FarbrorMartin
Copy link

FarbrorMartin commented Jun 11, 2022

To be clear, I don't think 0 FPS or paused Animated Textures need fixing. That was just to try to find the core issue.
The real problem is the constant high load when the are animating.

As a comparison an Animated Sprite also causes (unnecessary?) GPU load, but it depends on how many are on screen and how high FPS they are set to. A single 32x32 Animated Sprite at 60 FPS causes 80% GPU load on my machine, but at 4 FPS it's just 10%.
Edit: fixed typos

@lawnjelly
Copy link
Member

MRP = minimum reproduction project, a simple project zipped up that shows the bug, that we can debug.

The issue with the single sprite animating at 60fps, is that it will result in the entire editor being redrawn at 60fps, which will use a lot of GPU.

@Calinou
Copy link
Member

Calinou commented Jun 11, 2022

You can increase Low Processor Mode Sleep Usec to decrease CPU/GPU usage when something causes the editor to redraw constantly, but this will make the editor less reactive. The same goes for Unfocused Low Processor Mode Sleep Usec. Note that these values are ignored if Update Continuously is enabled in the Editor Settings.

AnimatedTexture has a longstanding issue where it causes constant redrawing regardless of the FPS it's set at. To be fair, the way it works was always pretty hacky, and it's been considered for removal in 4.0 (like ProxyTexture). We're too far in the 4.0 cycle to remove it by now, so I guess it'll have to stay.

@FarbrorMartin
Copy link

MRP of the problem.
32x32 Animated texture with 2 frames, animating at 4 fps. A single sprite with the animated texture.

In the Editor:
Sprite hidden: GPU load 2%
Sprite visible: GPU load 62%

Running the game: GPU load 13%.
(with the sprite not visible in editor window of course)

AnimatedTextureTest.zip

@FarbrorMartin
Copy link

AnimatedTexture has a longstanding issue where it causes constant redrawing regardless of the FPS it's set at. To be fair, the way it works was always pretty hacky, and it's been considered for removal in 4.0 (like ProxyTexture). We're too far in the 4.0 cycle to remove it by now, so I guess it'll have to stay.

I see. I only use it for animating tiles in Tilemaps, but it's really useful for that. To me it seems to work better in game than in the editor, so maybe there is something that could be done. See my post above.

@Calinou
Copy link
Member

Calinou commented Jun 11, 2022

I see. I only use it for animating tiles in Tilemaps, but it's really useful for that. To me it seems to work better in game than in the editor, so maybe there is something that could be done. See my post above.

We could disable redraw requests from AnimatedTexture by default, but this will cause the texture to be updated at erratic rates unless something else causes the editor to redraw constantly.

Edit: Pull request opened: #61943

@FarbrorMartin
Copy link

I don't know how Godot works internally, but the constructor of Animated Texture has:

	RenderingServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
	RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy));

Since the problem is mostly in the editor, maybe there is something in the editor that causes the forced redraw to trigger constantly?

@FarbrorMartin
Copy link

We could disable redraw requests from AnimatedTexture by default, but this will cause the texture to be updated at erratic rates unless something else causes the editor to redraw constantly.

I don't think that would be a big problem at all. You only need to know the sprite works, not have it animating constantly. And if you need to check the visual design you can just turn on the Continuous updates.

Sounds like a great trade off to me!

@Calinou
Copy link
Member

Calinou commented Jun 11, 2022

Since the problem is mostly in the editor, maybe there is something in the editor that causes the forced redraw to trigger constantly?

This occurs whenever low processor mode is in use. Projects don't use low-processor mode by default – they already redraw constantly, even if nothing on screen has changed. This is because most games require constant redrawing by design, and checking whether something needs to be redrawn takes time.

@lawnjelly
Copy link
Member

Unfortunately, enabling Update vital changes did not help with the issue.

This should now be fixed and will be available from 3.5 RC4 (later this week probably).

@clayjohn
Copy link
Member

Bumping to 4.x. This was resolved in 3.5 but the solution has not been forward-ported yet

@lawnjelly
Copy link
Member

Bumping to 4.x. This was resolved in 3.5 but the solution has not been forward-ported yet

Just to note that I haven't attempted to forward port the 3.5 solution because in the PR meeting where we discussed it, Juan believed that the low processor mode would take care of this in 4.x (i.e. rendering the editor frames at a lower rate, afaik) - whether this currently works or not I don't know. We can easily forward port the vital updates if opinion on this changes. 👍

@Calinou
Copy link
Member

Calinou commented Nov 16, 2022

Juan believed that the low processor mode would take care of this in 4.x (i.e. rendering the editor frames at a lower rate, afaik) - whether this currently works or not I don't know.

Low processor mode works in 4.0 like in 3.x, but it doesn't have a "vital updates only" mode yet. No matter what kind of framerate limiting is performed, we need this mode to prevent issues when running the project (it could be automatically enabled by default when the project is running).

@lullabyist
Copy link

Will "Vital updates only" make it into 4.0? I rely on it exclusively for hours daily on 3.5, and really want to make the shift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests