godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.58k stars 21.09k forks source link

ProgressBar calls the `_draw()` function an infinite number of times #95709

Open SebStrz opened 2 months ago

SebStrz commented 2 months ago

Tested versions

System information

Godot v4.3.stable - Windows 10.0.19045 - GLES3 (Compatibility) - NVIDIA GeForce RTX 3050 (NVIDIA; 32.0.15.6070) - AMD Ryzen 5 3600 6-Core Processor (12 Threads)

Issue description

When I add fill_mode = 1 to _draw() function for Progress Bar and run scene with that progress bar in it game freezes before loading properly. In Profiler Debugger you can see that the function _draw() is called houndreds of thousands of times. After some time game unfreezes.

Steps to reproduce

  1. Create a scene
  2. Create Progress Bar
  3. Attach Script to Progress Bar
  4. In that script paste
    func _draw() -> void:
    fill_mode = 1
  5. Run scene
  6. Game freezes

Minimal reproduction project (MRP)

progress_bar_glitch.zip

KoBeWi commented 2 months ago

Setting fill_mode queues a redraw, so if you do it inside _draw(), it will just queue itself infinitely. This applies to all similar properties/nodes.

EDIT: Although equivalent code

extends Node2D

func _draw() -> void:
    queue_redraw()

runs without problems, so this is weird.

Maximilian-Seitz commented 2 months ago

So the problem here has nothing to do with either ProgressBar or fill_mode.

Here's what I could reproduce: Any Control node that calls queue_redraw in _draw, which exists when the game starts up, will result in an infinite loop (of redrawing) on startup (causing an infinite Godot logo screen).

Example code:

extends Control

func _draw():
    print("Drawing")
    queue_redraw()

Put this on a node on startup to reproduce. The code runs/starts fine if extending CanvasItem, and putting it on a Node2D instead.

I have a feeling this may already be known, but if not, this issue should probably be renamed/changed.

AThousandShips commented 1 month ago

Got a fix for this up: