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

FontAtlasSet is broken #6642

Closed
guest-twenty-one opened this issue Nov 16, 2022 · 3 comments
Closed

FontAtlasSet is broken #6642

guest-twenty-one opened this issue Nov 16, 2022 · 3 comments
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Bug An unexpected or incorrect behavior
Milestone

Comments

@guest-twenty-one
Copy link

guest-twenty-one commented Nov 16, 2022

Bevy version

0.9.0

What went wrong

Minimal repro:

const MAX_ATLASES: usize = 1;
const DYNAMIC_SIZE: bool = false;
const TEXT: &str = "";

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(TextSettings {
            max_font_atlases: NonZeroUsize::new(MAX_ATLASES).unwrap(),
            allow_dynamic_font_size: DYNAMIC_SIZE,
        })
        .add_startup_system(setup)
        .run();
}

fn setup(mut commands: Commands, asset_server: ResMut<AssetServer>) {
    commands.spawn(Camera2dBundle::default());

    commands.spawn(TextBundle::from_sections([TextSection::new(
        TEXT,
        TextStyle {
            font: asset_server.load("fonts/sharetech-mono-regular.ttf"),
            font_size: 24.0,
            color: Color::RED,
        },
    )]));
}

Consider the following configurations:

const MAX_ATLASES: usize = 1;
const DYNAMIC_SIZE: bool = false;
const TEXT: &str = "AB"; // any text with 2 or more distinct characters

the application panics with:

'Fatal error when processing text: exceeded 1 available TextAltases for font. This can be caused by using an excessive number of font sizes or ui scaling...

even though it's using only one font size.

const MAX_ATLASES: usize = 2;
const DYNAMIC_SIZE: bool = true;
const TEXT: &str = "AB"; // any text with `MAX_ATLASES or more` distinct characters

the application panics with:

thread 'main' panicked at 'called Option::unwrap() on a None value', crates/bevy_ui/src/render/mod.rs:362:22

const MAX_ATLASES: usize = 1;
const DYNAMIC_SIZE: bool = true;
const TEXT: &str = "A"; // any non-empty text

the application doesn't panic, but it enters an endless loop.

I gave it a quick glance, and it seems that these lines:

if !text_settings.allow_dynamic_font_size {
if self.font_atlases.len() >= text_settings.max_font_atlases.get() {
return Err(TextError::ExceedMaxTextAtlases(
text_settings.max_font_atlases.get(),
));
}
} else {
// Clear last space in queue to make room for new font size
while self.queue.len() >= text_settings.max_font_atlases.get() - 1 {
if let Some(font_size_key) = self.queue.pop() {
self.font_atlases.remove(&font_size_key);
}
}
}

self.queue.insert(0, FloatOrd(font_size));

shouldn't be executed unconditionally, but only if the font with the given size isn't already present in FontAtlasSet (1st and 2nd example).

Also, the extra - 1 on this line:

while self.queue.len() >= text_settings.max_font_atlases.get() - 1 {

seems to be the cause of the endless loop in the third example.

@guest-twenty-one guest-twenty-one added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Nov 16, 2022
@alice-i-cecile alice-i-cecile added A-UI Graphical user interfaces, styles, layouts, and widgets and removed S-Needs-Triage This issue needs to be labelled labels Nov 16, 2022
@alice-i-cecile alice-i-cecile added this to the 0.9.1 milestone Nov 16, 2022
@alice-i-cecile
Copy link
Member

Great bug report, thank you.

@guest-twenty-one
Copy link
Author

Also, it seems there's a fundamental flaw with the eviction queue implementation:

  • if FontAtlasSet is full, the oldest FontAtlas from the queue is picked for removal
  • whether that FontAtlas is still being used or not by another Text node is not taken into consideration at all
  • if it happens that another Text node is still using it, the application will panic (the same panic as in the 2nd example above)

This makes usage of TextSettings with allow_dynamic_font_size: true with the current implementation completely unpredictable and should probably be avoided.

@rparrett
Copy link
Contributor

Additionally, when closing a window that has a scale factor, there's a single frame where there is no longer a window / scale factor and the default is used so new font atlases are created at a different size. (could be platform specific, testing on MacOS)

This can currently cause a panic when closing the window.

If we fix this by changing to a warning, we should open a separate issue for this.

bors bot pushed a commit that referenced this issue Nov 25, 2022
# Objective

Fixes #6642

In a way that doesn't create any breaking changes, as a possible way to fix the above in a patch release.

## Solution

Don't actually remove font atlases when `max_font_atlases` is exceeded. Add a warning instead.

Keep `TextError::ExceedMaxTextAtlases` and `TextSettings` as-is so we don't break anything.

This is a bit of a cop-out, but the problems revealed by #6642 seem very challenging to fix properly.

Maybe follow up later with something more like https://github.com/rparrett/bevy/commits/remove-max-font-atlases later, if this is the direction we want to go.

## Note

See previous attempt at a "simple fix" that only solved some of the issues: #6666
bors bot pushed a commit that referenced this issue Nov 25, 2022
# Objective

Fixes #6642

In a way that doesn't create any breaking changes, as a possible way to fix the above in a patch release.

## Solution

Don't actually remove font atlases when `max_font_atlases` is exceeded. Add a warning instead.

Keep `TextError::ExceedMaxTextAtlases` and `TextSettings` as-is so we don't break anything.

This is a bit of a cop-out, but the problems revealed by #6642 seem very challenging to fix properly.

Maybe follow up later with something more like https://github.com/rparrett/bevy/commits/remove-max-font-atlases later, if this is the direction we want to go.

## Note

See previous attempt at a "simple fix" that only solved some of the issues: #6666
@bors bors bot closed this as completed in d1528df Nov 26, 2022
cart pushed a commit that referenced this issue Nov 30, 2022
# Objective

Fixes #6642

In a way that doesn't create any breaking changes, as a possible way to fix the above in a patch release.

## Solution

Don't actually remove font atlases when `max_font_atlases` is exceeded. Add a warning instead.

Keep `TextError::ExceedMaxTextAtlases` and `TextSettings` as-is so we don't break anything.

This is a bit of a cop-out, but the problems revealed by #6642 seem very challenging to fix properly.

Maybe follow up later with something more like https://github.com/rparrett/bevy/commits/remove-max-font-atlases later, if this is the direction we want to go.

## Note

See previous attempt at a "simple fix" that only solved some of the issues: #6666
ItsDoot pushed a commit to ItsDoot/bevy that referenced this issue Feb 1, 2023
…e#6673)

# Objective

Fixes bevyengine#6642

In a way that doesn't create any breaking changes, as a possible way to fix the above in a patch release.

## Solution

Don't actually remove font atlases when `max_font_atlases` is exceeded. Add a warning instead.

Keep `TextError::ExceedMaxTextAtlases` and `TextSettings` as-is so we don't break anything.

This is a bit of a cop-out, but the problems revealed by bevyengine#6642 seem very challenging to fix properly.

Maybe follow up later with something more like https://github.com/rparrett/bevy/commits/remove-max-font-atlases later, if this is the direction we want to go.

## Note

See previous attempt at a "simple fix" that only solved some of the issues: bevyengine#6666
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-UI Graphical user interfaces, styles, layouts, and widgets C-Bug An unexpected or incorrect behavior
Projects
None yet
3 participants